build: unify Label function signatures
The Context.Label method and LABEL global function did not agree. Also breaks the convention I'd like to set that capitalized functions must agree with existing Go assembly syntax. To help avoid a conflict with `avo.Label`, attributes were moved to their own package. Fixes #35
This commit is contained in:
@@ -105,14 +105,14 @@ func main() {
|
|||||||
n := Load(Param("xs").Len(), GP64())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
Label("loop")
|
||||||
CMPQ(n, Imm(0))
|
CMPQ(n, Imm(0))
|
||||||
JE(LabelRef("done"))
|
JE(LabelRef("done"))
|
||||||
ADDQ(Mem{Base: ptr}, s)
|
ADDQ(Mem{Base: ptr}, s)
|
||||||
ADDQ(Imm(8), ptr)
|
ADDQ(Imm(8), ptr)
|
||||||
DECQ(n)
|
DECQ(n)
|
||||||
JMP(LabelRef("loop"))
|
JMP(LabelRef("loop"))
|
||||||
LABEL("done")
|
Label("done")
|
||||||
Store(s, ReturnIndex(0))
|
Store(s, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
Generate()
|
Generate()
|
||||||
|
|||||||
5
ast.go
5
ast.go
@@ -3,6 +3,7 @@ package avo
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/mmcloughlin/avo/attr"
|
||||||
"github.com/mmcloughlin/avo/buildtags"
|
"github.com/mmcloughlin/avo/buildtags"
|
||||||
"github.com/mmcloughlin/avo/gotypes"
|
"github.com/mmcloughlin/avo/gotypes"
|
||||||
"github.com/mmcloughlin/avo/operand"
|
"github.com/mmcloughlin/avo/operand"
|
||||||
@@ -128,7 +129,7 @@ func (f *File) Functions() []*Function {
|
|||||||
// Function represents an assembly function.
|
// Function represents an assembly function.
|
||||||
type Function struct {
|
type Function struct {
|
||||||
Name string
|
Name string
|
||||||
Attributes Attribute
|
Attributes attr.Attribute
|
||||||
Doc []string
|
Doc []string
|
||||||
Signature *gotypes.Signature
|
Signature *gotypes.Signature
|
||||||
LocalSize int
|
LocalSize int
|
||||||
@@ -236,7 +237,7 @@ func (d Datum) Overlaps(other Datum) bool {
|
|||||||
// Global represents a DATA section.
|
// Global represents a DATA section.
|
||||||
type Global struct {
|
type Global struct {
|
||||||
Symbol operand.Symbol
|
Symbol operand.Symbol
|
||||||
Attributes Attribute
|
Attributes attr.Attribute
|
||||||
Data []Datum
|
Data []Datum
|
||||||
Size int
|
Size int
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package avo
|
// Package attr provides attributes for text and data sections.
|
||||||
|
package attr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package avo
|
package attr
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"github.com/mmcloughlin/avo"
|
"github.com/mmcloughlin/avo"
|
||||||
|
"github.com/mmcloughlin/avo/attr"
|
||||||
"github.com/mmcloughlin/avo/buildtags"
|
"github.com/mmcloughlin/avo/buildtags"
|
||||||
"github.com/mmcloughlin/avo/gotypes"
|
"github.com/mmcloughlin/avo/gotypes"
|
||||||
"github.com/mmcloughlin/avo/operand"
|
"github.com/mmcloughlin/avo/operand"
|
||||||
@@ -90,7 +91,7 @@ func (c *Context) Doc(lines ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attributes sets function attributes for the currently active function.
|
// Attributes sets function attributes for the currently active function.
|
||||||
func (c *Context) Attributes(a avo.Attribute) {
|
func (c *Context) Attributes(a attr.Attribute) {
|
||||||
c.activefunc().Attributes = a
|
c.activefunc().Attributes = a
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,12 +125,12 @@ func (c *Context) AllocLocal(size int) operand.Mem {
|
|||||||
|
|
||||||
// Instruction adds an instruction to the active function.
|
// Instruction adds an instruction to the active function.
|
||||||
func (c *Context) Instruction(i *avo.Instruction) {
|
func (c *Context) Instruction(i *avo.Instruction) {
|
||||||
c.activefunc().AddNode(i)
|
c.activefunc().AddInstruction(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label adds a label to the active function.
|
// Label adds a label to the active function.
|
||||||
func (c *Context) Label(l avo.Label) {
|
func (c *Context) Label(name string) {
|
||||||
c.activefunc().AddLabel(l)
|
c.activefunc().AddLabel(avo.Label(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) activefunc() *avo.Function {
|
func (c *Context) activefunc() *avo.Function {
|
||||||
@@ -150,7 +151,7 @@ func (c *Context) StaticGlobal(name string) operand.Mem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DataAttributes sets the attributes on the current active global data section.
|
// DataAttributes sets the attributes on the current active global data section.
|
||||||
func (c *Context) DataAttributes(a avo.Attribute) {
|
func (c *Context) DataAttributes(a attr.Attribute) {
|
||||||
c.activeglobal().Attributes = a
|
c.activeglobal().Attributes = a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/mmcloughlin/avo/attr"
|
||||||
"github.com/mmcloughlin/avo/buildtags"
|
"github.com/mmcloughlin/avo/buildtags"
|
||||||
"github.com/mmcloughlin/avo/gotypes"
|
"github.com/mmcloughlin/avo/gotypes"
|
||||||
"github.com/mmcloughlin/avo/operand"
|
"github.com/mmcloughlin/avo/operand"
|
||||||
|
|
||||||
"github.com/mmcloughlin/avo/reg"
|
"github.com/mmcloughlin/avo/reg"
|
||||||
|
|
||||||
"github.com/mmcloughlin/avo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctx provides a global build context.
|
// ctx provides a global build context.
|
||||||
@@ -22,11 +21,8 @@ func TEXT(name, signature string) {
|
|||||||
ctx.SignatureExpr(signature)
|
ctx.SignatureExpr(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LABEL adds a label to the active function.
|
|
||||||
func LABEL(name string) { ctx.Label(avo.Label(name)) }
|
|
||||||
|
|
||||||
// GLOBL declares a new static global data section with the given attributes.
|
// GLOBL declares a new static global data section with the given attributes.
|
||||||
func GLOBL(name string, a avo.Attribute) operand.Mem {
|
func GLOBL(name string, a attr.Attribute) operand.Mem {
|
||||||
// TODO(mbm): should this be static?
|
// TODO(mbm): should this be static?
|
||||||
g := ctx.StaticGlobal(name)
|
g := ctx.StaticGlobal(name)
|
||||||
ctx.DataAttributes(a)
|
ctx.DataAttributes(a)
|
||||||
@@ -119,11 +115,14 @@ func Store(src reg.Register, dst gotypes.Component) { ctx.Store(src, dst) }
|
|||||||
func Doc(lines ...string) { ctx.Doc(lines...) }
|
func Doc(lines ...string) { ctx.Doc(lines...) }
|
||||||
|
|
||||||
// Attributes sets function attributes for the currently active function.
|
// Attributes sets function attributes for the currently active function.
|
||||||
func Attributes(a avo.Attribute) { ctx.Attributes(a) }
|
func Attributes(a attr.Attribute) { ctx.Attributes(a) }
|
||||||
|
|
||||||
// AllocLocal allocates size bytes in the stack of the currently active function.
|
// AllocLocal allocates size bytes in the stack of the currently active function.
|
||||||
// Returns a reference to the base pointer for the newly allocated region.
|
// Returns a reference to the base pointer for the newly allocated region.
|
||||||
func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) }
|
func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) }
|
||||||
|
|
||||||
|
// Label adds a label to the active function.
|
||||||
|
func Label(name string) { ctx.Label(name) }
|
||||||
|
|
||||||
// ConstData builds a static data section containing just the given constant.
|
// ConstData builds a static data section containing just the given constant.
|
||||||
func ConstData(name string, v operand.Constant) operand.Mem { return ctx.ConstData(name, v) }
|
func ConstData(name string, v operand.Constant) operand.Mem { return ctx.ConstData(name, v) }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mmcloughlin/avo"
|
"github.com/mmcloughlin/avo/attr"
|
||||||
"github.com/mmcloughlin/avo/operand"
|
"github.com/mmcloughlin/avo/operand"
|
||||||
"github.com/mmcloughlin/avo/reg"
|
"github.com/mmcloughlin/avo/reg"
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ func (c *Context) Store(src reg.Register, dst gotypes.Component) {
|
|||||||
// ConstData builds a static data section containing just the given constant.
|
// ConstData builds a static data section containing just the given constant.
|
||||||
func (c *Context) ConstData(name string, v operand.Constant) operand.Mem {
|
func (c *Context) ConstData(name string, v operand.Constant) operand.Mem {
|
||||||
g := c.StaticGlobal(name)
|
g := c.StaticGlobal(name)
|
||||||
c.DataAttributes(avo.RODATA | avo.NOPTR)
|
c.DataAttributes(attr.RODATA | attr.NOPTR)
|
||||||
c.AppendDatum(v)
|
c.AppendDatum(v)
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
. "github.com/mmcloughlin/avo"
|
. "github.com/mmcloughlin/avo/attr"
|
||||||
. "github.com/mmcloughlin/avo/build"
|
. "github.com/mmcloughlin/avo/build"
|
||||||
. "github.com/mmcloughlin/avo/operand"
|
. "github.com/mmcloughlin/avo/operand"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func main() {
|
|||||||
// Loop over blocks and process them with vector instructions.
|
// Loop over blocks and process them with vector instructions.
|
||||||
blockitems := 8 * unroll
|
blockitems := 8 * unroll
|
||||||
blocksize := 4 * blockitems
|
blocksize := 4 * blockitems
|
||||||
LABEL("blockloop")
|
Label("blockloop")
|
||||||
CMPQ(n, U32(blockitems))
|
CMPQ(n, U32(blockitems))
|
||||||
JL(LabelRef("tail"))
|
JL(LabelRef("tail"))
|
||||||
|
|
||||||
@@ -55,11 +55,11 @@ func main() {
|
|||||||
JMP(LabelRef("blockloop"))
|
JMP(LabelRef("blockloop"))
|
||||||
|
|
||||||
// Process any trailing entries.
|
// Process any trailing entries.
|
||||||
LABEL("tail")
|
Label("tail")
|
||||||
tail := XMM()
|
tail := XMM()
|
||||||
VXORPS(tail, tail, tail)
|
VXORPS(tail, tail, tail)
|
||||||
|
|
||||||
LABEL("tailloop")
|
Label("tailloop")
|
||||||
CMPQ(n, U32(0))
|
CMPQ(n, U32(0))
|
||||||
JE(LabelRef("reduce"))
|
JE(LabelRef("reduce"))
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func main() {
|
|||||||
JMP(LabelRef("tailloop"))
|
JMP(LabelRef("tailloop"))
|
||||||
|
|
||||||
// Reduce the lanes to one.
|
// Reduce the lanes to one.
|
||||||
LABEL("reduce")
|
Label("reduce")
|
||||||
for i := 1; i < unroll; i++ {
|
for i := 1; i < unroll; i++ {
|
||||||
VADDPS(acc[0], acc[i], acc[0])
|
VADDPS(acc[0], acc[i], acc[0])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func main() {
|
|||||||
p := GP64()
|
p := GP64()
|
||||||
MOVQ(Imm(Prime), p)
|
MOVQ(Imm(Prime), p)
|
||||||
|
|
||||||
LABEL("loop")
|
Label("loop")
|
||||||
CMPQ(n, Imm(0))
|
CMPQ(n, Imm(0))
|
||||||
JE(LabelRef("done"))
|
JE(LabelRef("done"))
|
||||||
b := GP64()
|
b := GP64()
|
||||||
@@ -31,7 +31,7 @@ func main() {
|
|||||||
DECQ(n)
|
DECQ(n)
|
||||||
|
|
||||||
JMP(LabelRef("loop"))
|
JMP(LabelRef("loop"))
|
||||||
LABEL("done")
|
Label("done")
|
||||||
Store(h, ReturnIndex(0))
|
Store(h, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
Generate()
|
Generate()
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func main() {
|
|||||||
p := GP64()
|
p := GP64()
|
||||||
MOVQ(Imm(Prime), p)
|
MOVQ(Imm(Prime), p)
|
||||||
|
|
||||||
LABEL("loop")
|
Label("loop")
|
||||||
CMPQ(n, Imm(0))
|
CMPQ(n, Imm(0))
|
||||||
JE(LabelRef("done"))
|
JE(LabelRef("done"))
|
||||||
b := GP64()
|
b := GP64()
|
||||||
@@ -35,7 +35,7 @@ func main() {
|
|||||||
DECQ(n)
|
DECQ(n)
|
||||||
|
|
||||||
JMP(LabelRef("loop"))
|
JMP(LabelRef("loop"))
|
||||||
LABEL("done")
|
Label("done")
|
||||||
Store(h, ReturnIndex(0))
|
Store(h, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
Generate()
|
Generate()
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func main() {
|
|||||||
JE(LabelRef(labels[i])) // JE(labels[i])
|
JE(LabelRef(labels[i])) // JE(labels[i])
|
||||||
} //
|
} //
|
||||||
for i := 3; i > 0; i-- { // for i in range(3, 0, -1):
|
for i := 3; i > 0; i-- { // for i in range(3, 0, -1):
|
||||||
LABEL(labels[i]) // LABEL(labels[i])
|
Label(labels[i]) // Label(labels[i])
|
||||||
r := GP64() // r = GeneralPurposeRegister64()
|
r := GP64() // r = GeneralPurposeRegister64()
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k3U64, r) // imul(r, k3U64)
|
imul(k3U64, r) // imul(r, k3U64)
|
||||||
@@ -88,7 +88,7 @@ func main() {
|
|||||||
ADDQ(U32(8), ptr) // ADD(reg_ptr,8)
|
ADDQ(U32(8), ptr) // ADD(reg_ptr,8)
|
||||||
SUBQ(U32(8), n) // SUB(reg_ptr_len,8)
|
SUBQ(U32(8), n) // SUB(reg_ptr_len,8)
|
||||||
} //
|
} //
|
||||||
LABEL(labels[0]) // LABEL(labels[0])
|
Label(labels[0]) // Label(labels[0])
|
||||||
//
|
//
|
||||||
labels = makelabels("shortTail", 8) // labels = [Label("shortTail%d" % i) for i in range(8)]
|
labels = makelabels("shortTail", 8) // labels = [Label("shortTail%d" % i) for i in range(8)]
|
||||||
//
|
//
|
||||||
@@ -102,49 +102,49 @@ func main() {
|
|||||||
//
|
//
|
||||||
ch := GP64() // reg_ch = GeneralPurposeRegister64()
|
ch := GP64() // reg_ch = GeneralPurposeRegister64()
|
||||||
//
|
//
|
||||||
LABEL(labels[7]) // LABEL(labels[7])
|
Label(labels[7]) // Label(labels[7])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||||
SHLQ(U8(32), ch) // SHL(reg_ch, 32)
|
SHLQ(U8(32), ch) // SHL(reg_ch, 32)
|
||||||
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[6]) // LABEL(labels[6])
|
Label(labels[6]) // Label(labels[6])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 5}, ch) // MOVZX(reg_ch, byte[reg_ptr+5])
|
MOVBQZX(Mem{Base: ptr, Disp: 5}, ch) // MOVZX(reg_ch, byte[reg_ptr+5])
|
||||||
SHLQ(U8(48), ch) // SHL(reg_ch, 48)
|
SHLQ(U8(48), ch) // SHL(reg_ch, 48)
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[5]) // LABEL(labels[5])
|
Label(labels[5]) // Label(labels[5])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
||||||
SHLQ(U8(16), ch) // SHL(reg_ch, 16)
|
SHLQ(U8(16), ch) // SHL(reg_ch, 16)
|
||||||
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[4]) // LABEL(labels[4])
|
Label(labels[4]) // Label(labels[4])
|
||||||
// XOR(reg_ch, reg_ch)
|
// XOR(reg_ch, reg_ch)
|
||||||
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
JMP(LabelRef(after)) // JMP(after)
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
//
|
//
|
||||||
LABEL(labels[3]) // LABEL(labels[3])
|
Label(labels[3]) // Label(labels[3])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
||||||
SHLQ(U8(48), ch) // SHL(reg_ch, 48)
|
SHLQ(U8(48), ch) // SHL(reg_ch, 48)
|
||||||
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[2]) // LABEL(labels[2])
|
Label(labels[2]) // Label(labels[2])
|
||||||
// XOR(reg_ch, reg_ch)
|
// XOR(reg_ch, reg_ch)
|
||||||
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
JMP(LabelRef(after)) // JMP(after)
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
//
|
//
|
||||||
LABEL(labels[1]) // LABEL(labels[1])
|
Label(labels[1]) // Label(labels[1])
|
||||||
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
||||||
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
ADDQ(ch, v0) // ADD(reg_v0, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[0]) // LABEL(labels[0])
|
Label(labels[0]) // Label(labels[0])
|
||||||
RORQ(U8(32), v1) // ROR(reg_v1, 32)
|
RORQ(U8(32), v1) // ROR(reg_v1, 32)
|
||||||
XORQ(U32(0xff), v1) // XOR(reg_v1, 0xFF)
|
XORQ(U32(0xff), v1) // XOR(reg_v1, 0xFF)
|
||||||
//
|
//
|
||||||
LABEL(after) // LABEL(after)
|
Label(after) // Label(after)
|
||||||
//
|
//
|
||||||
XORQ(v0, v1) // XOR(reg_v1, reg_v0)
|
XORQ(v0, v1) // XOR(reg_v1, reg_v0)
|
||||||
//
|
//
|
||||||
@@ -187,7 +187,7 @@ func main() {
|
|||||||
Store(v0, ReturnIndex(0))
|
Store(v0, ReturnIndex(0))
|
||||||
RET() // RETURN(reg_v0)
|
RET() // RETURN(reg_v0)
|
||||||
//
|
//
|
||||||
LABEL(long) // LABEL(coreLong)
|
Label(long) // Label(coreLong)
|
||||||
//
|
//
|
||||||
v2 := GP64() // reg_v2 = GeneralPurposeRegister64()
|
v2 := GP64() // reg_v2 = GeneralPurposeRegister64()
|
||||||
v3 := GP64() // reg_v3 = GeneralPurposeRegister64()
|
v3 := GP64() // reg_v3 = GeneralPurposeRegister64()
|
||||||
@@ -208,7 +208,7 @@ func main() {
|
|||||||
//
|
//
|
||||||
r := GP64() // r = GeneralPurposeRegister64()
|
r := GP64() // r = GeneralPurposeRegister64()
|
||||||
loop := "block" // with Loop() as loop:
|
loop := "block" // with Loop() as loop:
|
||||||
LABEL(loop)
|
Label(loop)
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k2U32, r) // imul(r, k2U32)
|
imul(k2U32, r) // imul(r, k2U32)
|
||||||
ADDQ(r, v0) // ADD(reg_v0, r)
|
ADDQ(r, v0) // ADD(reg_v0, r)
|
||||||
@@ -253,7 +253,7 @@ func main() {
|
|||||||
CMPQ(u64s, U32(i)) // CMP(reg_u64s, i)
|
CMPQ(u64s, U32(i)) // CMP(reg_u64s, i)
|
||||||
JE(LabelRef(labels[i])) // JE(labels[i])
|
JE(LabelRef(labels[i])) // JE(labels[i])
|
||||||
} //
|
} //
|
||||||
LABEL(labels[3]) // LABEL(labels[3])
|
Label(labels[3]) // Label(labels[3])
|
||||||
//
|
//
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k2U32, r) // imul(r, k2U32)
|
imul(k2U32, r) // imul(r, k2U32)
|
||||||
@@ -263,7 +263,7 @@ func main() {
|
|||||||
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
||||||
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
||||||
//
|
//
|
||||||
LABEL(labels[2]) // LABEL(labels[2])
|
Label(labels[2]) // Label(labels[2])
|
||||||
//
|
//
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k3U32, r) // imul(r, k3U32)
|
imul(k3U32, r) // imul(r, k3U32)
|
||||||
@@ -273,7 +273,7 @@ func main() {
|
|||||||
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
||||||
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
||||||
//
|
//
|
||||||
LABEL(labels[1]) // LABEL(labels[1])
|
Label(labels[1]) // Label(labels[1])
|
||||||
//
|
//
|
||||||
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
MOVQ(Mem{Base: ptr}, r) // MOV(r, [reg_ptr])
|
||||||
imul(k4U32, r) // imul(r, k4U32)
|
imul(k4U32, r) // imul(r, k4U32)
|
||||||
@@ -283,7 +283,7 @@ func main() {
|
|||||||
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
ADDQ(U32(8), ptr) // ADD(reg_ptr, 8)
|
||||||
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
SUBQ(U32(8), n) // SUB(reg_ptr_len, 8)
|
||||||
//
|
//
|
||||||
LABEL(labels[0]) // LABEL(labels[0])
|
Label(labels[0]) // Label(labels[0])
|
||||||
//
|
//
|
||||||
RORQ(U8(11), v3) // ROR(reg_v3, 11)
|
RORQ(U8(11), v3) // ROR(reg_v3, 11)
|
||||||
SUBQ(v1, v3) // SUB(reg_v3, reg_v1)
|
SUBQ(v1, v3) // SUB(reg_v3, reg_v1)
|
||||||
@@ -304,11 +304,11 @@ func main() {
|
|||||||
//
|
//
|
||||||
// reg_ch = GeneralPurposeRegister64()
|
// reg_ch = GeneralPurposeRegister64()
|
||||||
//
|
//
|
||||||
LABEL(labels[7]) // LABEL(labels[7])
|
Label(labels[7]) // Label(labels[7])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
MOVBQZX(Mem{Base: ptr, Disp: 6}, ch) // MOVZX(reg_ch, byte[reg_ptr+6])
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[6]) // LABEL(labels[6])
|
Label(labels[6]) // Label(labels[6])
|
||||||
// XOR(reg_ch, reg_ch)
|
// XOR(reg_ch, reg_ch)
|
||||||
MOVWQZX(Mem{Base: ptr, Disp: 4}, ch) // MOV(reg_ch.as_word, word[reg_ptr + 4])
|
MOVWQZX(Mem{Base: ptr, Disp: 4}, ch) // MOV(reg_ch.as_word, word[reg_ptr + 4])
|
||||||
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
@@ -316,37 +316,37 @@ func main() {
|
|||||||
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
||||||
JMP(LabelRef(after)) // JMP(after)
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
//
|
//
|
||||||
LABEL(labels[5]) // LABEL(labels[5])
|
Label(labels[5]) // Label(labels[5])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
MOVBQZX(Mem{Base: ptr, Disp: 4}, ch) // MOVZX(reg_ch, byte[reg_ptr+4])
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[4]) // LABEL(labels[4])
|
Label(labels[4]) // Label(labels[4])
|
||||||
// XOR(reg_ch, reg_ch)
|
// XOR(reg_ch, reg_ch)
|
||||||
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
MOVLQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_dword, dword[reg_ptr])
|
||||||
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
//
|
//
|
||||||
JMP(LabelRef(after)) // JMP(after)
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
//
|
//
|
||||||
LABEL(labels[3]) // LABEL(labels[3])
|
Label(labels[3]) // Label(labels[3])
|
||||||
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
MOVBQZX(Mem{Base: ptr, Disp: 2}, ch) // MOVZX(reg_ch, byte[reg_ptr+2])
|
||||||
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
ADDQ(ch, v3) // ADD(reg_v3, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[2]) // LABEL(labels[2])
|
Label(labels[2]) // Label(labels[2])
|
||||||
// XOR(reg_ch, reg_ch)
|
// XOR(reg_ch, reg_ch)
|
||||||
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
MOVWQZX(Mem{Base: ptr}, ch) // MOV(reg_ch.as_word, word[reg_ptr])
|
||||||
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
ADDQ(ch, v1) // ADD(reg_v1, reg_ch)
|
||||||
//
|
//
|
||||||
JMP(LabelRef(after)) // JMP(after)
|
JMP(LabelRef(after)) // JMP(after)
|
||||||
//
|
//
|
||||||
LABEL(labels[1]) // LABEL(labels[1])
|
Label(labels[1]) // Label(labels[1])
|
||||||
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
MOVBQZX(Mem{Base: ptr}, ch) // MOVZX(reg_ch, byte[reg_ptr])
|
||||||
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
ADDQ(ch, v2) // ADD(reg_v2, reg_ch)
|
||||||
//
|
//
|
||||||
LABEL(labels[0]) // LABEL(labels[0])
|
Label(labels[0]) // Label(labels[0])
|
||||||
ROLQ(U8(32), v3) // ROL(reg_v3, 32)
|
ROLQ(U8(32), v3) // ROL(reg_v3, 32)
|
||||||
XORQ(U32(0xff), v3) // XOR(reg_v3, 0xFF)
|
XORQ(U32(0xff), v3) // XOR(reg_v3, 0xFF)
|
||||||
//
|
//
|
||||||
LABEL(after) // LABEL(after)
|
Label(after) // Label(after)
|
||||||
//
|
//
|
||||||
// ## finalize
|
// ## finalize
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ func main() {
|
|||||||
n := Load(Param("xs").Len(), GP64())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
Label("loop")
|
||||||
CMPQ(n, Imm(0))
|
CMPQ(n, Imm(0))
|
||||||
JE(LabelRef("done"))
|
JE(LabelRef("done"))
|
||||||
ADDQ(Mem{Base: ptr}, s)
|
ADDQ(Mem{Base: ptr}, s)
|
||||||
ADDQ(Imm(8), ptr)
|
ADDQ(Imm(8), ptr)
|
||||||
DECQ(n)
|
DECQ(n)
|
||||||
JMP(LabelRef("loop"))
|
JMP(LabelRef("loop"))
|
||||||
LABEL("done")
|
Label("done")
|
||||||
Store(s, ReturnIndex(0))
|
Store(s, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
Generate()
|
Generate()
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ func main() {
|
|||||||
n := Load(Param("xs").Len(), GP64())
|
n := Load(Param("xs").Len(), GP64())
|
||||||
s := GP64()
|
s := GP64()
|
||||||
XORQ(s, s)
|
XORQ(s, s)
|
||||||
LABEL("loop")
|
Label("loop")
|
||||||
CMPQ(n, Imm(0))
|
CMPQ(n, Imm(0))
|
||||||
JE(LabelRef("done"))
|
JE(LabelRef("done"))
|
||||||
ADDQ(Mem{Base: ptr}, s)
|
ADDQ(Mem{Base: ptr}, s)
|
||||||
ADDQ(Imm(8), ptr)
|
ADDQ(Imm(8), ptr)
|
||||||
DECQ(n)
|
DECQ(n)
|
||||||
JMP(LabelRef("loop"))
|
JMP(LabelRef("loop"))
|
||||||
LABEL("done")
|
Label("done")
|
||||||
Store(s, ReturnIndex(0))
|
Store(s, ReturnIndex(0))
|
||||||
RET()
|
RET()
|
||||||
Generate()
|
Generate()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pass
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mmcloughlin/avo"
|
"github.com/mmcloughlin/avo"
|
||||||
|
"github.com/mmcloughlin/avo/attr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IncludeTextFlagHeader includes textflag.h if necessary.
|
// IncludeTextFlagHeader includes textflag.h if necessary.
|
||||||
@@ -26,7 +27,7 @@ func IncludeTextFlagHeader(f *avo.File) error {
|
|||||||
// requirestextflags returns whether the file uses flags in the textflags.h header.
|
// requirestextflags returns whether the file uses flags in the textflags.h header.
|
||||||
func requirestextflags(f *avo.File) bool {
|
func requirestextflags(f *avo.File) bool {
|
||||||
for _, s := range f.Sections {
|
for _, s := range f.Sections {
|
||||||
var a avo.Attribute
|
var a attr.Attribute
|
||||||
switch s := s.(type) {
|
switch s := s.(type) {
|
||||||
case *avo.Function:
|
case *avo.Function:
|
||||||
a = s.Attributes
|
a = s.Attributes
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package printer_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mmcloughlin/avo"
|
"github.com/mmcloughlin/avo/attr"
|
||||||
"github.com/mmcloughlin/avo/build"
|
"github.com/mmcloughlin/avo/build"
|
||||||
"github.com/mmcloughlin/avo/printer"
|
"github.com/mmcloughlin/avo/printer"
|
||||||
"github.com/mmcloughlin/avo/reg"
|
"github.com/mmcloughlin/avo/reg"
|
||||||
@@ -47,7 +47,7 @@ func TestTextDecl(t *testing.T) {
|
|||||||
|
|
||||||
ctx.Function("withattr")
|
ctx.Function("withattr")
|
||||||
ctx.SignatureExpr("func()")
|
ctx.SignatureExpr("func()")
|
||||||
ctx.Attributes(avo.NOSPLIT | avo.TLSBSS)
|
ctx.Attributes(attr.NOSPLIT | attr.TLSBSS)
|
||||||
ctx.RET()
|
ctx.RET()
|
||||||
|
|
||||||
AssertPrintsLines(t, ctx, printer.NewGoAsm, []string{
|
AssertPrintsLines(t, ctx, printer.NewGoAsm, []string{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/mmcloughlin/avo"
|
"github.com/mmcloughlin/avo/attr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -22,25 +22,25 @@ var (
|
|||||||
num = flag.Int("num", 32, "number of attributes to generate")
|
num = flag.Int("num", 32, "number of attributes to generate")
|
||||||
)
|
)
|
||||||
|
|
||||||
func GenerateAttributes(n int) []avo.Attribute {
|
func GenerateAttributes(n int) []attr.Attribute {
|
||||||
as := make([]avo.Attribute, 0, n)
|
as := make([]attr.Attribute, 0, n)
|
||||||
|
|
||||||
// Include each bitlevel.
|
// Include each bitlevel.
|
||||||
for i := 0; i < 16 && i < n; i++ {
|
for i := 0; i < 16 && i < n; i++ {
|
||||||
a := avo.Attribute(1 << uint(i))
|
a := attr.Attribute(1 << uint(i))
|
||||||
as = append(as, a)
|
as = append(as, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add randomly generated attributes.
|
// Add randomly generated attributes.
|
||||||
for len(as) < n {
|
for len(as) < n {
|
||||||
a := avo.Attribute(rand.Uint32())
|
a := attr.Attribute(rand.Uint32())
|
||||||
as = append(as, a)
|
as = append(as, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
return as
|
return as
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrintAttributesTest(w io.Writer, as []avo.Attribute) {
|
func PrintAttributesTest(w io.Writer, as []attr.Attribute) {
|
||||||
_, self, _, _ := runtime.Caller(0)
|
_, self, _, _ := runtime.Caller(0)
|
||||||
fmt.Fprintf(w, "// Code generated by %s. DO NOT EDIT.\n\n", filepath.Base(self))
|
fmt.Fprintf(w, "// Code generated by %s. DO NOT EDIT.\n\n", filepath.Base(self))
|
||||||
fmt.Fprintf(w, "#include \"textflag.h\"\n\n")
|
fmt.Fprintf(w, "#include \"textflag.h\"\n\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user