reg: doc exported symbols (#9)
This commit is contained in:
@@ -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)) }
|
||||
|
||||
31
reg/types.go
31
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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user