blob: 827cab91d5d69f3ed3da973d725bf791128472cb [file] [log] [blame] [edit]
// +build ignore
package main
import (
. "github.com/mmcloughlin/avo/build"
. "github.com/mmcloughlin/avo/operand"
)
//go:generate go run asm2.go -out search2.s -stubs stub_search2.go
func main() {
TEXT("Search", NOSPLIT, "func(xs []uint64, k uint64) int16")
Doc("Search finds the first idx for which xs[idx] >= k in xs.")
ptr := Load(Param("xs").Base(), GP64())
n := Load(Param("xs").Len(), GP64())
key := Load(Param("k"), GP64())
retInd := ReturnIndex(0)
retVal, err := retInd.Resolve()
if err != nil {
panic(err)
}
Comment("Save n")
n2 := GP64()
MOVQ(n, n2)
Comment("Initialize idx register to zero.")
idx := GP64()
XORL(idx.As32(), idx.As32())
Label("loop")
m := Mem{Base: ptr, Index: idx, Scale: 8}
Comment("Unroll1")
CMPQ(m, key)
JAE(LabelRef("Found"))
Comment("Unroll2")
CMPQ(m.Offset(16), key)
JAE(LabelRef("Found2"))
Comment("Unroll3")
CMPQ(m.Offset(32), key)
JAE(LabelRef("Found3"))
Comment("Unroll4")
CMPQ(m.Offset(48), key)
JAE(LabelRef("Found4"))
Comment("plus8")
ADDQ(Imm(8), idx)
CMPQ(idx, n)
JB(LabelRef("loop"))
JMP(LabelRef("NotFound"))
Label("Found2")
ADDL(Imm(2), idx.As32())
JMP(LabelRef("Found"))
Label("Found3")
ADDL(Imm(4), idx.As32())
JMP(LabelRef("Found"))
Label("Found4")
ADDL(Imm(6), idx.As32())
Label("Found")
MOVL(idx.As32(), n2.As32()) // n2 is no longer being used
Label("NotFound")
MOVL(n2.As32(), idx.As32())
SHRL(Imm(31), idx.As32())
ADDL(n2.As32(), idx.As32())
SHRL(Imm(1), idx.As32())
MOVL(idx.As32(), retVal.Addr)
RET()
Generate()
}