Files
TempleOS-Rijn/Kernel/Hash1a.CPP
T
2018-09-08 21:46:02 +02:00

398 lines
7.1 KiB
C++

/****
$SP,"<1>",BI=1$
Tasks have symbol tables. If symbol not found, parent task's table
is searched. Adam task has system-wide symbols.
SYMBOL LOOK-UP (Especially, used by JIT compiler and Loader)
1) Symbol text name is hashed -- Adding the ASCII values of all
chars with shifts.
2) Hash body array is indexed.
3) Linked-lst is traversed until match of text and type-of-entry
4) If not found, next hash table is searched.
Duplicate entries are allowed--they overshadow old entries.
ADDRESS-TO-SYMBOL LOOK-UP (Slow because not important--could add tree)
1)PSect Cache is scanned.
2)"next_added,last_added" que links are traversed. This speeds look-up
instead of scanning hash table because hash table is so sparce.
See $LK,"PSectFind",A="MN:PSectFind"$().
****/
asm {
USE64
// ************************************
// IN: RSI=Addr of string
// OUT: RAX
SYS_HASH_STR::
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
// ************************************
// IN: RAX=HASHED_STRING
// 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
SYS_HASH_SINGLE_TABLE_FIND1::
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
// ************************************
// IN: RSI=STR
// RBX=TYPE MASK
// RDI=TABLE
// RCX=INSTANCE NUM
// OUT: RAX=ENTRY OR ZERO NOT FOUND
// ZERO FLAG SET NOT FOUND
SYS_HASH_FIND1::
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
// ************************************
// IN: RSI=STR
// RDI=TABLE
// OUT: RAX=BUCKET
SYS_HASH_BUCKET_FIND::
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
//QueIns RCX
MOV RBX,U64 CHashTable.last_added[RDI]
MOV U64 CHash.next_added[RCX],RDI
MOV U64 CHash.last_added[RCX],RBX
MOV U64 CHash.next_added[RBX],RCX
MOV U64 CHashTable.last_added[RDI],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
//QueIns RCX
MOV RBX,U64 CHashTable.last_added[RDI]
MOV U64 CHash.next_added[RCX],RDI
MOV U64 CHash.last_added[RCX],RBX
MOV U64 CHash.next_added[RBX],RCX
MOV U64 CHashTable.last_added[RDI],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
//QueRem RAX
MOV RBX,U64 CHash.next_added[RAX]
MOV RDX,U64 CHash.last_added[RAX]
MOV U64 CHash.next_added[RDX],RBX
MOV U64 CHash.last_added[RBX],RDX
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);
_extern _HASH_FIND CHash *
HashFind(U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);
_extern _HASH_SINGLE_TABLE_FIND CHash *
HashSingleTableFind(U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);
_extern _HASH_BUCKET_FIND CHash **
HashBucketFind(U8 *needle_str,CHashTable *haystack_table);
_extern _HASH_ADD U0 HashAdd(CHash *temph,CHashTable *table);
_extern _HASH_REM_DEL Bool HashRemDel(CHash *temph,CHashTable *table,
I64 instance=1);//instance must match temph's
Í  Cat8äCbsX DogtäDogÀ BirdD\`h€ô´\Ì(\,0@ô
XHX`
X`T`
T`TH
THXH
lHl`
ªxª\
ÀxÀ\
€H€`
HHH`
\H\`
pHp`
4H4`
xðx
ðxð\
ð\\
\x
$\$x
8\8x
L\Lx
`\`x
\x
0\0x
D\Dx
\x
x8
8ìÿÿÿ8
ìÿÿÿ8ìÿÿÿx
ìÿÿÿxx
H`H,
H,4,
4,4`
4`H`hhHTXTüÿÿÿ8@d
P\Ì\Ì4èTèdèdèdd�èpè`è\è\ô\ô¼ä<LLL(L(Œ(Œ(tT\ \ÐT4ì`Ð`TtŒ0Œ0H,H,HH<ä¼`ø`ø`ì`ìpì�ìdd`ì`ìTì