Source file src/cmd/compile/internal/ssa/ssaop/regmask.go

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssaop
     6  
     7  import (
     8  	"fmt"
     9  	"math/bits"
    10  )
    11  
    12  // A RegMask encodes a set of machine registers.
    13  type RegMask struct {
    14  	V1, V2 uint64
    15  }
    16  
    17  type Register uint8
    18  
    19  func (r RegMask) Intersect(s RegMask) RegMask {
    20  	return RegMask{r.V1 & s.V1, r.V2 & s.V2}
    21  }
    22  
    23  func (r RegMask) Union(s RegMask) RegMask {
    24  	return RegMask{r.V1 | s.V1, r.V2 | s.V2}
    25  }
    26  
    27  func (r RegMask) Minus(s RegMask) RegMask {
    28  	return RegMask{r.V1 &^ s.V1, r.V2 &^ s.V2}
    29  }
    30  
    31  func (r RegMask) Empty() bool {
    32  	return r.V1 == 0 && r.V2 == 0
    33  }
    34  
    35  func (r RegMask) PickReg() Register {
    36  	if r.Empty() {
    37  		panic("can't pick a register from an empty set")
    38  	}
    39  	// pick the lowest one
    40  	if r.V1 != 0 {
    41  		return Register(bits.TrailingZeros64(r.V1))
    42  	}
    43  	return Register(bits.TrailingZeros64(r.V2) + 64)
    44  }
    45  
    46  func (r RegMask) AddReg(i Register) RegMask {
    47  	if i < 64 {
    48  		return RegMask{r.V1 | 1<<i, r.V2}
    49  	}
    50  	return RegMask{r.V1, r.V2 | 1<<(i-64)}
    51  }
    52  
    53  func (r RegMask) RemoveReg(i Register) RegMask {
    54  	if i < 64 {
    55  		return RegMask{r.V1 &^ (1 << i), r.V2}
    56  	}
    57  	return RegMask{r.V1, r.V2 &^ (1 << (i - 64))}
    58  }
    59  
    60  func (r RegMask) HasReg(i Register) bool {
    61  	if i < 64 {
    62  		return (r.V1>>i)&1 != 0
    63  	}
    64  	return (r.V2>>(i-64))&1 != 0
    65  }
    66  
    67  func (m RegMask) String() string {
    68  	s := ""
    69  	for r := Register(0); !m.Empty(); r++ {
    70  		if !m.HasReg(r) {
    71  			continue
    72  		}
    73  		m = m.RemoveReg(r)
    74  		if s != "" {
    75  			s += " "
    76  		}
    77  		s += fmt.Sprintf("r%d", r)
    78  	}
    79  	return s
    80  }
    81  

View as plain text