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}