1
2
3
4
5 package ssaop
6
7 import (
8 "fmt"
9 "math/bits"
10 )
11
12
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
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