Add PopCount compiler intrinsic. Remove BCount

Remove set_bits_table
This commit is contained in:
xmm15 2020-02-17 23:26:23 -06:00
parent 9be5a44f28
commit 436e03d10c
18 changed files with 612 additions and 599 deletions

Binary file not shown.

View file

@ -199,6 +199,7 @@ CIntermediateStruct intermediate_code_table[IC_ICS_NUM]={
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"COS"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"TAN"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ATAN"},
{IS_1_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"POPCNT"},
};
U0 CompLoadDefines()

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -116,7 +116,7 @@ class CIntermediateStruct
#define IC_JMP 0x51
#define IC_SUB_CALL 0x52
#define IC_SWITCH 0x53
#define IC_NOBOUND_SWITCH 0x54
#define IC_NOBOUND_SWITCH 0x54
#define IC_ADD_RSP 0x55
#define IC_ADD_RSP1 0x56
@ -171,7 +171,7 @@ class CIntermediateStruct
#define IC_QUEUE_INIT 0x80
#define IC_QUEUE_INSERT 0x81
#define IC_QUEUE_INSERT_REV 0x82
#define IC_QUEUE_INSERT_REV 0x82
#define IC_QUEUE_REMOVE 0x83
#define IC_STRLEN 0x84
@ -234,7 +234,8 @@ class CIntermediateStruct
#define IC_COS 0xB6
#define IC_TAN 0xB7
#define IC_ATAN 0xB8
#define IC_ICS_NUM 0xB9
#define IC_POPCNT 0xB9
#define IC_ICS_NUM 0xBA
#define KW_INCLUDE 0
#define KW_DEFINE 1

View file

@ -931,6 +931,17 @@ args.
OptSetNOP1(tmpi); //BSR
}
break;
case IC_POPCNT:
if (tmpi1->ic_code==IC_IMM_I64) {
tmpi1->ic_data = PopCount(tmpi1->ic_data);
tmpi_push = tmpi1;
OptSetNOP1(OptLag(tmpi1)); //CALL_START
tmpi2 = OptLead1(tmpi);
tmpi1->ic_flags |= tmpi->ic_flags | tmpi2->ic_flags;
OptSetNOP1(tmpi2); //CALL_END
OptSetNOP1(tmpi); //POPCNT
}
break;
case IC_LBTS:
case IC_LBTR:
case IC_LBTC:

View file

@ -439,6 +439,7 @@ here1:
case IC_LBTC:
case IC_BSF:
case IC_BSR:
case IC_POPCNT:
case IC_SIGN_I64:
case IC_TOUPPER:
case IC_TO_I64:

View file

@ -619,6 +619,7 @@ p4_sib:
case IC_ADDR_IMPORT:
case IC_BSF:
case IC_BSR:
case IC_POPCNT:
case IC_SIGN_I64:
case IC_TOUPPER:
case IC_TO_I64:

View file

@ -817,6 +817,12 @@ cc->pass==10 is final pass, code is placed into buf.
ICU16(tmpi,0x0375);
ICU24(tmpi,0xD0F748);
break;
case IC_POPCNT:
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
ICU16(tmpi, 0xF348);
ICU32(tmpi, 0xC0B80F48);
break;
case IC_SIGN_I64:
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);

View file

@ -9,6 +9,6 @@ $FG,2$BEqual$FG$: Set bit to value.
$FG$Bit operations are "atomic", no interrupt between the reading and writing the bit, important when multitasking. For multicore use "locked" forms.$FG$
$FG,5$These don't take a pointer, but the actual field.$FG$
$FG,2$Bsf$FG$: Bit Scan Fwd (Pos of first low one bit or -1)
$FG,2$Bsr$FG$: Bit Scan Rev (Pos of first high one bit or -1)
$FG,2$BCount$FG$: Bit Count (Count of set bits)
$FG,2$Bsf$FG$: Bit Scan Forward (Pos of first low one bit or -1)
$FG,2$Bsr$FG$: Bit Scan Reverse (Pos of first high one bit or -1)
$FG,2$PopCount$FG$:Population Count (Count of set bits)

Binary file not shown.

View file

@ -9,8 +9,7 @@ CTask *zenith_task;
I64 sys_num_spawned_tasks;
CTask *sys_winmgr_task,*sys_task_being_screen_updated;
U8 *rev_bits_table, //Table with U8 bits revd
*set_bits_table; //Table with count of set bits in a U8
U8 *rev_bits_table; //Table with U8 bits reversed
CDate local_time_offset;
F64 *pow10_I64,
sys_os_version=0.10;
@ -25,7 +24,7 @@ CGridGlobals mouse_grid; //See $LK,"::/Demo/Graphics/Grid.CC"$.
CMouseStateGlobals mouse,mouse_last;
CKbdStateGlobals kbd;
CKeyDevGlobals keydev;
CMouseHardStateGlobals mouse_hard,mouse_hard_last;
CMouseHardStateGlobals mouse_hard,mouse_hard_last;
CScreenCastGlobals screencast;
CTextGlobals text;

View file

@ -26,11 +26,9 @@ U0 SysGlobalsInit()
DebugMode(ON);
rev_bits_table=CAlloc(256);
set_bits_table=CAlloc(256);
for (i=0;i<256;i++)
for (j=0;j<8;j++) {
if (Bt(&i,7-j)) LBts(rev_bits_table+i,j);
if (Bt(&i,j)) set_bits_table[i]++;
}
ext=CAlloc(EXT_EXTS_NUM*sizeof(U8 *));

View file

@ -4,15 +4,7 @@ U0 PortNop()
InU8(0x21);
}
I64 BCount(I64 d)
{//Count set bits in I64.
I64 res=0,i;
for (i=0;i<8;i++)
res+=set_bits_table[d.u8[i]];
return res;
}
U0 IntCore0TimerHandler(CTask *)
U0 IntCore0TimerHandler(CTask *)
{//Called from $LK,"IntCore0TimerHandler",A="FF:::/Kernel/KInterrupts.CC,IntCore0TimerHandler"$
I64 i;
if (mp_count>1)

File diff suppressed because one or more lines are too long

View file

@ -6,32 +6,20 @@ $LK,"KernelB",A="FF:::/StartOS.CC,KernelB"$ StartOS.CC
#help_index "Bit"
#help_file "::/Doc/Bit"
public _intern IC_BSF I64 Bsf(
I64 bit_field_val);//Scan forward from lowest for 1st set. -1 if not found.
public _intern IC_BSR I64 Bsr(
I64 bit_field_val);//Scan rev from highest for 1st set. -1 if not found.
public _intern IC_BT Bool Bt(
U8 *bit_field,I64 bit); //Bit test.
public _intern IC_BTC Bool Btc(
U8 *bit_field,I64 bit); //Bit test and complement (same as xor with 1).
public _intern IC_BTR Bool Btr(
U8 *bit_field,I64 bit); //Bit test and reset to zero.
public _intern IC_BTS Bool Bts(
U8 *bit_field,I64 bit); //Bit test and set to one.
public _intern IC_LBTC Bool LBtc(
U8 *bit_field,I64 bit); //Locked bit test and complement (xor with 1).
public _intern IC_LBTR Bool LBtr(
U8 *bit_field,I64 bit); //Locked bit test and reset to zero.
public _intern IC_LBTS Bool LBts(
U8 *bit_field,I64 bit); //Locked bit test and set to one.
public _extern _BEQUAL Bool BEqual(
U8 *bit_field,I64 bit,Bool val);//Set bit equ to val.
public _extern _BIT_FIELD_EXT_U32 U32 BFieldExtU32(
U8 *bit_field,I64 bit,I64 size); //Extract U32 from bit field.
public _extern _BIT_FIELD_OR_U32 U0 BFieldOrU32(
U8 *bit_field,I64 bit,U32 pattern); //Or U32 into bit field.
public _extern _LBEQUAL Bool LBEqual(
U8 *bit_field,I64 bit,Bool val); //Locked Set bit equ to val.
public _intern IC_BSF I64 Bsf(I64 bit_field_val);//Scan forward from lowest for 1st set. -1 if not found.
public _intern IC_BSR I64 Bsr(I64 bit_field_val);//Scan rev from highest for 1st set. -1 if not found.
public _intern IC_BT Bool Bt(U8 *bit_field,I64 bit); //Bit test.
public _intern IC_BTC Bool Btc(U8 *bit_field,I64 bit); //Bit test and complement (same as xor with 1).
public _intern IC_BTR Bool Btr(U8 *bit_field,I64 bit); //Bit test and reset to zero.
public _intern IC_BTS Bool Bts(U8 *bit_field,I64 bit); //Bit test and set to one.
public _intern IC_LBTC Bool LBtc(U8 *bit_field,I64 bit); //Locked bit test and complement (xor with 1).
public _intern IC_LBTR Bool LBtr(U8 *bit_field,I64 bit); //Locked bit test and reset to zero.
public _intern IC_LBTS Bool LBts(U8 *bit_field,I64 bit); //Locked bit test and set to one.
public _intern IC_POPCNT I64 PopCount(I64 bit_field_val);
public _extern _BEQUAL Bool BEqual(U8 *bit_field,I64 bit,Bool val);//Set bit equ to val.
public _extern _BIT_FIELD_EXT_U32 U32 BFieldExtU32(U8 *bit_field,I64 bit,I64 size); //Extract U32 from bit field.
public _extern _BIT_FIELD_OR_U32 U0 BFieldOrU32(U8 *bit_field,I64 bit,U32 pattern); //Or U32 into bit field.
public _extern _LBEQUAL Bool LBEqual(U8 *bit_field,I64 bit,Bool val); //Locked Set bit equ to val.
#help_index "Boot"
_extern MEM_BOOT_BASE U32 mem_boot_base;

View file

@ -6,8 +6,7 @@ public extern CAutoCompleteGlobals ac;
public extern CAutoCompleteDictGlobals acd;
#help_index "Bit"
public extern I64 BCount(I64 d);
public extern U8 *rev_bits_table,*set_bits_table;
public extern U8 *rev_bits_table;
#help_index "Boot"
#help_file "::/Doc/Boot"

Binary file not shown.