examples/stadtx: commit first working example
This commit is contained in:
394
examples/stadtx/asm.go
Normal file
394
examples/stadtx/asm.go
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
. "github.com/mmcloughlin/avo/build"
|
||||||
|
. "github.com/mmcloughlin/avo/operand"
|
||||||
|
. "github.com/mmcloughlin/avo/reg"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
k0U64 = 0xb89b0f8e1655514f
|
||||||
|
k1U64 = 0x8c6f736011bd5127
|
||||||
|
k2U64 = 0x8f29bd94edce7b39
|
||||||
|
k3U64 = 0x9c1b8e1e9628323f
|
||||||
|
|
||||||
|
k2U32 = 0x802910e3
|
||||||
|
k3U32 = 0x819b13af
|
||||||
|
k4U32 = 0x91cb27e5
|
||||||
|
k5U32 = 0xc1a269c1
|
||||||
|
)
|
||||||
|
|
||||||
|
func imul(k uint64, r Register) {
|
||||||
|
t := GP64v()
|
||||||
|
MOVQ(Imm(k), t)
|
||||||
|
IMULQ(t, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makelabels(name string, n int) []string {
|
||||||
|
l := make([]string, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
l[i] = name + strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
Package("github.com/mmcloughlin/avo/examples/stadtx")
|
||||||
|
TEXT("Hash", "func(state *State, key []byte) uint64")
|
||||||
|
|
||||||
|
statePtr := Load(Param("state"), GP64v())
|
||||||
|
ptr := Load(Param("key").Base(), GP64v())
|
||||||
|
n := Load(Param("key").Len(), GP64v())
|
||||||
|
|
||||||
|
v0 := GP64v() // reg_v0 = GeneralPurposeRegister64()
|
||||||
|
v1 := GP64v() // reg_v1 = GeneralPurposeRegister64()
|
||||||
|
MOVQ(Mem{Base: statePtr}, v0) // MOV(reg_v0, [reg_state_ptr])
|
||||||
|
MOVQ(Mem{Base: statePtr, Disp: 8}, v1) // MOV(reg_v1, [reg_state_ptr+8])
|
||||||
|
|
||||||
|
t := GP64v() // t = GeneralPurposeRegister64()
|
||||||
|
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||||
|
ADDQ(Imm(1), t) // ADD(t, 1)
|
||||||
|
imul(k0U64, t) // imul(t, k0U64)
|
||||||
|
XORQ(t, v0) // XOR(reg_v0, t)
|
||||||
|
|
||||||
|
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||||
|
ADDQ(Imm(2), t) // ADD(t, 2)
|
||||||
|
imul(k1U64, t) // imul(t, k1U64)
|
||||||
|
XORQ(t, v1) // XOR(reg_v1, t)
|
||||||
|
|
||||||
|
long := "coreLong" // coreLong = Label("coreLong")
|
||||||
|
CMPQ(n, Imm(32)) // CMP(reg_ptr_len, 32)
|
||||||
|
JGE(LabelRef(long)) // JGE(coreLong)
|
||||||
|
//
|
||||||
|
u64s := GP64v() // reg_u64s = GeneralPurposeRegister64()
|
||||||
|
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||||
|
SHRQ(Imm(3), u64s) // SHR(reg_u64s, 3)
|
||||||
|
//
|
||||||
|
labels := makelabels("shortCore", 4) // labels = [Label("shortCore%d" % i) for i in range(4)]
|
||||||
|
//
|
||||||
|
for i := 0; i < 4; i++ { // for i in range(4):
|
||||||
|
CMPQ(u64s, Imm(i)) // CMP(reg_u64s, i)
|
||||||
|
JE(LabelRef(labels[i])) // JE(labels[i])
|
||||||
|
} //
|
||||||
|
for i := 3; i > 0; i-- { // for i in range(3, 0, -1):
|
||||||
|
LABEL(labels[i]) // LABEL(labels[i])
|
||||||
|
r := GP64v() // r = GeneralPurposeRegister64()
|
||||||
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
|
imul(k3U64, r) // imul(r, k3U64)
|
||||||
|
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||||
|
RORQ(Imm(17), v0) // ROR(reg_v0, 17)
|
||||||
|
XORQ(v1, v0) // XOR(reg_v0, reg_v1)
|
||||||
|
RORQ(Imm(53), v1) // ROR(reg_v1, 53)
|
||||||
|
ADDQ(v0, v1) // ADD(reg_v1, reg_v0)
|
||||||
|
ADDQ(Imm(8), ptr) // ADD(reg_ptr,8)
|
||||||
|
SUBQ(Imm(8), n) // SUB(reg_ptr_len,8)
|
||||||
|
} //
|
||||||
|
LABEL(labels[0]) // LABEL(labels[0])
|
||||||
|
//
|
||||||
|
labels = makelabels("shortTail", 8) // labels = [Label("shortTail%d" % i) for i in range(8)]
|
||||||
|
//
|
||||||
|
// split(labels, reg_ptr_len,0,7)
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
CMPQ(n, Imm(i))
|
||||||
|
JE(LabelRef(labels[i]))
|
||||||
|
}
|
||||||
|
//
|
||||||
|
after := "shortAfter" // after = Label("shortAfter")
|
||||||
|
//
|
||||||
|
ch := GP64v() // reg_ch = GeneralPurposeRegister64()
|
||||||
|
//
|
||||||
|
LABEL(labels[7]) // LABEL(labels[7])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||||
|
SHLQ(Imm(32), ch) // SHL(reg_ch, 32)
|
||||||
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[6]) // LABEL(labels[6])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 5}, ch) // MOVZX(reg_ch, byte[reg_ptr+5])
|
||||||
|
SHLQ(Imm(48), ch) // SHL(reg_ch, 48)
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[5]) // LABEL(labels[5])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
||||||
|
SHLQ(Imm(16), ch) // SHL(reg_ch, 16)
|
||||||
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[4]) // LABEL(labels[4])
|
||||||
|
// XOR(reg_ch, reg_ch)
|
||||||
|
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
|
//
|
||||||
|
LABEL(labels[3]) // LABEL(labels[3])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
||||||
|
SHLQ(Imm(48), ch) // SHL(reg_ch, 48)
|
||||||
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[2]) // LABEL(labels[2])
|
||||||
|
// XOR(reg_ch, reg_ch)
|
||||||
|
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
|
//
|
||||||
|
LABEL(labels[1]) // LABEL(labels[1])
|
||||||
|
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
||||||
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[0]) // LABEL(labels[0])
|
||||||
|
RORQ(Imm(32), v1) // ROR(reg_v1, 32)
|
||||||
|
XORQ(Imm(0xff), v1) // XOR(reg_v1, 0xFF)
|
||||||
|
//
|
||||||
|
LABEL(after) // LABEL(after)
|
||||||
|
//
|
||||||
|
XORQ(v0, v1) // XOR(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
RORQ(Imm(33), v0) // ROR(reg_v0, 33)
|
||||||
|
ADDQ(v1, v0) // ADD(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(17), v1) // ROL(reg_v1, 17)
|
||||||
|
XORQ(v0, v1) // XOR(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(43), v0) // ROL(reg_v0, 43)
|
||||||
|
ADDQ(v1, v0) // ADD(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(31), v1) // ROL(reg_v1, 31)
|
||||||
|
SUBQ(v0, v1) // SUB(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(13), v0) // ROL(reg_v0, 13)
|
||||||
|
XORQ(v1, v0) // XOR(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
SUBQ(v0, v1) // SUB(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(41), v0) // ROL(reg_v0, 41)
|
||||||
|
ADDQ(v1, v0) // ADD(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(37), v1) // ROL(reg_v1, 37)
|
||||||
|
XORQ(v0, v1) // XOR(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
RORQ(Imm(39), v0) // ROR(reg_v0, 39)
|
||||||
|
ADDQ(v1, v0) // ADD(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
RORQ(Imm(15), v1) // ROR(reg_v1, 15)
|
||||||
|
ADDQ(v0, v1) // ADD(reg_v1, reg_v0)
|
||||||
|
//
|
||||||
|
ROLQ(Imm(15), v0) // ROL(reg_v0, 15)
|
||||||
|
XORQ(v1, v0) // XOR(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
RORQ(Imm(5), v1) // ROR(reg_v1, 5)
|
||||||
|
//
|
||||||
|
XORQ(v1, v0) // XOR(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
Store(v0, ReturnIndex(0))
|
||||||
|
RET() // RETURN(reg_v0)
|
||||||
|
//
|
||||||
|
LABEL(long) // LABEL(coreLong)
|
||||||
|
//
|
||||||
|
v2 := GP64v() // reg_v2 = GeneralPurposeRegister64()
|
||||||
|
v3 := GP64v() // reg_v3 = GeneralPurposeRegister64()
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: statePtr, Disp: 16}, v2) // MOV(reg_v2, [reg_state_ptr+16])
|
||||||
|
MOVQ(Mem{Base: statePtr, Disp: 24}, v3) // MOV(reg_v3, [reg_state_ptr+24])
|
||||||
|
//
|
||||||
|
// t = GeneralPurposeRegister64()
|
||||||
|
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||||
|
ADDQ(Imm(3), t) // ADD(t, 3)
|
||||||
|
imul(k2U64, t) // imul(t, k2U64)
|
||||||
|
XORQ(t, v2) // XOR(reg_v2, t)
|
||||||
|
//
|
||||||
|
MOVQ(n, t) // MOV(t, reg_ptr_len)
|
||||||
|
ADDQ(Imm(4), t) // ADD(t, 4)
|
||||||
|
imul(k3U64, t) // imul(t, k3U64)
|
||||||
|
XORQ(t, v3) // XOR(reg_v3, t)
|
||||||
|
//
|
||||||
|
r := GP64v() // r = GeneralPurposeRegister64()
|
||||||
|
loop := "block" // with Loop() as loop:
|
||||||
|
LABEL(loop)
|
||||||
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
|
imul(k2U32, r) // imul(r, k2U32)
|
||||||
|
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||||
|
ROLQ(Imm(57), v0) // ROL(reg_v0, 57)
|
||||||
|
XORQ(v3, v0) // XOR(reg_v0, reg_v3)
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr, Disp: 8}, r) // MOV(r, [reg_ptr + 8])
|
||||||
|
imul(k3U32, r) // imul(r, k3U32)
|
||||||
|
ADDQ(r, v1) // ADD(reg_v1, r)
|
||||||
|
ROLQ(Imm(63), v1) // ROL(reg_v1, 63)
|
||||||
|
XORQ(v2, v1) // XOR(reg_v1, reg_v2)
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr, Disp: 16}, r) // MOV(r, [reg_ptr + 16])
|
||||||
|
imul(k4U32, r) // imul(r, k4U32)
|
||||||
|
ADDQ(r, v2) // ADD(reg_v2, r)
|
||||||
|
RORQ(Imm(47), v2) // ROR(reg_v2, 47)
|
||||||
|
ADDQ(v0, v2) // ADD(reg_v2, reg_v0)
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr, Disp: 24}, r) // MOV(r, [reg_ptr + 24])
|
||||||
|
imul(k5U32, r) // imul(r, k5U32)
|
||||||
|
ADDQ(r, v3) // ADD(reg_v3, r)
|
||||||
|
RORQ(Imm(11), v3) // ROR(reg_v3, 11)
|
||||||
|
SUBQ(v1, v3) // SUB(reg_v3, reg_v1)
|
||||||
|
//
|
||||||
|
ADDQ(Imm(32), ptr) // ADD(reg_ptr, 32)
|
||||||
|
SUBQ(Imm(32), n) // SUB(reg_ptr_len, 32)
|
||||||
|
//
|
||||||
|
CMPQ(n, Imm(32)) // CMP(reg_ptr_len, 32)
|
||||||
|
JGE(LabelRef(loop)) // JGE(loop.begin)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
nsave := GP64v() // reg_ptr_len_saved = GeneralPurposeRegister64()
|
||||||
|
MOVQ(n, nsave) // MOV(reg_ptr_len_saved, reg_ptr_len)
|
||||||
|
//
|
||||||
|
// reg_u64s = GeneralPurposeRegister64()
|
||||||
|
MOVQ(n, u64s) // MOV(reg_u64s, reg_ptr_len)
|
||||||
|
SHRQ(Imm(3), u64s) // SHR(reg_u64s, 3)
|
||||||
|
//
|
||||||
|
labels = makelabels("longCore", 4) // labels = [Label("longCore%d" % i) for i in range(4)]
|
||||||
|
//
|
||||||
|
for i := 0; i < 4; i++ { // for i in range(4):
|
||||||
|
CMPQ(u64s, Imm(i)) // CMP(reg_u64s, i)
|
||||||
|
JE(LabelRef(labels[i])) // JE(labels[i])
|
||||||
|
} //
|
||||||
|
LABEL(labels[3]) // LABEL(labels[3])
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
|
imul(k2U32, r) // imul(r, k2U32)
|
||||||
|
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||||
|
ROLQ(Imm(57), v0) // ROL(reg_v0, 57)
|
||||||
|
XORQ(v3, v0) // XOR(reg_v0, reg_v3)
|
||||||
|
ADDQ(Imm(8), ptr) // ADD(reg_ptr, 8)
|
||||||
|
SUBQ(Imm(8), n) // SUB(reg_ptr_len, 8)
|
||||||
|
//
|
||||||
|
LABEL(labels[2]) // LABEL(labels[2])
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
|
imul(k3U32, r) // imul(r, k3U32)
|
||||||
|
ADDQ(r, v1) // ADD(reg_v1, r)
|
||||||
|
ROLQ(Imm(63), v1) // ROL(reg_v1, 63)
|
||||||
|
XORQ(v2, v1) // XOR(reg_v1, reg_v2)
|
||||||
|
ADDQ(Imm(8), ptr) // ADD(reg_ptr, 8)
|
||||||
|
SUBQ(Imm(8), n) // SUB(reg_ptr_len, 8)
|
||||||
|
//
|
||||||
|
LABEL(labels[1]) // LABEL(labels[1])
|
||||||
|
//
|
||||||
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
|
imul(k4U32, r) // imul(r, k4U32)
|
||||||
|
ADDQ(r, v2) // ADD(reg_v2, r)
|
||||||
|
RORQ(Imm(47), v2) // ROR(reg_v2, 47)
|
||||||
|
ADDQ(v0, v2) // ADD(reg_v2, reg_v0)
|
||||||
|
ADDQ(Imm(8), ptr) // ADD(reg_ptr, 8)
|
||||||
|
SUBQ(Imm(8), n) // SUB(reg_ptr_len, 8)
|
||||||
|
//
|
||||||
|
LABEL(labels[0]) // LABEL(labels[0])
|
||||||
|
//
|
||||||
|
RORQ(Imm(11), v3) // ROR(reg_v3, 11)
|
||||||
|
SUBQ(v1, v3) // SUB(reg_v3, reg_v1)
|
||||||
|
//
|
||||||
|
ADDQ(Imm(1), nsave) // ADD(reg_ptr_len_saved, 1)
|
||||||
|
imul(k3U64, nsave) // imul(reg_ptr_len_saved, k3U64)
|
||||||
|
XORQ(nsave, v0) // XOR(reg_v0, reg_ptr_len_saved)
|
||||||
|
//
|
||||||
|
labels = makelabels("longTail", 8) // labels = [Label("longTail%d" % i) for i in range(8)]
|
||||||
|
//
|
||||||
|
// split(labels, reg_ptr_len, 0, 7)
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
CMPQ(n, Imm(i))
|
||||||
|
JE(LabelRef(labels[i]))
|
||||||
|
}
|
||||||
|
//
|
||||||
|
after = "longAfter" // after = Label("longAfter")
|
||||||
|
//
|
||||||
|
// reg_ch = GeneralPurposeRegister64()
|
||||||
|
//
|
||||||
|
LABEL(labels[7]) // LABEL(labels[7])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[6]) // LABEL(labels[6])
|
||||||
|
// XOR(reg_ch, reg_ch)
|
||||||
|
MOVWQZX(Mem{Base: ptr, Disp: 4}, ch) // MOV(reg_ch.as_word, word[reg_ptr + 4])
|
||||||
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
|
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
||||||
|
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
||||||
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
|
//
|
||||||
|
LABEL(labels[5]) // LABEL(labels[5])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[4]) // LABEL(labels[4])
|
||||||
|
// XOR(reg_ch, reg_ch)
|
||||||
|
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
||||||
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
|
//
|
||||||
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
|
//
|
||||||
|
LABEL(labels[3]) // LABEL(labels[3])
|
||||||
|
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
||||||
|
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[2]) // LABEL(labels[2])
|
||||||
|
// XOR(reg_ch, reg_ch)
|
||||||
|
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
||||||
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
|
//
|
||||||
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
|
//
|
||||||
|
LABEL(labels[1]) // LABEL(labels[1])
|
||||||
|
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
||||||
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
|
//
|
||||||
|
LABEL(labels[0]) // LABEL(labels[0])
|
||||||
|
ROLQ(Imm(32), v3) // ROL(reg_v3, 32)
|
||||||
|
XORQ(Imm(0xff), v3) // XOR(reg_v3, 0xFF)
|
||||||
|
//
|
||||||
|
LABEL(after) // LABEL(after)
|
||||||
|
//
|
||||||
|
// ## finalize
|
||||||
|
//
|
||||||
|
SUBQ(v2, v1) // SUB(reg_v1, reg_v2)
|
||||||
|
RORQ(Imm(19), v0) // ROR(reg_v0, 19)
|
||||||
|
SUBQ(v0, v1) // SUB(reg_v1, reg_v0)
|
||||||
|
RORQ(Imm(53), v1) // ROR(reg_v1, 53)
|
||||||
|
XORQ(v1, v3) // XOR(reg_v3, reg_v1)
|
||||||
|
SUBQ(v3, v0) // SUB(reg_v0, reg_v3)
|
||||||
|
ROLQ(Imm(43), v3) // ROL(reg_v3, 43)
|
||||||
|
ADDQ(v3, v0) // ADD(reg_v0, reg_v3)
|
||||||
|
RORQ(Imm(3), v0) // ROR(reg_v0, 3)
|
||||||
|
SUBQ(v0, v3) // SUB(reg_v3, reg_v0)
|
||||||
|
RORQ(Imm(43), v2) // ROR(reg_v2, 43)
|
||||||
|
SUBQ(v3, v2) // SUB(reg_v2, reg_v3)
|
||||||
|
ROLQ(Imm(55), v2) // ROL(reg_v2, 55)
|
||||||
|
XORQ(v0, v2) // XOR(reg_v2, reg_v0)
|
||||||
|
SUBQ(v2, v1) // SUB(reg_v1, reg_v2)
|
||||||
|
RORQ(Imm(7), v3) // ROR(reg_v3, 7)
|
||||||
|
SUBQ(v2, v3) // SUB(reg_v3, reg_v2)
|
||||||
|
RORQ(Imm(31), v2) // ROR(reg_v2, 31)
|
||||||
|
ADDQ(v2, v3) // ADD(reg_v3, reg_v2)
|
||||||
|
SUBQ(v1, v2) // SUB(reg_v2, reg_v1)
|
||||||
|
RORQ(Imm(39), v3) // ROR(reg_v3, 39)
|
||||||
|
XORQ(v3, v2) // XOR(reg_v2, reg_v3)
|
||||||
|
RORQ(Imm(17), v3) // ROR(reg_v3, 17)
|
||||||
|
XORQ(v2, v3) // XOR(reg_v3, reg_v2)
|
||||||
|
ADDQ(v3, v1) // ADD(reg_v1, reg_v3)
|
||||||
|
RORQ(Imm(9), v1) // ROR(reg_v1, 9)
|
||||||
|
XORQ(v1, v2) // XOR(reg_v2, reg_v1)
|
||||||
|
ROLQ(Imm(24), v2) // ROL(reg_v2, 24)
|
||||||
|
XORQ(v2, v3) // XOR(reg_v3, reg_v2)
|
||||||
|
RORQ(Imm(59), v3) // ROR(reg_v3, 59)
|
||||||
|
RORQ(Imm(1), v0) // ROR(reg_v0, 1)
|
||||||
|
SUBQ(v1, v0) // SUB(reg_v0, reg_v1)
|
||||||
|
//
|
||||||
|
XORQ(v1, v0) // XOR(reg_v0, reg_v1)
|
||||||
|
XORQ(v3, v2) // XOR(reg_v2, reg_v3)
|
||||||
|
//
|
||||||
|
XORQ(v2, v0) // XOR(reg_v0, reg_v2)
|
||||||
|
//
|
||||||
|
Store(v0, ReturnIndex(0))
|
||||||
|
RET() // RETURN(reg_v0)
|
||||||
|
|
||||||
|
Generate()
|
||||||
|
}
|
||||||
3
examples/stadtx/stadtx.go
Normal file
3
examples/stadtx/stadtx.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package stadtx
|
||||||
|
|
||||||
|
type State [4]uint64
|
||||||
310
examples/stadtx/stadtx.s
Normal file
310
examples/stadtx/stadtx.s
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
// Code generated by command: go run asm.go -out stadtx.s -stubs stub.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func Hash(state *State, key []byte) uint64
|
||||||
|
TEXT ·Hash(SB),0,$0-40
|
||||||
|
MOVQ state(FP), AX
|
||||||
|
MOVQ key_base+8(FP), CX
|
||||||
|
MOVQ key_len+16(FP), DX
|
||||||
|
MOVQ (AX), BX
|
||||||
|
MOVQ 8(AX), BP
|
||||||
|
MOVQ DX, SI
|
||||||
|
ADDQ $0x1, SI
|
||||||
|
MOVQ $0xb89b0f8e1655514f, DI
|
||||||
|
IMULQ DI, SI
|
||||||
|
XORQ SI, BX
|
||||||
|
MOVQ DX, SI
|
||||||
|
ADDQ $0x2, SI
|
||||||
|
MOVQ $0x8c6f736011bd5127, DI
|
||||||
|
IMULQ DI, SI
|
||||||
|
XORQ SI, BP
|
||||||
|
CMPQ DX, $0x20
|
||||||
|
JGE coreLong
|
||||||
|
MOVQ DX, SI
|
||||||
|
SHRQ $0x3, SI
|
||||||
|
CMPQ SI, $0x0
|
||||||
|
JE shortCore0
|
||||||
|
CMPQ SI, $0x1
|
||||||
|
JE shortCore1
|
||||||
|
CMPQ SI, $0x2
|
||||||
|
JE shortCore2
|
||||||
|
CMPQ SI, $0x3
|
||||||
|
JE shortCore3
|
||||||
|
shortCore3:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x9c1b8e1e9628323f, DI
|
||||||
|
IMULQ DI, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
RORQ $0x11, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
RORQ $0x35, BP
|
||||||
|
ADDQ BX, BP
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
shortCore2:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x9c1b8e1e9628323f, DI
|
||||||
|
IMULQ DI, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
RORQ $0x11, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
RORQ $0x35, BP
|
||||||
|
ADDQ BX, BP
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
shortCore1:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x9c1b8e1e9628323f, DI
|
||||||
|
IMULQ DI, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
RORQ $0x11, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
RORQ $0x35, BP
|
||||||
|
ADDQ BX, BP
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
shortCore0:
|
||||||
|
CMPQ DX, $0x0
|
||||||
|
JE shortTail0
|
||||||
|
CMPQ DX, $0x1
|
||||||
|
JE shortTail1
|
||||||
|
CMPQ DX, $0x2
|
||||||
|
JE shortTail2
|
||||||
|
CMPQ DX, $0x3
|
||||||
|
JE shortTail3
|
||||||
|
CMPQ DX, $0x4
|
||||||
|
JE shortTail4
|
||||||
|
CMPQ DX, $0x5
|
||||||
|
JE shortTail5
|
||||||
|
CMPQ DX, $0x6
|
||||||
|
JE shortTail6
|
||||||
|
CMPQ DX, $0x7
|
||||||
|
JE shortTail7
|
||||||
|
shortTail7:
|
||||||
|
MOVBQZX 6(CX), SI
|
||||||
|
SHLQ $0x20, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
shortTail6:
|
||||||
|
MOVBQZX 5(CX), SI
|
||||||
|
SHLQ $0x30, SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
shortTail5:
|
||||||
|
MOVBQZX 4(CX), SI
|
||||||
|
SHLQ $0x10, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
shortTail4:
|
||||||
|
MOVLQZX (CX), SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
JMP shortAfter
|
||||||
|
shortTail3:
|
||||||
|
MOVBQZX 2(CX), SI
|
||||||
|
SHLQ $0x30, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
shortTail2:
|
||||||
|
MOVWQZX (CX), SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
JMP shortAfter
|
||||||
|
shortTail1:
|
||||||
|
MOVBQZX (CX), SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
shortTail0:
|
||||||
|
RORQ $0x20, BP
|
||||||
|
XORQ $0xff, BP
|
||||||
|
shortAfter:
|
||||||
|
XORQ BX, BP
|
||||||
|
RORQ $0x21, BX
|
||||||
|
ADDQ BP, BX
|
||||||
|
ROLQ $0x11, BP
|
||||||
|
XORQ BX, BP
|
||||||
|
ROLQ $0x2b, BX
|
||||||
|
ADDQ BP, BX
|
||||||
|
ROLQ $0x1f, BP
|
||||||
|
SUBQ BX, BP
|
||||||
|
ROLQ $0xd, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
SUBQ BX, BP
|
||||||
|
ROLQ $0x29, BX
|
||||||
|
ADDQ BP, BX
|
||||||
|
ROLQ $0x25, BP
|
||||||
|
XORQ BX, BP
|
||||||
|
RORQ $0x27, BX
|
||||||
|
ADDQ BP, BX
|
||||||
|
RORQ $0xf, BP
|
||||||
|
ADDQ BX, BP
|
||||||
|
ROLQ $0xf, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
RORQ $0x5, BP
|
||||||
|
XORQ BP, BX
|
||||||
|
MOVQ BX, ret+32(FP)
|
||||||
|
RET
|
||||||
|
coreLong:
|
||||||
|
MOVQ 16(AX), DI
|
||||||
|
MOVQ 24(AX), AX
|
||||||
|
MOVQ DX, SI
|
||||||
|
ADDQ $0x3, SI
|
||||||
|
MOVQ $0x8f29bd94edce7b39, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
XORQ SI, DI
|
||||||
|
MOVQ DX, SI
|
||||||
|
ADDQ $0x4, SI
|
||||||
|
MOVQ $0x9c1b8e1e9628323f, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
XORQ SI, AX
|
||||||
|
block:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x802910e3, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
ROLQ $0x39, BX
|
||||||
|
XORQ AX, BX
|
||||||
|
MOVQ 8(CX), SI
|
||||||
|
MOVQ $0x819b13af, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
ROLQ $0x3f, BP
|
||||||
|
XORQ DI, BP
|
||||||
|
MOVQ 16(CX), SI
|
||||||
|
MOVQ $0x91cb27e5, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
ADDQ SI, DI
|
||||||
|
RORQ $0x2f, DI
|
||||||
|
ADDQ BX, DI
|
||||||
|
MOVQ 24(CX), SI
|
||||||
|
MOVQ $0xc1a269c1, R8
|
||||||
|
IMULQ R8, SI
|
||||||
|
ADDQ SI, AX
|
||||||
|
RORQ $0xb, AX
|
||||||
|
SUBQ BP, AX
|
||||||
|
ADDQ $0x20, CX
|
||||||
|
SUBQ $0x20, DX
|
||||||
|
CMPQ DX, $0x20
|
||||||
|
JGE block
|
||||||
|
MOVQ DX, R8
|
||||||
|
MOVQ DX, SI
|
||||||
|
SHRQ $0x3, SI
|
||||||
|
CMPQ SI, $0x0
|
||||||
|
JE longCore0
|
||||||
|
CMPQ SI, $0x1
|
||||||
|
JE longCore1
|
||||||
|
CMPQ SI, $0x2
|
||||||
|
JE longCore2
|
||||||
|
CMPQ SI, $0x3
|
||||||
|
JE longCore3
|
||||||
|
longCore3:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x802910e3, R9
|
||||||
|
IMULQ R9, SI
|
||||||
|
ADDQ SI, BX
|
||||||
|
ROLQ $0x39, BX
|
||||||
|
XORQ AX, BX
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
longCore2:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x819b13af, R9
|
||||||
|
IMULQ R9, SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
ROLQ $0x3f, BP
|
||||||
|
XORQ DI, BP
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
longCore1:
|
||||||
|
MOVQ (CX), SI
|
||||||
|
MOVQ $0x91cb27e5, R9
|
||||||
|
IMULQ R9, SI
|
||||||
|
ADDQ SI, DI
|
||||||
|
RORQ $0x2f, DI
|
||||||
|
ADDQ BX, DI
|
||||||
|
ADDQ $0x8, CX
|
||||||
|
SUBQ $0x8, DX
|
||||||
|
longCore0:
|
||||||
|
RORQ $0xb, AX
|
||||||
|
SUBQ BP, AX
|
||||||
|
ADDQ $0x1, R8
|
||||||
|
MOVQ $0x9c1b8e1e9628323f, SI
|
||||||
|
IMULQ SI, R8
|
||||||
|
XORQ R8, BX
|
||||||
|
CMPQ DX, $0x0
|
||||||
|
JE longTail0
|
||||||
|
CMPQ DX, $0x1
|
||||||
|
JE longTail1
|
||||||
|
CMPQ DX, $0x2
|
||||||
|
JE longTail2
|
||||||
|
CMPQ DX, $0x3
|
||||||
|
JE longTail3
|
||||||
|
CMPQ DX, $0x4
|
||||||
|
JE longTail4
|
||||||
|
CMPQ DX, $0x5
|
||||||
|
JE longTail5
|
||||||
|
CMPQ DX, $0x6
|
||||||
|
JE longTail6
|
||||||
|
CMPQ DX, $0x7
|
||||||
|
JE longTail7
|
||||||
|
longTail7:
|
||||||
|
MOVBQZX 6(CX), SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
longTail6:
|
||||||
|
MOVWQZX 4(CX), SI
|
||||||
|
ADDQ SI, DI
|
||||||
|
MOVLQZX (CX), SI
|
||||||
|
ADDQ SI, AX
|
||||||
|
JMP longAfter
|
||||||
|
longTail5:
|
||||||
|
MOVBQZX 4(CX), SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
longTail4:
|
||||||
|
MOVLQZX (CX), SI
|
||||||
|
ADDQ SI, DI
|
||||||
|
JMP longAfter
|
||||||
|
longTail3:
|
||||||
|
MOVBQZX 2(CX), SI
|
||||||
|
ADDQ SI, AX
|
||||||
|
longTail2:
|
||||||
|
MOVWQZX (CX), SI
|
||||||
|
ADDQ SI, BP
|
||||||
|
JMP longAfter
|
||||||
|
longTail1:
|
||||||
|
MOVBQZX (CX), SI
|
||||||
|
ADDQ SI, DI
|
||||||
|
longTail0:
|
||||||
|
ROLQ $0x20, AX
|
||||||
|
XORQ $0xff, AX
|
||||||
|
longAfter:
|
||||||
|
SUBQ DI, BP
|
||||||
|
RORQ $0x13, BX
|
||||||
|
SUBQ BX, BP
|
||||||
|
RORQ $0x35, BP
|
||||||
|
XORQ BP, AX
|
||||||
|
SUBQ AX, BX
|
||||||
|
ROLQ $0x2b, AX
|
||||||
|
ADDQ AX, BX
|
||||||
|
RORQ $0x3, BX
|
||||||
|
SUBQ BX, AX
|
||||||
|
RORQ $0x2b, DI
|
||||||
|
SUBQ AX, DI
|
||||||
|
ROLQ $0x37, DI
|
||||||
|
XORQ BX, DI
|
||||||
|
SUBQ DI, BP
|
||||||
|
RORQ $0x7, AX
|
||||||
|
SUBQ DI, AX
|
||||||
|
RORQ $0x1f, DI
|
||||||
|
ADDQ DI, AX
|
||||||
|
SUBQ BP, DI
|
||||||
|
RORQ $0x27, AX
|
||||||
|
XORQ AX, DI
|
||||||
|
RORQ $0x11, AX
|
||||||
|
XORQ DI, AX
|
||||||
|
ADDQ AX, BP
|
||||||
|
RORQ $0x9, BP
|
||||||
|
XORQ BP, DI
|
||||||
|
ROLQ $0x18, DI
|
||||||
|
XORQ DI, AX
|
||||||
|
RORQ $0x3b, AX
|
||||||
|
RORQ $0x1, BX
|
||||||
|
SUBQ BP, BX
|
||||||
|
XORQ BP, BX
|
||||||
|
XORQ AX, DI
|
||||||
|
XORQ DI, BX
|
||||||
|
MOVQ BX, ret+32(FP)
|
||||||
|
RET
|
||||||
25
examples/stadtx/stadtx_test.go
Normal file
25
examples/stadtx/stadtx_test.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package stadtx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testing/quick"
|
||||||
|
|
||||||
|
ref "github.com/dgryski/go-stadtx"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run asm.go -out stadtx.s -stubs stub.go
|
||||||
|
|
||||||
|
func IUT(s State, key []byte) uint64 {
|
||||||
|
return Hash(&s, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Expect(s State, key []byte) uint64 {
|
||||||
|
t := ref.State(s)
|
||||||
|
return ref.Hash(&t, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCmp(t *testing.T) {
|
||||||
|
if err := quick.CheckEqual(IUT, Expect, nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
examples/stadtx/stub.go
Normal file
5
examples/stadtx/stub.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// Code generated by command: go run asm.go -out stadtx.s -stubs stub.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package stadtx
|
||||||
|
|
||||||
|
func Hash(state *State, key []byte) uint64
|
||||||
@@ -3,7 +3,6 @@ package gotypes
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -113,12 +112,17 @@ func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string)
|
|||||||
func (t *Tuple) Lookup(name string) Component {
|
func (t *Tuple) Lookup(name string) Component {
|
||||||
e := t.byname[name]
|
e := t.byname[name]
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return componenterr(fmt.Sprintf("unknown variable \"%s\"", name))
|
return errorf("unknown variable \"%s\"", name)
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tuple) At(i int) Component { return t.components[i] }
|
func (t *Tuple) At(i int) Component {
|
||||||
|
if i >= len(t.components) {
|
||||||
|
return errorf("index out of range")
|
||||||
|
}
|
||||||
|
return t.components[i]
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tuple) Bytes() int { return t.size }
|
func (t *Tuple) Bytes() int { return t.size }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user