package printer_test import ( "testing" "github.com/mmcloughlin/avo/attr" "github.com/mmcloughlin/avo/build" "github.com/mmcloughlin/avo/buildtags" "github.com/mmcloughlin/avo/printer" "github.com/mmcloughlin/avo/reg" ) func TestBasic(t *testing.T) { ctx := build.NewContext() ctx.Function("add") ctx.SignatureExpr("func(x, y uint64) uint64") x := ctx.Load(ctx.Param("x"), reg.RAX) y := ctx.Load(ctx.Param("y"), reg.R9) ctx.ADDQ(x, y) ctx.Store(y, ctx.ReturnIndex(0)) ctx.RET() AssertPrintsLines(t, ctx, printer.NewGoAsm, []string{ "// Code generated by avo. DO NOT EDIT.", "", "// func add(x uint64, y uint64) uint64", "TEXT ·add(SB), $0-24", "\tMOVQ x+0(FP), AX", "\tMOVQ y+8(FP), R9", "\tADDQ AX, R9", "\tMOVQ R9, ret+16(FP)", "\tRET", "", }) } func TestTextDecl(t *testing.T) { ctx := build.NewContext() ctx.Function("noargs") ctx.SignatureExpr("func()") ctx.AllocLocal(16) ctx.RET() ctx.Function("withargs") ctx.SignatureExpr("func(x, y uint64) uint64") ctx.RET() ctx.Function("withattr") ctx.SignatureExpr("func()") ctx.Attributes(attr.NOSPLIT | attr.TLSBSS) ctx.RET() AssertPrintsLines(t, ctx, printer.NewGoAsm, []string{ "// Code generated by avo. DO NOT EDIT.", "", "// func noargs()", "TEXT ·noargs(SB), $16", // expect only the frame size "\tRET", "", "// func withargs(x uint64, y uint64) uint64", "TEXT ·withargs(SB), $0-24", // expect both frame size and argument size "\tRET", "", "// func withattr()", "TEXT ·withattr(SB), NOSPLIT|TLSBSS, $0", // expect to see attributes "\tRET", "", }) } func TestConstraints(t *testing.T) { ctx := build.NewContext() ctx.ConstraintExpr("linux,386 darwin,!cgo") ctx.ConstraintExpr("!noasm") expect := []string{ "// Code generated by avo. DO NOT EDIT.", "", } if buildtags.GoBuildSyntaxSupported() { expect = append(expect, "//go:build ((linux && 386) || (darwin && !cgo)) && !noasm", ) } if buildtags.PlusBuildSyntaxSupported() { expect = append(expect, "// +build linux,386 darwin,!cgo", "// +build !noasm", ) } expect = append(expect, "") AssertPrintsLines(t, ctx, printer.NewGoAsm, expect) } func TestAlignmentNoOperands(t *testing.T) { ctx := build.NewContext() ctx.Function("alignment") ctx.SignatureExpr("func()") ctx.ADDQ(reg.RAX, reg.RBX) ctx.VMOVDQU(reg.Y4, reg.Y11) ctx.VZEROUPPER() ctx.ADDQ(reg.R9, reg.R13) ctx.RET() AssertPrintsLines(t, ctx, printer.NewGoAsm, []string{ "// Code generated by avo. DO NOT EDIT.", "", "// func alignment()", "TEXT ·alignment(SB), $0", "\tADDQ AX, BX", "\tVMOVDQU Y4, Y11", "\tVZEROUPPER", // instruction with no alignment doesn't affect width "\tADDQ R9, R13", // retains alignment from above "\tRET", "", }) }