reg.go

  1package regalloc
  2
  3import (
  4	"fmt"
  5
  6	"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
  7)
  8
  9// VReg represents a register which is assigned to an SSA value. This is used to represent a register in the backend.
 10// A VReg may or may not be a physical register, and the info of physical register can be obtained by RealReg.
 11type VReg uint64
 12
 13// VRegID is the lower 32bit of VReg, which is the pure identifier of VReg without RealReg info.
 14type VRegID uint32
 15
 16// RealReg returns the RealReg of this VReg.
 17func (v VReg) RealReg() RealReg {
 18	return RealReg(v >> 32)
 19}
 20
 21// IsRealReg returns true if this VReg is backed by a physical register.
 22func (v VReg) IsRealReg() bool {
 23	return v.RealReg() != RealRegInvalid
 24}
 25
 26// FromRealReg returns a VReg from the given RealReg and RegType.
 27// This is used to represent a specific pre-colored register in the backend.
 28func FromRealReg(r RealReg, typ RegType) VReg {
 29	rid := VRegID(r)
 30	if rid > vRegIDReservedForRealNum {
 31		panic(fmt.Sprintf("invalid real reg %d", r))
 32	}
 33	return VReg(r).SetRealReg(r).SetRegType(typ)
 34}
 35
 36// SetRealReg sets the RealReg of this VReg and returns the updated VReg.
 37func (v VReg) SetRealReg(r RealReg) VReg {
 38	return VReg(r)<<32 | (v & 0xff_00_ffffffff)
 39}
 40
 41// RegType returns the RegType of this VReg.
 42func (v VReg) RegType() RegType {
 43	return RegType(v >> 40)
 44}
 45
 46// SetRegType sets the RegType of this VReg and returns the updated VReg.
 47func (v VReg) SetRegType(t RegType) VReg {
 48	return VReg(t)<<40 | (v & 0x00_ff_ffffffff)
 49}
 50
 51// ID returns the VRegID of this VReg.
 52func (v VReg) ID() VRegID {
 53	return VRegID(v & 0xffffffff)
 54}
 55
 56// Valid returns true if this VReg is Valid.
 57func (v VReg) Valid() bool {
 58	return v.ID() != vRegIDInvalid && v.RegType() != RegTypeInvalid
 59}
 60
 61// RealReg represents a physical register.
 62type RealReg byte
 63
 64const RealRegInvalid RealReg = 0
 65
 66const (
 67	vRegIDInvalid            VRegID = 1 << 31
 68	VRegIDNonReservedBegin          = vRegIDReservedForRealNum
 69	vRegIDReservedForRealNum VRegID = 128
 70	VRegInvalid                     = VReg(vRegIDInvalid)
 71)
 72
 73// String implements fmt.Stringer.
 74func (r RealReg) String() string {
 75	switch r {
 76	case RealRegInvalid:
 77		return "invalid"
 78	default:
 79		return fmt.Sprintf("r%d", r)
 80	}
 81}
 82
 83// String implements fmt.Stringer.
 84func (v VReg) String() string {
 85	if v.IsRealReg() {
 86		return fmt.Sprintf("r%d", v.ID())
 87	}
 88	return fmt.Sprintf("v%d?", v.ID())
 89}
 90
 91// RegType represents the type of a register.
 92type RegType byte
 93
 94const (
 95	RegTypeInvalid RegType = iota
 96	RegTypeInt
 97	RegTypeFloat
 98	NumRegType
 99)
100
101// String implements fmt.Stringer.
102func (r RegType) String() string {
103	switch r {
104	case RegTypeInt:
105		return "int"
106	case RegTypeFloat:
107		return "float"
108	default:
109		return "invalid"
110	}
111}
112
113// RegTypeOf returns the RegType of the given ssa.Type.
114func RegTypeOf(p ssa.Type) RegType {
115	switch p {
116	case ssa.TypeI32, ssa.TypeI64:
117		return RegTypeInt
118	case ssa.TypeF32, ssa.TypeF64, ssa.TypeV128:
119		return RegTypeFloat
120	default:
121		panic("invalid type")
122	}
123}