github.com/thepudds/swisstable@v0.0.0-20221011152303-9c77dc657777/avo/asm.go (about)

     1  package main
     2  
     3  import (
     4  	. "github.com/mmcloughlin/avo/build"
     5  	"github.com/mmcloughlin/avo/operand"
     6  )
     7  
     8  //go:generate go run . -out ../match_amd64.s -stubs ../match_stub.go -pkg swisstable
     9  
    10  func main() {
    11  	// TODO: add more emitted comments. Mention ok is only false if short (<16 bytes), and >16 bytes allowed.
    12  	// TODO: probably could have lighterweight signature (no ok, maybe direct pointer rather than slice, etc).
    13  	// TODO: at least change signature to:
    14  	//  func(b []byte, c byte) (bitmask uint32, ok bool)
    15  	// similar to:
    16  	//    func IndexAny(s []byte, chars string) int
    17  	//    func IndexByte(b []byte, c byte) int
    18  	TEXT("MatchByte", NOSPLIT, "func(c uint8, buffer []byte) (mask uint32, ok bool)")
    19  	Comment("Get our input parameters")
    20  	c := Load(Param("c"), GP32())
    21  	ptr := Load(Param("buffer").Base(), GP64())
    22  	n := Load(Param("buffer").Len(), GP64())
    23  	result := GP32()
    24  
    25  	Comment("Check len of our input slice, which must be at least 16")
    26  	CMPQ(n, operand.Imm(16))
    27  	JGE(operand.LabelRef("valid"))
    28  	Comment("Input slice too short. Return 0, false")
    29  	ok, err := ReturnIndex(1).Resolve()
    30  	if err != nil {
    31  		panic(err)
    32  	}
    33  	XORL(result, result)
    34  	Store(result, ReturnIndex(0))
    35  	MOVB(operand.Imm(0), ok.Addr)
    36  	RET()
    37  
    38  	Label("valid")
    39  	Comment("Input slice is a valid length")
    40  
    41  	Comment("Move c into an xmm register")
    42  	x0, x1, x2 := XMM(), XMM(), XMM()
    43  	MOVD(c, x0)
    44  	Comment("Shuffle the value of c into every byte of another xmm register")
    45  	PXOR(x1, x1)
    46  	PSHUFB(x1, x0)
    47  	Comment("Do an unaligned move of 16 bytes of input slice data to xmm register")
    48  	Comment("MOVOU is how MOVDQU is spelled in Go asm")
    49  	MOVOU(operand.Mem{Base: ptr}, x2)
    50  
    51  	Comment("Find matching bytes with result in xmm register")
    52  	PCMPEQB(x2, x0)
    53  
    54  	Comment("Collapse matching bytes result down to an integer bitmask")
    55  	PMOVMSKB(x0, result)
    56  
    57  	Comment("Return bitmask, true")
    58  	Store(result, ReturnIndex(0))
    59  	MOVB(operand.Imm(1), ok.Addr)
    60  	RET()
    61  	Generate()
    62  }