From dc571a47df56f7b18b2dcdc2354bd1f78cac869a Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Fri, 4 Jan 2019 22:06:00 -0800 Subject: [PATCH] reg: doc exported symbols (#9) --- reg/collection.go | 31 ++++++++++++++++++++++--------- reg/types.go | 31 ++++++++++++++++++++++++++----- reg/x86.go | 8 +++++++- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/reg/collection.go b/reg/collection.go index ff22286..548d61c 100644 --- a/reg/collection.go +++ b/reg/collection.go @@ -1,35 +1,48 @@ package reg +// Collection represents a collection of virtual registers. This is primarily +// useful for allocating virtual registers with distinct IDs. type Collection struct { vid map[Kind]VID } +// NewCollection builds an empty register collection. func NewCollection() *Collection { return &Collection{ 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 { vid := c.vid[k] c.vid[k]++ 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)) } diff --git a/reg/types.go b/reg/types.go index 71c478c..e111139 100644 --- a/reg/types.go +++ b/reg/types.go @@ -5,8 +5,10 @@ import ( "fmt" ) +// Size is a register size. type Size uint +// Typical register sizes. const ( B8 Size = 1 << iota B16 @@ -17,21 +19,26 @@ const ( B512 ) +// Bytes returns the register size in bytes. func (s Size) Bytes() uint { return uint(s) } +// Kind is a class of registers. type Kind uint8 +// Family is a collection of Physical registers of a common kind. type Family struct { Kind Kind 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 { r := newregister(f, s, id, name, flags...) f.add(r) return r } +// add r to the family. func (f *Family) add(r Physical) { if r.Kind() != f.Kind { panic("bad kind") @@ -39,6 +46,7 @@ func (f *Family) add(r Physical) { 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 { return NewVirtual(id, f.Kind, s) } @@ -67,11 +75,7 @@ func (f *Family) Lookup(id PID, s Spec) Physical { return nil } -type ( - VID uint16 - PID uint16 -) - +// Register represents a virtual or physical register. type Register interface { Kind() Kind Bytes() uint @@ -80,6 +84,10 @@ type Register interface { 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 { VirtualID() VID SatisfiedBy(Physical) bool @@ -101,6 +109,7 @@ type virtual struct { mask uint16 } +// NewVirtual builds a Virtual register. func NewVirtual(id VID, k Kind, s Size) Virtual { return virtual{ id: id, @@ -132,13 +141,19 @@ func (v virtual) as(s Spec) Register { func (v virtual) register() {} +// Info is a bitmask of register properties. type Info uint8 +// Defined register Info flags. const ( None Info = 0 Restricted Info = 1 << iota ) +// PID is a physical register ID. +type PID uint16 + +// Physical is a concrete register. type Physical interface { PhysicalID() PID Mask() uint16 @@ -154,6 +169,7 @@ func ToPhysical(r Register) Physical { return nil } +// register implements Physical. type register struct { family *Family id PID @@ -187,8 +203,11 @@ func (r register) as(s Spec) 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 +// Spec values required for x86-64. const ( S0 Spec = 0x0 // zero value reserved for pseudo registers S8L Spec = 0x1 @@ -224,6 +243,7 @@ func AreConflicting(x, y Physical) bool { // Allocation records a register allocation. type Allocation map[Register]Physical +// NewEmptyAllocation builds an empty register allocation. func NewEmptyAllocation() Allocation { return Allocation{} } @@ -240,6 +260,7 @@ func (a Allocation) Merge(b Allocation) error { return nil } +// LookupDefault returns the register assigned to r, or r itself if there is none. func (a Allocation) LookupDefault(r Register) Register { if p, found := a[r]; found { return p diff --git a/reg/x86.go b/reg/x86.go index 79687fc..96316bd 100644 --- a/reg/x86.go +++ b/reg/x86.go @@ -28,6 +28,7 @@ func init() { } } +// FamilyOfKind returns the Family of registers of the given kind. func FamilyOfKind(k Kind) *Family { return familiesByKind[k] } @@ -40,7 +41,7 @@ var ( 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 { As8() 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) As64() Register { return c.as(S64) } +// GPPhysical is a general-purpose physical register. type GPPhysical interface { Physical GP @@ -73,6 +75,7 @@ type gpp struct { func newgpp(r Physical) GPPhysical { return gpp{Physical: r, GP: gpcasts{r}} } +// GPVirtual is a general-purpose virtual register. type GPVirtual interface { Virtual GP @@ -174,6 +177,7 @@ var ( R15 = gp(S64, 15, "R15") ) +// Vec provides methods for vector registers. type Vec interface { AsX() 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) AsZ() Register { return c.as(S512) } +// VecPhysical is a physical vector register. type VecPhysical interface { Physical Vec @@ -200,6 +205,7 @@ type vecp struct { func newvecp(r Physical) VecPhysical { return vecp{Physical: r, Vec: veccasts{r}} } +// VecVirtual is a virtual vector register. type VecVirtual interface { Virtual Vec