// func memhash(p unsafe.Pointer, h, s uintptr) uintptr
// hash function using AES hardware instructions
-TEXT runtime·memhash(SB),NOSPLIT,$0-32
+TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT,$0-32
+#ifdef GOEXPERIMENT_regabiargs
+ // AX = ptr to data
+ // BX = seed
+ // CX = size
+#endif
CMPB runtime·useAeshash(SB), $0
JEQ noaes
+#ifndef GOEXPERIMENT_regabiargs
MOVQ p+0(FP), AX // ptr to data
MOVQ s+16(FP), CX // size
LEAQ ret+24(FP), DX
+#endif
JMP aeshashbody<>(SB)
noaes:
- JMP runtime·memhashFallback(SB)
+ JMP runtime·memhashFallback<ABIInternal>(SB)
// func strhash(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·strhash(SB),NOSPLIT,$0-24
+TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+ // AX = ptr to string struct
+ // BX = seed
+#endif
CMPB runtime·useAeshash(SB), $0
JEQ noaes
+#ifndef GOEXPERIMENT_regabiargs
MOVQ p+0(FP), AX // ptr to string struct
+#endif
MOVQ 8(AX), CX // length of string
MOVQ (AX), AX // string data
+#ifndef GOEXPERIMENT_regabiargs
LEAQ ret+16(FP), DX
+#endif
JMP aeshashbody<>(SB)
noaes:
- JMP runtime·strhashFallback(SB)
+ JMP runtime·strhashFallback<ABIInternal>(SB)
// AX: data
+#ifdef GOEXPERIMENT_regabiargs
+// BX: hash seed
+#else
+// h+8(FP): hash seed
+#endif
// CX: length
+#ifdef GOEXPERIMENT_regabiargs
+// At return: AX = return value
+#else
// DX: address to put return value
+#endif
TEXT aeshashbody<>(SB),NOSPLIT,$0-0
// Fill an SSE register with our seeds.
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ BX, X0 // 64 bits of per-table hash seed
+#else
MOVQ h+8(FP), X0 // 64 bits of per-table hash seed
+#endif
PINSRW $4, CX, X0 // 16 bits of length
PSHUFHW $0, X0, X0 // repeat length 4 times total
MOVO X0, X1 // save unscrambled seed
AESENC X1, X1 // scramble combo 3 times
AESENC X1, X1
AESENC X1, X1
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X1, AX // return X1
+#else
MOVQ X1, (DX)
+#endif
RET
endofpage:
aes0:
// Return scrambled input seed
AESENC X0, X0
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X0, AX // return X0
+#else
MOVQ X0, (DX)
+#endif
RET
aes16:
// combine results
PXOR X3, X2
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X2, AX // return X2
+#else
MOVQ X2, (DX)
+#endif
RET
aes33to64:
PXOR X6, X4
PXOR X7, X5
PXOR X5, X4
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X4, AX // return X4
+#else
MOVQ X4, (DX)
+#endif
RET
aes65to128:
PXOR X10, X8
PXOR X11, X9
PXOR X9, X8
+#ifdef GOEXPERIMENT_regabig
+ // X15 must be zero on return
+ PXOR X15, X15
+#endif
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X8, AX // return X8
+#else
MOVQ X8, (DX)
+#endif
RET
aes129plus:
PXOR X10, X8
PXOR X11, X9
PXOR X9, X8
+#ifdef GOEXPERIMENT_regabig
+ // X15 must be zero on return
+ PXOR X15, X15
+#endif
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X8, AX // return X8
+#else
MOVQ X8, (DX)
+#endif
RET
// func memhash32(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash32(SB),NOSPLIT,$0-24
+// ABIInternal for performance.
+TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+ // AX = ptr to data
+ // BX = seed
+#endif
CMPB runtime·useAeshash(SB), $0
JEQ noaes
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ BX, X0 // X0 = seed
+#else
MOVQ p+0(FP), AX // ptr to data
MOVQ h+8(FP), X0 // seed
+#endif
PINSRD $2, (AX), X0 // data
AESENC runtime·aeskeysched+0(SB), X0
AESENC runtime·aeskeysched+16(SB), X0
AESENC runtime·aeskeysched+32(SB), X0
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X0, AX // return X0
+#else
MOVQ X0, ret+16(FP)
+#endif
RET
noaes:
- JMP runtime·memhash32Fallback(SB)
+ JMP runtime·memhash32Fallback<ABIInternal>(SB)
// func memhash64(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash64(SB),NOSPLIT,$0-24
+// ABIInternal for performance.
+TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+ // AX = ptr to data
+ // BX = seed
+#else
+#endif
CMPB runtime·useAeshash(SB), $0
JEQ noaes
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ BX, X0 // X0 = seed
+#else
MOVQ p+0(FP), AX // ptr to data
MOVQ h+8(FP), X0 // seed
+#endif
PINSRQ $1, (AX), X0 // data
AESENC runtime·aeskeysched+0(SB), X0
AESENC runtime·aeskeysched+16(SB), X0
AESENC runtime·aeskeysched+32(SB), X0
+#ifdef GOEXPERIMENT_regabiargs
+ MOVQ X0, AX // return X0
+#else
MOVQ X0, ret+16(FP)
+#endif
RET
noaes:
- JMP runtime·memhash64Fallback(SB)
+ JMP runtime·memhash64Fallback<ABIInternal>(SB)
// simple mask to get rid of data in the high part of the register.
DATA masks<>+0x00(SB)/8, $0x0000000000000000
// See memclrNoHeapPointers Go doc for important implementation constraints.
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
-TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-16
+// ABIInternal for performance.
+TEXT runtime·memclrNoHeapPointers<ABIInternal>(SB), NOSPLIT, $0-16
+#ifdef GOEXPERIMENT_regabiargs
+ // AX = ptr
+ // BX = n
+ MOVQ AX, DI // DI = ptr
+#else
MOVQ ptr+0(FP), DI
MOVQ n+8(FP), BX
+#endif
XORQ AX, AX
// MOVOU seems always faster than REP STOSQ.
JE _8
CMPQ BX, $16
JBE _9through16
- PXOR X0, X0
+#ifndef GOEXPERIMENT_regabig
+ PXOR X15, X15
+#endif
CMPQ BX, $32
JBE _17through32
CMPQ BX, $64
// TODO: for really big clears, use MOVNTDQ, even without AVX2.
loop:
- MOVOU X0, 0(DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, 64(DI)
- MOVOU X0, 80(DI)
- MOVOU X0, 96(DI)
- MOVOU X0, 112(DI)
- MOVOU X0, 128(DI)
- MOVOU X0, 144(DI)
- MOVOU X0, 160(DI)
- MOVOU X0, 176(DI)
- MOVOU X0, 192(DI)
- MOVOU X0, 208(DI)
- MOVOU X0, 224(DI)
- MOVOU X0, 240(DI)
+ MOVOU X15, 0(DI)
+ MOVOU X15, 16(DI)
+ MOVOU X15, 32(DI)
+ MOVOU X15, 48(DI)
+ MOVOU X15, 64(DI)
+ MOVOU X15, 80(DI)
+ MOVOU X15, 96(DI)
+ MOVOU X15, 112(DI)
+ MOVOU X15, 128(DI)
+ MOVOU X15, 144(DI)
+ MOVOU X15, 160(DI)
+ MOVOU X15, 176(DI)
+ MOVOU X15, 192(DI)
+ MOVOU X15, 208(DI)
+ MOVOU X15, 224(DI)
+ MOVOU X15, 240(DI)
SUBQ $256, BX
ADDQ $256, DI
CMPQ BX, $256
MOVQ AX, -8(DI)(BX*1)
RET
_17through32:
- MOVOU X0, (DI)
- MOVOU X0, -16(DI)(BX*1)
+ MOVOU X15, (DI)
+ MOVOU X15, -16(DI)(BX*1)
RET
_33through64:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
+ MOVOU X15, (DI)
+ MOVOU X15, 16(DI)
+ MOVOU X15, -32(DI)(BX*1)
+ MOVOU X15, -16(DI)(BX*1)
RET
_65through128:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, -64(DI)(BX*1)
- MOVOU X0, -48(DI)(BX*1)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
+ MOVOU X15, (DI)
+ MOVOU X15, 16(DI)
+ MOVOU X15, 32(DI)
+ MOVOU X15, 48(DI)
+ MOVOU X15, -64(DI)(BX*1)
+ MOVOU X15, -48(DI)(BX*1)
+ MOVOU X15, -32(DI)(BX*1)
+ MOVOU X15, -16(DI)(BX*1)
RET
_129through256:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, 64(DI)
- MOVOU X0, 80(DI)
- MOVOU X0, 96(DI)
- MOVOU X0, 112(DI)
- MOVOU X0, -128(DI)(BX*1)
- MOVOU X0, -112(DI)(BX*1)
- MOVOU X0, -96(DI)(BX*1)
- MOVOU X0, -80(DI)(BX*1)
- MOVOU X0, -64(DI)(BX*1)
- MOVOU X0, -48(DI)(BX*1)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
+ MOVOU X15, (DI)
+ MOVOU X15, 16(DI)
+ MOVOU X15, 32(DI)
+ MOVOU X15, 48(DI)
+ MOVOU X15, 64(DI)
+ MOVOU X15, 80(DI)
+ MOVOU X15, 96(DI)
+ MOVOU X15, 112(DI)
+ MOVOU X15, -128(DI)(BX*1)
+ MOVOU X15, -112(DI)(BX*1)
+ MOVOU X15, -96(DI)(BX*1)
+ MOVOU X15, -80(DI)(BX*1)
+ MOVOU X15, -64(DI)(BX*1)
+ MOVOU X15, -48(DI)(BX*1)
+ MOVOU X15, -32(DI)(BX*1)
+ MOVOU X15, -16(DI)(BX*1)
RET