1
2
3
4
5 package bitvec
6
7 import (
8 "math/bits"
9
10 "cmd/compile/internal/base"
11 "cmd/internal/src"
12 )
13
14 const (
15 wordBits = 32
16 wordMask = wordBits - 1
17 wordShift = 5
18 )
19
20
21 type BitVec struct {
22 N int32
23 B []uint32
24 }
25
26 func New(n int32) BitVec {
27 nword := (n + wordBits - 1) / wordBits
28 return BitVec{n, make([]uint32, nword)}
29 }
30
31 type Bulk struct {
32 words []uint32
33 nbit int32
34 nword int32
35 }
36
37 func NewBulk(nbit int32, count int32, pos src.XPos) Bulk {
38 nword := (nbit + wordBits - 1) / wordBits
39 size := int64(nword) * int64(count)
40 if int64(int32(size*4)) != size*4 {
41 base.FatalfAt(pos, "NewBulk too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
42 }
43 return Bulk{
44 words: make([]uint32, size),
45 nbit: nbit,
46 nword: nword,
47 }
48 }
49
50 func (b *Bulk) Next() BitVec {
51 out := BitVec{b.nbit, b.words[:b.nword]}
52 b.words = b.words[b.nword:]
53 return out
54 }
55
56 func (bv1 BitVec) Eq(bv2 BitVec) bool {
57 if bv1.N != bv2.N {
58 base.Fatalf("bvequal: lengths %d and %d are not equal", bv1.N, bv2.N)
59 }
60 for i, x := range bv1.B {
61 if x != bv2.B[i] {
62 return false
63 }
64 }
65 return true
66 }
67
68 func (dst BitVec) Copy(src BitVec) {
69 copy(dst.B, src.B)
70 }
71
72 func (bv BitVec) Get(i int32) bool {
73 if i < 0 || i >= bv.N {
74 base.Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.N)
75 }
76 mask := uint32(1 << uint(i%wordBits))
77 return bv.B[i>>wordShift]&mask != 0
78 }
79
80 func (bv BitVec) Set(i int32) {
81 if i < 0 || i >= bv.N {
82 base.Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.N)
83 }
84 mask := uint32(1 << uint(i%wordBits))
85 bv.B[i/wordBits] |= mask
86 }
87
88 func (bv BitVec) Unset(i int32) {
89 if i < 0 || i >= bv.N {
90 base.Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.N)
91 }
92 mask := uint32(1 << uint(i%wordBits))
93 bv.B[i/wordBits] &^= mask
94 }
95
96
97
98 func (bv BitVec) Next(i int32) int32 {
99 if i >= bv.N {
100 return -1
101 }
102
103
104 if bv.B[i>>wordShift]>>uint(i&wordMask) == 0 {
105 i &^= wordMask
106 i += wordBits
107 for i < bv.N && bv.B[i>>wordShift] == 0 {
108 i += wordBits
109 }
110 }
111
112 if i >= bv.N {
113 return -1
114 }
115
116
117 w := bv.B[i>>wordShift] >> uint(i&wordMask)
118 i += int32(bits.TrailingZeros32(w))
119
120 return i
121 }
122
123 func (bv BitVec) IsEmpty() bool {
124 for _, x := range bv.B {
125 if x != 0 {
126 return false
127 }
128 }
129 return true
130 }
131
132 func (bv BitVec) Count() int {
133 n := 0
134 for _, x := range bv.B {
135 n += bits.OnesCount32(x)
136 }
137 return n
138 }
139
140 func (bv BitVec) Not() {
141 for i, x := range bv.B {
142 bv.B[i] = ^x
143 }
144 if bv.N%wordBits != 0 {
145 bv.B[len(bv.B)-1] &= 1<<uint(bv.N%wordBits) - 1
146 }
147 }
148
149
150 func (dst BitVec) Or(src1, src2 BitVec) {
151 if len(src1.B) == 0 {
152 return
153 }
154 _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1]
155
156 for i, x := range src1.B {
157 dst.B[i] = x | src2.B[i]
158 }
159 }
160
161
162 func (dst BitVec) And(src1, src2 BitVec) {
163 if len(src1.B) == 0 {
164 return
165 }
166 _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1]
167
168 for i, x := range src1.B {
169 dst.B[i] = x & src2.B[i]
170 }
171 }
172
173
174 func (dst BitVec) AndNot(src1, src2 BitVec) {
175 if len(src1.B) == 0 {
176 return
177 }
178 _, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1]
179
180 for i, x := range src1.B {
181 dst.B[i] = x &^ src2.B[i]
182 }
183 }
184
185 func (bv BitVec) String() string {
186 s := make([]byte, 2+bv.N)
187 copy(s, "#*")
188 for i := int32(0); i < bv.N; i++ {
189 ch := byte('0')
190 if bv.Get(i) {
191 ch = '1'
192 }
193 s[2+i] = ch
194 }
195 return string(s)
196 }
197
198 func (bv BitVec) Clear() {
199 for i := range bv.B {
200 bv.B[i] = 0
201 }
202 }
203
View as plain text