github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/wazevo/backend/regalloc/reg.go (about)

     1  package regalloc
     2  
     3  import (
     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.
    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  }