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

     1  package regalloc
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  // NewRegSet returns a new RegSet with the given registers.
     9  func NewRegSet(regs ...RealReg) RegSet {
    10  	var ret RegSet
    11  	for _, r := range regs {
    12  		ret = ret.add(r)
    13  	}
    14  	return ret
    15  }
    16  
    17  // RegSet represents a set of registers.
    18  type RegSet uint64
    19  
    20  func (rs RegSet) format(info *RegisterInfo) string { //nolint:unused
    21  	var ret []string
    22  	for i := 0; i < 64; i++ {
    23  		if rs&(1<<uint(i)) != 0 {
    24  			ret = append(ret, info.RealRegName(RealReg(i)))
    25  		}
    26  	}
    27  	return strings.Join(ret, ", ")
    28  }
    29  
    30  func (rs RegSet) has(r RealReg) bool {
    31  	return rs&(1<<uint(r)) != 0
    32  }
    33  
    34  func (rs RegSet) add(r RealReg) RegSet {
    35  	if r >= 64 {
    36  		return rs
    37  	}
    38  	return rs | 1<<uint(r)
    39  }
    40  
    41  func (rs RegSet) Range(f func(allocatedRealReg RealReg)) {
    42  	for i := 0; i < 64; i++ {
    43  		if rs&(1<<uint(i)) != 0 {
    44  			f(RealReg(i))
    45  		}
    46  	}
    47  }
    48  
    49  type regInUseSet struct {
    50  	set RegSet
    51  	vrs [64]VReg
    52  }
    53  
    54  func (rs *regInUseSet) reset() {
    55  	rs.set = 0
    56  	for i := range rs.vrs {
    57  		rs.vrs[i] = VRegInvalid
    58  	}
    59  }
    60  
    61  func (rs *regInUseSet) format(info *RegisterInfo) string { //nolint:unused
    62  	var ret []string
    63  	for i := 0; i < 64; i++ {
    64  		if rs.set&(1<<uint(i)) != 0 {
    65  			vr := rs.vrs[i]
    66  			ret = append(ret, fmt.Sprintf("(%s->v%d)", info.RealRegName(RealReg(i)), vr.ID()))
    67  		}
    68  	}
    69  	return strings.Join(ret, ", ")
    70  }
    71  
    72  func (rs *regInUseSet) has(r RealReg) bool {
    73  	if r >= 64 {
    74  		return false
    75  	}
    76  	return rs.set&(1<<uint(r)) != 0
    77  }
    78  
    79  func (rs *regInUseSet) get(r RealReg) VReg {
    80  	if r >= 64 {
    81  		return VRegInvalid
    82  	}
    83  	return rs.vrs[r]
    84  }
    85  
    86  func (rs *regInUseSet) remove(r RealReg) {
    87  	if r >= 64 {
    88  		return
    89  	}
    90  	rs.set &= ^(1 << uint(r))
    91  	rs.vrs[r] = VRegInvalid
    92  }
    93  
    94  func (rs *regInUseSet) add(r RealReg, vr VReg) {
    95  	if r >= 64 {
    96  		return
    97  	}
    98  	rs.set |= 1 << uint(r)
    99  	rs.vrs[r] = vr
   100  }
   101  
   102  func (rs *regInUseSet) range_(f func(allocatedRealReg RealReg, vr VReg)) {
   103  	for i := 0; i < 64; i++ {
   104  		if rs.set&(1<<uint(i)) != 0 {
   105  			f(RealReg(i), rs.vrs[i])
   106  		}
   107  	}
   108  }