.: doc exported symbols (#9)
This commit is contained in:
32
ast.go
32
ast.go
@@ -9,14 +9,12 @@ import (
|
|||||||
"github.com/mmcloughlin/avo/reg"
|
"github.com/mmcloughlin/avo/reg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Asm interface {
|
// Node is a part of a Function.
|
||||||
Asm() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Node interface {
|
type Node interface {
|
||||||
node()
|
node()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Label within a function.
|
||||||
type Label string
|
type Label string
|
||||||
|
|
||||||
func (l Label) node() {}
|
func (l Label) node() {}
|
||||||
@@ -44,6 +42,8 @@ type Instruction struct {
|
|||||||
|
|
||||||
func (i *Instruction) node() {}
|
func (i *Instruction) node() {}
|
||||||
|
|
||||||
|
// TargetLabel returns the label referenced by this instruction. Returns nil if
|
||||||
|
// no label is referenced.
|
||||||
func (i Instruction) TargetLabel() *Label {
|
func (i Instruction) TargetLabel() *Label {
|
||||||
if !i.IsBranch {
|
if !i.IsBranch {
|
||||||
return nil
|
return nil
|
||||||
@@ -58,6 +58,7 @@ func (i Instruction) TargetLabel() *Label {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Registers returns all registers involved in the instruction.
|
||||||
func (i Instruction) Registers() []reg.Register {
|
func (i Instruction) Registers() []reg.Register {
|
||||||
var rs []reg.Register
|
var rs []reg.Register
|
||||||
for _, op := range i.Operands {
|
for _, op := range i.Operands {
|
||||||
@@ -66,6 +67,7 @@ func (i Instruction) Registers() []reg.Register {
|
|||||||
return rs
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InputRegisters returns all registers read by this instruction.
|
||||||
func (i Instruction) InputRegisters() []reg.Register {
|
func (i Instruction) InputRegisters() []reg.Register {
|
||||||
var rs []reg.Register
|
var rs []reg.Register
|
||||||
for _, op := range i.Inputs {
|
for _, op := range i.Inputs {
|
||||||
@@ -79,6 +81,7 @@ func (i Instruction) InputRegisters() []reg.Register {
|
|||||||
return rs
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OutputRegisters returns all registers written by this instruction.
|
||||||
func (i Instruction) OutputRegisters() []reg.Register {
|
func (i Instruction) OutputRegisters() []reg.Register {
|
||||||
var rs []reg.Register
|
var rs []reg.Register
|
||||||
for _, op := range i.Outputs {
|
for _, op := range i.Outputs {
|
||||||
@@ -89,6 +92,7 @@ func (i Instruction) OutputRegisters() []reg.Register {
|
|||||||
return rs
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Section is a part of a file.
|
||||||
type Section interface {
|
type Section interface {
|
||||||
section()
|
section()
|
||||||
}
|
}
|
||||||
@@ -100,14 +104,17 @@ type File struct {
|
|||||||
Sections []Section
|
Sections []Section
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFile initializes an empty file.
|
||||||
func NewFile() *File {
|
func NewFile() *File {
|
||||||
return &File{}
|
return &File{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddSection appends a Section to the file.
|
||||||
func (f *File) AddSection(s Section) {
|
func (f *File) AddSection(s Section) {
|
||||||
f.Sections = append(f.Sections, s)
|
f.Sections = append(f.Sections, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Functions returns all functions in the file.
|
||||||
func (f *File) Functions() []*Function {
|
func (f *File) Functions() []*Function {
|
||||||
var fns []*Function
|
var fns []*Function
|
||||||
for _, s := range f.Sections {
|
for _, s := range f.Sections {
|
||||||
@@ -137,6 +144,7 @@ type Function struct {
|
|||||||
|
|
||||||
func (f *Function) section() {}
|
func (f *Function) section() {}
|
||||||
|
|
||||||
|
// NewFunction builds an empty function of the given name.
|
||||||
func NewFunction(name string) *Function {
|
func NewFunction(name string) *Function {
|
||||||
return &Function{
|
return &Function{
|
||||||
Name: name,
|
Name: name,
|
||||||
@@ -144,24 +152,30 @@ func NewFunction(name string) *Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSignature sets the function signature.
|
||||||
func (f *Function) SetSignature(s *gotypes.Signature) {
|
func (f *Function) SetSignature(s *gotypes.Signature) {
|
||||||
f.Signature = s
|
f.Signature = s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllocLocal allocates size bytes in this function's stack.
|
||||||
|
// Returns a reference to the base pointer for the newly allocated region.
|
||||||
func (f *Function) AllocLocal(size int) operand.Mem {
|
func (f *Function) AllocLocal(size int) operand.Mem {
|
||||||
ptr := operand.NewStackAddr(f.LocalSize)
|
ptr := operand.NewStackAddr(f.LocalSize)
|
||||||
f.LocalSize += size
|
f.LocalSize += size
|
||||||
return ptr
|
return ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddInstruction appends an instruction to f.
|
||||||
func (f *Function) AddInstruction(i *Instruction) {
|
func (f *Function) AddInstruction(i *Instruction) {
|
||||||
f.AddNode(i)
|
f.AddNode(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddLabel appends a label to f.
|
||||||
func (f *Function) AddLabel(l Label) {
|
func (f *Function) AddLabel(l Label) {
|
||||||
f.AddNode(l)
|
f.AddNode(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNode appends a Node to f.
|
||||||
func (f *Function) AddNode(n Node) {
|
func (f *Function) AddNode(n Node) {
|
||||||
f.Nodes = append(f.Nodes, n)
|
f.Nodes = append(f.Nodes, n)
|
||||||
}
|
}
|
||||||
@@ -193,11 +207,13 @@ func (f *Function) ArgumentBytes() int {
|
|||||||
return f.Signature.Bytes()
|
return f.Signature.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Datum represents a data element at a particular offset of a data section.
|
||||||
type Datum struct {
|
type Datum struct {
|
||||||
Offset int
|
Offset int
|
||||||
Value operand.Constant
|
Value operand.Constant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDatum builds a Datum from the given constant.
|
||||||
func NewDatum(offset int, v operand.Constant) Datum {
|
func NewDatum(offset int, v operand.Constant) Datum {
|
||||||
return Datum{
|
return Datum{
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
@@ -210,12 +226,14 @@ func (d Datum) Interval() (int, int) {
|
|||||||
return d.Offset, d.Offset + d.Value.Bytes()
|
return d.Offset, d.Offset + d.Value.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overlaps returns true
|
||||||
func (d Datum) Overlaps(other Datum) bool {
|
func (d Datum) Overlaps(other Datum) bool {
|
||||||
s, e := d.Interval()
|
s, e := d.Interval()
|
||||||
so, eo := other.Interval()
|
so, eo := other.Interval()
|
||||||
return !(eo <= s || e <= so)
|
return !(eo <= s || e <= so)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Global represents a DATA section.
|
||||||
type Global struct {
|
type Global struct {
|
||||||
Symbol operand.Symbol
|
Symbol operand.Symbol
|
||||||
Attributes Attribute
|
Attributes Attribute
|
||||||
@@ -223,28 +241,33 @@ type Global struct {
|
|||||||
Size int
|
Size int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGlobal constructs an empty DATA section.
|
||||||
func NewGlobal(sym operand.Symbol) *Global {
|
func NewGlobal(sym operand.Symbol) *Global {
|
||||||
return &Global{
|
return &Global{
|
||||||
Symbol: sym,
|
Symbol: sym,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStaticGlobal is a convenience for building a static DATA section.
|
||||||
func NewStaticGlobal(name string) *Global {
|
func NewStaticGlobal(name string) *Global {
|
||||||
return NewGlobal(operand.NewStaticSymbol(name))
|
return NewGlobal(operand.NewStaticSymbol(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Global) section() {}
|
func (g *Global) section() {}
|
||||||
|
|
||||||
|
// Base returns a pointer to the start of the data section.
|
||||||
func (g *Global) Base() operand.Mem {
|
func (g *Global) Base() operand.Mem {
|
||||||
return operand.NewDataAddr(g.Symbol, 0)
|
return operand.NewDataAddr(g.Symbol, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grow ensures that the data section has at least the given size.
|
||||||
func (g *Global) Grow(size int) {
|
func (g *Global) Grow(size int) {
|
||||||
if g.Size < size {
|
if g.Size < size {
|
||||||
g.Size = size
|
g.Size = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDatum adds d to this data section, growing it if necessary. Errors if the datum overlaps with existing data.
|
||||||
func (g *Global) AddDatum(d Datum) error {
|
func (g *Global) AddDatum(d Datum) error {
|
||||||
for _, other := range g.Data {
|
for _, other := range g.Data {
|
||||||
if d.Overlaps(other) {
|
if d.Overlaps(other) {
|
||||||
@@ -255,6 +278,7 @@ func (g *Global) AddDatum(d Datum) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append the constant to the end of the data section.
|
||||||
func (g *Global) Append(v operand.Constant) {
|
func (g *Global) Append(v operand.Constant) {
|
||||||
g.add(Datum{
|
g.add(Datum{
|
||||||
Offset: g.Size,
|
Offset: g.Size,
|
||||||
|
|||||||
6
attr.go
6
attr.go
@@ -9,7 +9,7 @@ import (
|
|||||||
// Attribute represents TEXT or DATA flags.
|
// Attribute represents TEXT or DATA flags.
|
||||||
type Attribute uint16
|
type Attribute uint16
|
||||||
|
|
||||||
// Reference: https://github.com/golang/go/blob/c043fc4f655ce34f67a0e7fe2833139f6313a3f0/src/runtime/textflag.h#L11-L34
|
// Reference: https://github.com/golang/go/blob/35f4ec152b44ae5fc83aaf68e2eb3aa1a778e5cd/src/runtime/textflag.h#L11-L34
|
||||||
//
|
//
|
||||||
// // Don't profile the marked routine. This flag is deprecated.
|
// // Don't profile the marked routine. This flag is deprecated.
|
||||||
// #define NOPROF 1
|
// #define NOPROF 1
|
||||||
@@ -34,7 +34,7 @@ type Attribute uint16
|
|||||||
// // TODO(mwhudson): only implemented for ppc64x at present.
|
// // TODO(mwhudson): only implemented for ppc64x at present.
|
||||||
// #define NOFRAME 512
|
// #define NOFRAME 512
|
||||||
// // Function can call reflect.Type.Method or reflect.Type.MethodByName.
|
// // Function can call reflect.Type.Method or reflect.Type.MethodByName.
|
||||||
// #define REFLECTMETHOD = 1024
|
// #define REFLECTMETHOD 1024
|
||||||
//
|
//
|
||||||
const (
|
const (
|
||||||
NOPROF Attribute = 1 << iota
|
NOPROF Attribute = 1 << iota
|
||||||
@@ -59,7 +59,7 @@ func (a Attribute) Asm() string {
|
|||||||
return strings.Join(parts, "|")
|
return strings.Join(parts, "|")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainsTextFlags() returns whether the Asm() representation requires macros in "textflags.h".
|
// ContainsTextFlags returns whether the Asm() representation requires macros in "textflags.h".
|
||||||
func (a Attribute) ContainsTextFlags() bool {
|
func (a Attribute) ContainsTextFlags() bool {
|
||||||
flags, _ := a.split()
|
flags, _ := a.split()
|
||||||
return len(flags) > 0
|
return len(flags) > 0
|
||||||
|
|||||||
Reference in New Issue
Block a user