Files
avo/reg/types.go

158 lines
2.6 KiB
Go
Raw Normal View History

2018-11-11 22:17:06 -06:00
package reg
2018-12-02 23:59:29 -08:00
import (
"fmt"
)
2018-12-02 15:15:00 -08:00
2018-11-11 22:17:06 -06:00
type Size uint
const (
B8 Size = 1 << iota
B16
B32
B64
B128
B256
B512
)
func (s Size) Bytes() uint { return uint(s) }
type Kind uint8
type Family struct {
Kind Kind
2018-12-02 21:35:33 -08:00
registers []Physical
2018-11-11 22:17:06 -06:00
}
2018-12-02 23:59:29 -08:00
func (f *Family) define(s Spec, id PID, name string) Physical {
2018-11-11 22:17:06 -06:00
r := register{
id: id,
kind: f.Kind,
name: name,
Spec: s,
}
f.registers = append(f.registers, r)
return r
}
2018-12-02 23:59:29 -08:00
func (f *Family) Virtual(id VID, s Size) Virtual {
2018-12-03 20:40:43 -08:00
return NewVirtual(id, f.Kind, s)
2018-11-11 22:17:06 -06:00
}
2018-12-03 22:39:43 -08:00
// Registers returns the registers in this family.
func (f *Family) Registers() []Physical {
rs := make([]Physical, 0, len(f.registers))
for _, r := range f.registers {
rs = append(rs, r)
}
return rs
}
// Set returns the set of registers in the family.
func (f *Family) Set() Set {
s := NewEmptySet()
for _, r := range f.registers {
s.Add(r)
}
return s
}
2018-11-11 22:17:06 -06:00
type private interface {
private()
}
2018-12-02 23:59:29 -08:00
type (
ID uint32
VID uint16
PID uint16
)
2018-12-02 21:35:33 -08:00
type Register interface {
2018-12-02 23:59:29 -08:00
ID() ID
2018-11-11 22:17:06 -06:00
Kind() Kind
Bytes() uint
2018-12-02 15:15:00 -08:00
Asm() string
private
}
type Virtual interface {
2018-12-02 23:59:29 -08:00
VirtualID() VID
2018-12-02 21:35:33 -08:00
Register
2018-11-11 22:17:06 -06:00
}
type virtual struct {
2018-12-02 23:59:29 -08:00
id VID
2018-11-11 22:17:06 -06:00
kind Kind
Size
}
2018-12-03 20:40:43 -08:00
func NewVirtual(id VID, k Kind, s Size) Virtual {
return virtual{
id: id,
kind: k,
Size: s,
}
}
2018-12-02 23:59:29 -08:00
func (v virtual) VirtualID() VID { return v.id }
func (v virtual) Kind() Kind { return v.kind }
func (v virtual) ID() ID {
2018-12-03 22:39:43 -08:00
return (ID(1) << 31) | ID(v.VirtualID())
2018-12-02 23:59:29 -08:00
}
2018-11-11 22:17:06 -06:00
2018-12-02 15:15:00 -08:00
func (v virtual) Asm() string {
// TODO(mbm): decide on virtual register syntax
return fmt.Sprintf("<virtual:%v:%v:%v>", v.id, v.Kind(), v.Bytes())
}
func (v virtual) private() {}
2018-12-02 21:35:33 -08:00
type Physical interface {
2018-12-02 23:59:29 -08:00
PhysicalID() PID
2018-11-11 22:17:06 -06:00
Mask() uint16
2018-12-02 21:35:33 -08:00
Register
2018-11-11 22:17:06 -06:00
}
type register struct {
2018-12-02 23:59:29 -08:00
id PID
2018-11-11 22:17:06 -06:00
kind Kind
name string
Spec
}
2018-12-02 23:59:29 -08:00
func (r register) PhysicalID() PID { return r.id }
2018-12-03 22:39:43 -08:00
func (r register) ID() ID { return (ID(r.Mask()) << 16) | ID(r.id) }
2018-12-02 23:59:29 -08:00
func (r register) Kind() Kind { return r.kind }
func (r register) Asm() string { return r.name }
func (r register) private() {}
2018-11-11 22:17:06 -06:00
type Spec uint16
const (
S8L Spec = 0x1
S8H Spec = 0x2
S8 = S8L
S16 Spec = 0x3
S32 Spec = 0x7
S64 Spec = 0xf
S128 Spec = 0x1f
S256 Spec = 0x3f
S512 Spec = 0x7f
)
// Mask returns a mask representing which bytes of an underlying register are
// used by this register. This is almost always the low bytes, except for the
// case of the high-byte registers. If bit n of the mask is set, this means
// bytes 2^(n-1) to 2^n-1 are used.
func (s Spec) Mask() uint16 {
return uint16(s)
}
// Bytes returns the register size in bytes.
func (s Spec) Bytes() uint {
x := uint(s)
return (x >> 1) + (x & 1)
}