1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// +build ignore
package main
import (
"strconv"
. "github.com/mmcloughlin/avo/build"
"github.com/mmcloughlin/avo/buildtags"
. "github.com/mmcloughlin/avo/operand"
. "github.com/mmcloughlin/avo/reg"
)
// siphash 1-3
const (
cROUND = 1
dROUND = 3
)
func sipround(v0, v1, v2, v3 Register) {
ADDQ(v1, v0)
ADDQ(v3, v2)
ROLQ(Imm(13), v1)
ROLQ(Imm(16), v3)
XORQ(v0, v1)
XORQ(v2, v3)
ROLQ(Imm(32), v0)
ADDQ(v1, v2)
ADDQ(v3, v0)
ROLQ(Imm(17), v1)
ROLQ(Imm(21), v3)
XORQ(v2, v1)
XORQ(v0, v3)
ROLQ(Imm(32), v2)
}
func main() {
Package("github.com/dgryski/go-sip13")
Constraint(buildtags.Not("noasm").ToConstraint())
makeSip("Sum64", "func(k0, k1 uint64, p []byte) uint64")
makeSip("Sum64Str", "func(k0, k1 uint64, p string) uint64")
Generate()
}
func makeSip(fname, fproto string) {
TEXT(fname, NOSPLIT, fproto)
reg_v0 := GP64()
reg_v1 := GP64()
reg_v2 := GP64()
reg_v3 := GP64()
Load(Param("k0"), reg_v0)
MOVQ(reg_v0, reg_v2)
Load(Param("k1"), reg_v1)
MOVQ(reg_v1, reg_v3)
reg_magic := GP64()
MOVQ(Imm(0x736f6d6570736575), reg_magic)
XORQ(reg_magic, reg_v0)
MOVQ(Imm(0x646f72616e646f6d), reg_magic)
XORQ(reg_magic, reg_v1)
MOVQ(Imm(0x6c7967656e657261), reg_magic)
XORQ(reg_magic, reg_v2)
MOVQ(Imm(0x7465646279746573), reg_magic)
XORQ(reg_magic, reg_v3)
reg_p := Load(Param("p").Base(), GP64())
reg_p_len := Load(Param("p").Len(), GP64())
reg_b := GP64()
MOVQ(reg_p_len, reg_b)
SHLQ(Imm(56), reg_b)
reg_m := GP64()
loop_end := "loop_end"
loop_begin := "loop_begin"
CMPQ(reg_p_len, Imm(8))
JL(LabelRef(loop_end))
Label(loop_begin)
MOVQ(Mem{Base: reg_p}, reg_m)
XORQ(reg_m, reg_v3)
for i := 0; i < cROUND; i++ {
sipround(reg_v0, reg_v1, reg_v2, reg_v3)
}
XORQ(reg_m, reg_v0)
ADDQ(Imm(8), reg_p)
SUBQ(Imm(8), reg_p_len)
CMPQ(reg_p_len, Imm(8))
JGE(LabelRef(loop_begin))
Label(loop_end)
var labels []string
for i := 0; i < 8; i++ {
labels = append(labels, "sw"+strconv.Itoa(i))
}
for i := 0; i < 7; i++ {
CMPQ(reg_p_len, Imm(uint64(i)))
JE(LabelRef(labels[i]))
}
char := GP64()
for i := 7; i > 0; i-- {
Label(labels[i])
MOVBQZX(Mem{Base: reg_p, Disp: i - 1}, char)
SHLQ(Imm(uint64(i-1)*8), char)
ORQ(char, reg_b)
}
Label(labels[0])
XORQ(reg_b, reg_v3)
for i := 0; i < cROUND; i++ {
sipround(reg_v0, reg_v1, reg_v2, reg_v3)
}
XORQ(reg_b, reg_v0)
XORQ(Imm(0xff), reg_v2)
for i := 0; i < dROUND; i++ {
sipround(reg_v0, reg_v1, reg_v2, reg_v3)
}
XORQ(reg_v1, reg_v0)
XORQ(reg_v3, reg_v2)
XORQ(reg_v2, reg_v0)
Store(reg_v0, ReturnIndex(0))
RET()
}
|