github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/engine/wazevo/backend/regalloc/reg.go (about) 1 package regalloc 2 3 import ( 4 "fmt" 5 6 "github.com/bananabytelabs/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. 11 type VReg uint64 12 13 // VRegID is the lower 32bit of VReg, which is the pure identifier of VReg without RealReg info. 14 type VRegID uint32 15 16 // RealReg returns the RealReg of this VReg. 17 func (v VReg) RealReg() RealReg { 18 return RealReg(v >> 32) 19 } 20 21 // IsRealReg returns true if this VReg is backed by a physical register. 22 func (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. 28 func 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. 37 func (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. 42 func (v VReg) RegType() RegType { 43 return RegType(v >> 40) 44 } 45 46 // SetRegType sets the RegType of this VReg and returns the updated VReg. 47 func (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. 52 func (v VReg) ID() VRegID { 53 return VRegID(v & 0xffffffff) 54 } 55 56 // Valid returns true if this VReg is Valid. 57 func (v VReg) Valid() bool { 58 return v.ID() != vRegIDInvalid && v.RegType() != RegTypeInvalid 59 } 60 61 // RealReg represents a physical register. 62 type RealReg byte 63 64 const RealRegInvalid RealReg = 0 65 66 const ( 67 vRegIDInvalid VRegID = 1 << 31 68 VRegIDNonReservedBegin = vRegIDReservedForRealNum 69 vRegIDReservedForRealNum VRegID = 128 70 VRegInvalid = VReg(vRegIDInvalid) 71 ) 72 73 // String implements fmt.Stringer. 74 func (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. 84 func (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. 92 type RegType byte 93 94 const ( 95 RegTypeInvalid RegType = iota 96 RegTypeInt 97 RegTypeFloat 98 NumRegType 99 ) 100 101 // String implements fmt.Stringer. 102 func (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. 114 func 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 } 124 125 const RealRegsNumMax = 128