diff --git a/examples/sum/asm.go b/examples/sum/asm.go new file mode 100644 index 0000000..d0eb561 --- /dev/null +++ b/examples/sum/asm.go @@ -0,0 +1,27 @@ +// +build ignore + +package main + +import ( + . "github.com/mmcloughlin/avo/build" + "github.com/mmcloughlin/avo/operand" +) + +func main() { + TEXT("Sum", "func(xs []uint64) uint64") + ptr := Load(Param("xs").Base(), GP64v()) + n := Load(Param("xs").Len(), GP64v()) + s := GP64v() + XORQ(s, s) + LABEL("loop") + CMPQ(n, operand.Imm(0)) + JE(operand.LabelRef("done")) + ADDQ(operand.Mem{Base: ptr}, s) + ADDQ(operand.Imm(8), ptr) + DECQ(n) + JMP(operand.LabelRef("loop")) + LABEL("done") + Store(s, ReturnIndex(0)) + RET() + Generate() +} diff --git a/examples/sum/stub.go b/examples/sum/stub.go new file mode 100644 index 0000000..859a440 --- /dev/null +++ b/examples/sum/stub.go @@ -0,0 +1,3 @@ +package sum + +func Sum(xs []uint64) uint64 diff --git a/examples/sum/sum.s b/examples/sum/sum.s new file mode 100644 index 0000000..7bbe334 --- /dev/null +++ b/examples/sum/sum.s @@ -0,0 +1,18 @@ + +#include "textflag.h" + +// func Sum(xs []uint64) uint64 +TEXT ·Sum(SB),0,$0-32 + MOVQ xs_base(FP), DX + MOVQ xs_len+8(FP), CX + XORQ AX, AX +loop: + CMPQ CX, $0x0 + JE done + ADDQ (DX), AX + ADDQ $0x8, DX + DECQ CX + JMP loop +done: + MOVQ AX, ret+24(FP) + RET diff --git a/examples/sum/sum_test.go b/examples/sum/sum_test.go new file mode 100644 index 0000000..6178198 --- /dev/null +++ b/examples/sum/sum_test.go @@ -0,0 +1,20 @@ +package sum + +import ( + "testing" + "testing/quick" +) + +//go:generate go run asm.go -out sum.s -stubs stub.go + +func expect(xs []uint64) uint64 { + var s uint64 + for _, x := range xs { + s += x + } + return s +} + +func TestSum(t *testing.T) { + quick.CheckEqual(Sum, expect, nil) +} diff --git a/gotypes/components.go b/gotypes/components.go index 0220f4b..6362134 100644 --- a/gotypes/components.go +++ b/gotypes/components.go @@ -126,12 +126,11 @@ func (c *component) Index(i int) Component { } func (c *component) sub(suffix string, offset int, t types.Type) *component { - var s *component - *s = *c + s := *c s.name += suffix s.offset += offset s.typ = t - return s + return &s } // TODO(mbm): gotypes.Component handling for structs diff --git a/operand/types.go b/operand/types.go index 74f0b03..4e012a8 100644 --- a/operand/types.go +++ b/operand/types.go @@ -65,7 +65,7 @@ func (m Mem) Asm() string { type Imm uint64 func (i Imm) Asm() string { - return fmt.Sprintf("%#x", i) + return fmt.Sprintf("$%#x", i) } // Rel is an offset relative to the instruction pointer.