Created
June 20, 2025 20:45
-
-
Save bitonic/5ebac6b05a67ef95d8627712d84671c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //go:build amd64 | |
| #include "textflag.h" | |
| #define LEHMER_LO AX | |
| #define LEHMER_HI DX | |
| #define LEHMER_M R15 | |
| #define MASK R8 | |
| #define SLOTS R9 | |
| #define KEY DI | |
| #define ENTRY R11 | |
| #define NEW_ENTRY SI | |
| #define INDEX R12 | |
| #define MIN_TIME R14 | |
| #define MIN_TIME_INDEX R10 | |
| #define SCRATCH_1 R13 | |
| #define SLOT X0 | |
| #define SLOT_MATCH X1 | |
| #define SLOT_TMP X2 | |
| #define LEHMER_SEED \ | |
| MOVQ KEY, LEHMER_LO \ | |
| MOVQ KEY, LEHMER_HI \ | |
| ORQ $1, LEHMER_HI \ | |
| MOVQ $0xda942042e4dd58b5, LEHMER_M | |
| #define LEHMER_ROUND \ | |
| MOVQ LEHMER_HI, SCRATCH_1 \ // x = hi*m | |
| IMULQ LEHMER_M, SCRATCH_1 \ | |
| MULQ LEHMER_M \ // hi, lo = lo*m | |
| ADDQ SCRATCH_1, LEHMER_HI \ // hi += x | |
| // Just for testing | |
| TEXT ·lehmerRound(SB),NOSPLIT,$0-32 | |
| MOVQ hi+0(FP), LEHMER_HI | |
| MOVQ lo+8(FP), LEHMER_LO | |
| MOVQ $0xda942042e4dd58b5, LEHMER_M | |
| LEHMER_ROUND | |
| MOVQ LEHMER_HI, retHi+16(FP) | |
| MOVQ LEHMER_LO, retLo+24(FP) | |
| RET | |
| #define GET_ROUND(finished) \ | |
| MOVQ LEHMER_HI, INDEX \ | |
| ANDQ MASK, INDEX \ // idx = (idx & mask) * 16 | |
| SHLQ $4, INDEX \ | |
| MOVO 0(SLOTS)(INDEX*1), SLOT \ // slot = slots[idx] | |
| MOVQ SLOT, SCRATCH_1 \ | |
| CMPQ SCRATCH_1, KEY \ | |
| JEQ finished \ // key is equal, we're done | |
| // func slotsGet5(mask uint64, slots unsafe.Pointer, key uint64) (entry unsafe.Pointer) | |
| TEXT ·slotsGet5(SB),NOSPLIT,$0-32 | |
| // Arg loading | |
| MOVQ mask+0(FP), MASK | |
| MOVQ slots+8(FP), SLOTS | |
| MOVQ key+16(FP), KEY | |
| // lehmer64 seeding | |
| LEHMER_SEED | |
| // 5 rounds | |
| LEHMER_ROUND | |
| GET_ROUND(get5Finished) | |
| LEHMER_ROUND | |
| GET_ROUND(get5Finished) | |
| // Nothing found | |
| PXOR SLOT, SLOT | |
| get5Finished: | |
| PEXTRQ $1, SLOT, entry+24(FP) | |
| RET | |
| #define PUT_ROUND(break) \ | |
| MOVQ LEHMER_HI, INDEX \ | |
| ANDQ MASK, INDEX \ // idx = (idx & mask) * 16 | |
| SHLQ $4, INDEX \ | |
| MOVO 0(SLOTS)(INDEX*1), SLOT \ // slot = slots[idx] | |
| MOVO SLOT, SLOT_TMP \ | |
| PCMPEQQ SLOT_MATCH, SLOT_TMP \ // if the entry is nil, or the key is equal, exit | |
| PTEST SLOT_TMP, SLOT_TMP \ | |
| JNE break \ | |
| PEXTRQ $1, SLOT, ENTRY \ // less or equal below makes it so that the user can use -1 as time and it'll still work | |
| MOVQ (ENTRY), SCRATCH_1 \ // if time =< min_time { | |
| CMPQ SCRATCH_1, MIN_TIME \ // min_time = time | |
| CMOVQLS SCRATCH_1, MIN_TIME \ // min_time_index = index | |
| CMOVQLS INDEX, MIN_TIME_INDEX \ // } | |
| // func slotsPut5(mask uint64, slots unsafe.Pointer, key uint64, entry unsafe.Pointer) | |
| TEXT ·slotsPut5(SB),NOSPLIT,$0-32 | |
| MOVQ mask+0(FP), MASK | |
| MOVQ slots+8(FP), SLOTS | |
| MOVQ key+16(FP), KEY | |
| MOVQ entry+24(FP), NEW_ENTRY | |
| // Prepare thing to compare with | |
| PXOR SLOT_MATCH, SLOT_MATCH // slot_match = (key, nil) | |
| MOVQ KEY, SLOT_MATCH | |
| // Prepare min time | |
| MOVQ $0xffffffffffffffff, MIN_TIME | |
| // lehmer64 seeding | |
| LEHMER_SEED | |
| // 5 rounds | |
| LEHMER_ROUND | |
| PUT_ROUND(put5Found) | |
| LEHMER_ROUND | |
| PUT_ROUND(put5Found) | |
| put5Exit: | |
| CMPL runtime·writeBarrier(SB), $0x0 | |
| JEQ put5Write | |
| CALL runtime·gcWriteBarrier2(SB) | |
| MOVQ NEW_ENTRY, (R11) | |
| MOVQ 1(SLOTS)(MIN_TIME_INDEX*1), SCRATCH_1 | |
| MOVQ SCRATCH_1, 8(R11) | |
| put5Write: | |
| MOVQ KEY, SLOT // slots[min_time_index] = (key, entry) | |
| PINSRQ $1, NEW_ENTRY, SLOT | |
| MOVO SLOT, 0(SLOTS)(MIN_TIME_INDEX*1) | |
| RET | |
| put5Found: | |
| MOVQ INDEX, MIN_TIME_INDEX | |
| JMP put5Exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment