github.com/etecs-ru/ristretto@v0.9.1/z/simd/asm2.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 //go:generate go run asm2.go -out search_amd64.s -stubs stub_search_amd64.go 7 8 func main() { 9 TEXT("Search", NOSPLIT, "func(xs []uint64, k uint64) int16") 10 Doc("Search finds the first idx for which xs[idx] >= k in xs.") 11 ptr := Load(Param("xs").Base(), GP64()) 12 n := Load(Param("xs").Len(), GP64()) 13 key := Load(Param("k"), GP64()) 14 retInd := ReturnIndex(0) 15 retVal, err := retInd.Resolve() 16 if err != nil { 17 panic(err) 18 } 19 20 Comment("Save n") 21 n2 := GP64() 22 MOVQ(n, n2) 23 24 Comment("Initialize idx register to zero.") 25 idx := GP64() 26 XORL(idx.As32(), idx.As32()) 27 28 Label("loop") 29 m := Mem{Base: ptr, Index: idx, Scale: 8} 30 31 Comment("Unroll1") 32 CMPQ(m, key) 33 JAE(LabelRef("Found")) 34 35 Comment("Unroll2") 36 CMPQ(m.Offset(16), key) 37 JAE(LabelRef("Found2")) 38 39 Comment("Unroll3") 40 CMPQ(m.Offset(32), key) 41 JAE(LabelRef("Found3")) 42 43 Comment("Unroll4") 44 CMPQ(m.Offset(48), key) 45 JAE(LabelRef("Found4")) 46 47 Comment("plus8") 48 ADDQ(Imm(8), idx) 49 CMPQ(idx, n) 50 JB(LabelRef("loop")) 51 JMP(LabelRef("NotFound")) 52 53 Label("Found2") 54 ADDL(Imm(2), idx.As32()) 55 JMP(LabelRef("Found")) 56 57 Label("Found3") 58 ADDL(Imm(4), idx.As32()) 59 JMP(LabelRef("Found")) 60 61 Label("Found4") 62 ADDL(Imm(6), idx.As32()) 63 64 Label("Found") 65 MOVL(idx.As32(), n2.As32()) // n2 is no longer being used 66 67 Label("NotFound") 68 MOVL(n2.As32(), idx.As32()) 69 SHRL(Imm(31), idx.As32()) 70 ADDL(n2.As32(), idx.As32()) 71 SHRL(Imm(1), idx.As32()) 72 MOVL(idx.As32(), retVal.Addr) 73 RET() 74 75 Generate() 76 }