reg: doc exported symbols (#9)

This commit is contained in:
Michael McLoughlin
2019-01-04 22:06:00 -08:00
parent 2e250a6f4c
commit dc571a47df
3 changed files with 55 additions and 15 deletions

View File

@@ -1,35 +1,48 @@
package reg package reg
// Collection represents a collection of virtual registers. This is primarily
// useful for allocating virtual registers with distinct IDs.
type Collection struct { type Collection struct {
vid map[Kind]VID vid map[Kind]VID
} }
// NewCollection builds an empty register collection.
func NewCollection() *Collection { func NewCollection() *Collection {
return &Collection{ return &Collection{
vid: map[Kind]VID{}, vid: map[Kind]VID{},
} }
} }
// VirtualRegister allocates and returns a new virtual register of the given kind and size.
func (c *Collection) VirtualRegister(k Kind, s Size) Virtual { func (c *Collection) VirtualRegister(k Kind, s Size) Virtual {
vid := c.vid[k] vid := c.vid[k]
c.vid[k]++ c.vid[k]++
return NewVirtual(vid, k, s) return NewVirtual(vid, k, s)
} }
func (c *Collection) GP8() GPVirtual { return c.GPv(B8) } // GP8 allocates and returns a general-purpose 8-bit register.
func (c *Collection) GP8() GPVirtual { return c.GP(B8) }
func (c *Collection) GP16() GPVirtual { return c.GPv(B16) } // GP16 allocates and returns a general-purpose 16-bit register.
func (c *Collection) GP16() GPVirtual { return c.GP(B16) }
func (c *Collection) GP32() GPVirtual { return c.GPv(B32) } // GP32 allocates and returns a general-purpose 32-bit register.
func (c *Collection) GP32() GPVirtual { return c.GP(B32) }
func (c *Collection) GP64() GPVirtual { return c.GPv(B64) } // GP64 allocates and returns a general-purpose 64-bit register.
func (c *Collection) GP64() GPVirtual { return c.GP(B64) }
func (c *Collection) GPv(s Size) GPVirtual { return newgpv(c.VirtualRegister(KindGP, s)) } // GP allocates and returns a general-purpose register of the given size.
func (c *Collection) GP(s Size) GPVirtual { return newgpv(c.VirtualRegister(KindGP, s)) }
func (c *Collection) XMM() VecVirtual { return c.Vecv(B128) } // XMM allocates and returns a 128-bit vector register.
func (c *Collection) XMM() VecVirtual { return c.Vec(B128) }
func (c *Collection) YMM() VecVirtual { return c.Vecv(B256) } // YMM allocates and returns a 256-bit vector register.
func (c *Collection) YMM() VecVirtual { return c.Vec(B256) }
func (c *Collection) ZMM() VecVirtual { return c.Vecv(B512) } // ZMM allocates and returns a 512-bit vector register.
func (c *Collection) ZMM() VecVirtual { return c.Vec(B512) }
func (c *Collection) Vecv(s Size) VecVirtual { return newvecv(c.VirtualRegister(KindVector, s)) } // Vec allocates and returns a vector register of the given size.
func (c *Collection) Vec(s Size) VecVirtual { return newvecv(c.VirtualRegister(KindVector, s)) }

View File

@@ -5,8 +5,10 @@ import (
"fmt" "fmt"
) )
// Size is a register size.
type Size uint type Size uint
// Typical register sizes.
const ( const (
B8 Size = 1 << iota B8 Size = 1 << iota
B16 B16
@@ -17,21 +19,26 @@ const (
B512 B512
) )
// Bytes returns the register size in bytes.
func (s Size) Bytes() uint { return uint(s) } func (s Size) Bytes() uint { return uint(s) }
// Kind is a class of registers.
type Kind uint8 type Kind uint8
// Family is a collection of Physical registers of a common kind.
type Family struct { type Family struct {
Kind Kind Kind Kind
registers []Physical registers []Physical
} }
// define builds a register and adds it to the Family.
func (f *Family) define(s Spec, id PID, name string, flags ...Info) Physical { func (f *Family) define(s Spec, id PID, name string, flags ...Info) Physical {
r := newregister(f, s, id, name, flags...) r := newregister(f, s, id, name, flags...)
f.add(r) f.add(r)
return r return r
} }
// add r to the family.
func (f *Family) add(r Physical) { func (f *Family) add(r Physical) {
if r.Kind() != f.Kind { if r.Kind() != f.Kind {
panic("bad kind") panic("bad kind")
@@ -39,6 +46,7 @@ func (f *Family) add(r Physical) {
f.registers = append(f.registers, r) f.registers = append(f.registers, r)
} }
// Virtual returns a virtual register from this family's kind.
func (f *Family) Virtual(id VID, s Size) Virtual { func (f *Family) Virtual(id VID, s Size) Virtual {
return NewVirtual(id, f.Kind, s) return NewVirtual(id, f.Kind, s)
} }
@@ -67,11 +75,7 @@ func (f *Family) Lookup(id PID, s Spec) Physical {
return nil return nil
} }
type ( // Register represents a virtual or physical register.
VID uint16
PID uint16
)
type Register interface { type Register interface {
Kind() Kind Kind() Kind
Bytes() uint Bytes() uint
@@ -80,6 +84,10 @@ type Register interface {
register() register()
} }
// VID is a virtual register ID.
type VID uint16
// Virtual is a register of a given type and size, not yet allocated to a physical register.
type Virtual interface { type Virtual interface {
VirtualID() VID VirtualID() VID
SatisfiedBy(Physical) bool SatisfiedBy(Physical) bool
@@ -101,6 +109,7 @@ type virtual struct {
mask uint16 mask uint16
} }
// NewVirtual builds a Virtual register.
func NewVirtual(id VID, k Kind, s Size) Virtual { func NewVirtual(id VID, k Kind, s Size) Virtual {
return virtual{ return virtual{
id: id, id: id,
@@ -132,13 +141,19 @@ func (v virtual) as(s Spec) Register {
func (v virtual) register() {} func (v virtual) register() {}
// Info is a bitmask of register properties.
type Info uint8 type Info uint8
// Defined register Info flags.
const ( const (
None Info = 0 None Info = 0
Restricted Info = 1 << iota Restricted Info = 1 << iota
) )
// PID is a physical register ID.
type PID uint16
// Physical is a concrete register.
type Physical interface { type Physical interface {
PhysicalID() PID PhysicalID() PID
Mask() uint16 Mask() uint16
@@ -154,6 +169,7 @@ func ToPhysical(r Register) Physical {
return nil return nil
} }
// register implements Physical.
type register struct { type register struct {
family *Family family *Family
id PID id PID
@@ -187,8 +203,11 @@ func (r register) as(s Spec) Register {
func (r register) register() {} func (r register) register() {}
// Spec defines the size of a register as well as the bit ranges it occupies in
// an underlying physical register.
type Spec uint16 type Spec uint16
// Spec values required for x86-64.
const ( const (
S0 Spec = 0x0 // zero value reserved for pseudo registers S0 Spec = 0x0 // zero value reserved for pseudo registers
S8L Spec = 0x1 S8L Spec = 0x1
@@ -224,6 +243,7 @@ func AreConflicting(x, y Physical) bool {
// Allocation records a register allocation. // Allocation records a register allocation.
type Allocation map[Register]Physical type Allocation map[Register]Physical
// NewEmptyAllocation builds an empty register allocation.
func NewEmptyAllocation() Allocation { func NewEmptyAllocation() Allocation {
return Allocation{} return Allocation{}
} }
@@ -240,6 +260,7 @@ func (a Allocation) Merge(b Allocation) error {
return nil return nil
} }
// LookupDefault returns the register assigned to r, or r itself if there is none.
func (a Allocation) LookupDefault(r Register) Register { func (a Allocation) LookupDefault(r Register) Register {
if p, found := a[r]; found { if p, found := a[r]; found {
return p return p

View File

@@ -28,6 +28,7 @@ func init() {
} }
} }
// FamilyOfKind returns the Family of registers of the given kind.
func FamilyOfKind(k Kind) *Family { func FamilyOfKind(k Kind) *Family {
return familiesByKind[k] return familiesByKind[k]
} }
@@ -40,7 +41,7 @@ var (
StackPointer = Pseudo.define(S0, 0, "SP") StackPointer = Pseudo.define(S0, 0, "SP")
) )
// GP is the interface for a general purpose register. // GP provides additional methods for general purpose registers.
type GP interface { type GP interface {
As8() Register As8() Register
As8L() Register As8L() Register
@@ -61,6 +62,7 @@ func (c gpcasts) As16() Register { return c.as(S16) }
func (c gpcasts) As32() Register { return c.as(S32) } func (c gpcasts) As32() Register { return c.as(S32) }
func (c gpcasts) As64() Register { return c.as(S64) } func (c gpcasts) As64() Register { return c.as(S64) }
// GPPhysical is a general-purpose physical register.
type GPPhysical interface { type GPPhysical interface {
Physical Physical
GP GP
@@ -73,6 +75,7 @@ type gpp struct {
func newgpp(r Physical) GPPhysical { return gpp{Physical: r, GP: gpcasts{r}} } func newgpp(r Physical) GPPhysical { return gpp{Physical: r, GP: gpcasts{r}} }
// GPVirtual is a general-purpose virtual register.
type GPVirtual interface { type GPVirtual interface {
Virtual Virtual
GP GP
@@ -174,6 +177,7 @@ var (
R15 = gp(S64, 15, "R15") R15 = gp(S64, 15, "R15")
) )
// Vec provides methods for vector registers.
type Vec interface { type Vec interface {
AsX() Register AsX() Register
AsY() Register AsY() Register
@@ -188,6 +192,7 @@ func (c veccasts) AsX() Register { return c.as(S128) }
func (c veccasts) AsY() Register { return c.as(S256) } func (c veccasts) AsY() Register { return c.as(S256) }
func (c veccasts) AsZ() Register { return c.as(S512) } func (c veccasts) AsZ() Register { return c.as(S512) }
// VecPhysical is a physical vector register.
type VecPhysical interface { type VecPhysical interface {
Physical Physical
Vec Vec
@@ -200,6 +205,7 @@ type vecp struct {
func newvecp(r Physical) VecPhysical { return vecp{Physical: r, Vec: veccasts{r}} } func newvecp(r Physical) VecPhysical { return vecp{Physical: r, Vec: veccasts{r}} }
// VecVirtual is a virtual vector register.
type VecVirtual interface { type VecVirtual interface {
Virtual Virtual
Vec Vec