asm { //************************************ SYS_HASH_STR:: // IN: RSI=Addr of string // OUT: RAX XOR RAX,RAX TEST RSI,RSI JZ @@15 PUSH RSI PUSH RBX XOR RBX,RBX JMP @@10 @@05: SHL1 RBX ADC RBX,RAX @@10: LODSB TEST AL,AL JNZ @@05 MOV RAX,RBX SHR RBX,16 ADC RAX,RBX POP RBX POP RSI @@15: RET //************************************ SYS_HASH_SINGLE_TABLE_FIND1:: // IN: RAX=HASHED STRING VAL // RSI=STR // RBX=TYPE MASK // RDI=TABLE // RCX=INSTANCE, NOT ZERO // OUT: RAX=ENTRY OR ZERO NOT FOUND // RDX=POINTER TO POINTER TO ENTRY // RCX IF NOT FOUND ENOUGH, DECREMENTED BY NUM MATCHES // ZERO FLAG SET NOT FOUND MOV RCX,1 SYS_HASH_SINGLE_TABLE_FIND:: TEST RCX,RCX JNZ @@05 XOR RAX,RAX RET @@05: AND RAX,U64 CHashTable.mask[RDI] MOV RDX,U64 CHashTable.body[RDI] LEA RDX,U64 [RDX+RAX*8] @@10: MOV RAX,U64 [RDX] TEST RAX,RAX JNZ @@15 RET @@15: TEST U32 CHash.type[RAX],EBX JZ @@30 PUSH RAX PUSH RDI PUSH RSI MOV RDI,U64 CHash.str[RAX] @@20: LODSB CMP U8 [RDI],AL JNE @@25 INC RDI TEST AL,AL JNZ @@20 POP RSI POP RDI POP RAX LOOP @@30 INC U32 CHash.use_cnt[RAX] TEST RAX,RAX RET @@25: POP RSI POP RDI POP RAX @@30: LEA RDX,U64 CHash.next[RAX] JMP @@10 //************************************ SYS_HASH_FIND1:: // IN: RSI=STR // RBX=TYPE MASK // RDI=TABLE // RCX=INSTANCE NUM // OUT: RAX=ENTRY OR ZERO NOT FOUND // ZERO FLAG SET NOT FOUND MOV RCX,1 SYS_HASH_FIND:: PUSH RDI CALL SYS_HASH_STR @@05: PUSH RAX CALL SYS_HASH_SINGLE_TABLE_FIND JNZ @@15 POP RAX @@10: MOV RDI,U64 CHashTable.next[RDI] TEST RDI,RDI JNZ @@05 POP RDI XOR RAX,RAX RET @@15: ADD RSP,8 POP RDI TEST RAX,RAX RET //************************************ SYS_HASH_BUCKET_FIND:: // IN: RSI=STR // RDI=TABLE // OUT: RAX=BUCKET PUSH RDX CALL SYS_HASH_STR AND RAX,U64 CHashTable.mask[RDI] MOV RDX,U64 CHashTable.body[RDI] LEA RAX,U64 [RDX+RAX*8] POP RDX RET _HASH_STR:: PUSH RBP MOV RBP,RSP PUSH RSI MOV RSI,U64 SF_ARG1[RBP] CALL SYS_HASH_STR POP RSI POP RBP RET1 8 _HASH_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] MOV RBX,U64 SF_ARG3[RBP] MOV RCX,U64 SF_ARG4[RBP] CALL SYS_HASH_FIND POP RDI POP RSI POP RBP RET1 32 _HASH_SINGLE_TABLE_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] MOV RBX,U64 SF_ARG3[RBP] MOV RCX,U64 SF_ARG4[RBP] CALL SYS_HASH_STR CALL SYS_HASH_SINGLE_TABLE_FIND POP RDI POP RSI POP RBP RET1 32 _HASH_BUCKET_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] CALL SYS_HASH_BUCKET_FIND POP RDI POP RSI POP RBP RET1 16 _HASH_ADD:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RCX,U64 SF_ARG1[RBP] MOV RSI,U64 CHash.str[RCX] MOV RDI,U64 SF_ARG2[RBP] CALL SYS_HASH_BUCKET_FIND MOV RCX,U64 SF_ARG1[RBP] PUSHFD CLI MOV RBX,U64 [RAX] MOV U64 CHash.next[RCX],RBX MOV U64 [RAX],RCX POPFD POP RDI POP RSI POP RBP RET1 16 _HASH_ADD_AFTER:: PUSH RBP MOV RBP,RSP PUSH RDI MOV RCX,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG3[RBP] PUSHFD CLI MOV RAX,SF_ARG2[RBP] MOV RBX,U64 [RAX] MOV U64 CHash.next[RCX],RBX MOV U64 [RAX],RCX POPFD POP RDI POP RBP RET1 24 _HASH_REM_DEL:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RCX,U64 SF_ARG1[RBP] TEST RCX,RCX JZ @@10 MOV RSI,U64 CHash.str[RCX] XOR RBX,RBX MOV EBX,U32 CHash.type[RCX] AND EBX,~HTG_FLAGS_MASK&0xFFFFFFFF MOV RDI,U64 SF_ARG2[RBP] MOV RCX,U64 SF_ARG3[RBP] CALL SYS_HASH_STR PUSHFD CLI CALL SYS_HASH_SINGLE_TABLE_FIND JZ @@05 CMP RAX,U64 SF_ARG1[RBP] JNE @@05 MOV RBX,U64 CHash.next[RAX] MOV U64 [RDX],RBX POPFD PUSH_C_REGS PUSH RAX CALL &HashDel POP_C_REGS POP RDI POP RSI MOV RAX,1 POP RBP RET1 24 @@05: POPFD @@10: POP RDI POP RSI XOR RAX,RAX POP RBP RET1 24 } _extern _HASH_STR I64 HashStr(U8 *st); //Hash a string. _extern _HASH_FIND CHash *HashFind(U8 *needle_str,CHashTable *haystack_table, I64 mask,I64 instance=1);//Find string in hash table. _extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind(U8 *needle_str, CHashTable *haystack_table, I64 mask,I64 instance=1);//Find string in single hash table. _extern _HASH_BUCKET_FIND CHash **HashBucketFind(U8 *needle_str, CHashTable *haystack_table); //Find hash bucket. _extern _HASH_ADD U0 HashAdd(CHash *tmph, CHashTable *table); //Add entry to hash table. _extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table, I64 instance=1);//Remove hash entry and del. Instance must match.