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  }