github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/gc/bv.c (about) 1 // Copyright 2013 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 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 enum { 10 WORDSIZE = sizeof(uint32), 11 WORDBITS = 32, 12 WORDMASK = WORDBITS - 1, 13 WORDSHIFT = 5, 14 }; 15 16 static uintptr 17 bvsize(uintptr n) 18 { 19 return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE; 20 } 21 22 int32 23 bvbits(Bvec *bv) 24 { 25 return bv->n; 26 } 27 28 int32 29 bvwords(Bvec *bv) 30 { 31 return (bv->n + WORDBITS - 1) / WORDBITS; 32 } 33 34 Bvec* 35 bvalloc(int32 n) 36 { 37 Bvec *bv; 38 uintptr nbytes; 39 40 if(n < 0) 41 fatal("bvalloc: initial size is negative\n"); 42 nbytes = sizeof(Bvec) + bvsize(n); 43 bv = malloc(nbytes); 44 if(bv == nil) 45 fatal("bvalloc: malloc failed\n"); 46 memset(bv, 0, nbytes); 47 bv->n = n; 48 return bv; 49 } 50 51 /* difference */ 52 void 53 bvandnot(Bvec *dst, Bvec *src1, Bvec *src2) 54 { 55 int32 i, w; 56 57 if(dst->n != src1->n || dst->n != src2->n) 58 fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 59 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 60 dst->b[w] = src1->b[w] & ~src2->b[w]; 61 } 62 63 int 64 bvcmp(Bvec *bv1, Bvec *bv2) 65 { 66 uintptr nbytes; 67 68 if(bv1->n != bv2->n) 69 fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n); 70 nbytes = bvsize(bv1->n); 71 return memcmp(bv1->b, bv2->b, nbytes); 72 } 73 74 void 75 bvcopy(Bvec *dst, Bvec *src) 76 { 77 memmove(dst->b, src->b, bvsize(dst->n)); 78 } 79 80 Bvec* 81 bvconcat(Bvec *src1, Bvec *src2) 82 { 83 Bvec *dst; 84 int32 i; 85 86 dst = bvalloc(src1->n + src2->n); 87 for(i = 0; i < src1->n; i++) 88 if(bvget(src1, i)) 89 bvset(dst, i); 90 for(i = 0; i < src2->n; i++) 91 if(bvget(src2, i)) 92 bvset(dst, i + src1->n); 93 return dst; 94 } 95 96 int 97 bvget(Bvec *bv, int32 i) 98 { 99 if(i < 0 || i >= bv->n) 100 fatal("bvget: index %d is out of bounds with length %d\n", i, bv->n); 101 return (bv->b[i>>WORDSHIFT] >> (i&WORDMASK)) & 1; 102 } 103 104 // bvnext returns the smallest index >= i for which bvget(bv, i) == 1. 105 // If there is no such index, bvnext returns -1. 106 int 107 bvnext(Bvec *bv, int32 i) 108 { 109 uint32 w; 110 111 if(i >= bv->n) 112 return -1; 113 114 // Jump i ahead to next word with bits. 115 if((bv->b[i>>WORDSHIFT]>>(i&WORDMASK)) == 0) { 116 i &= ~WORDMASK; 117 i += WORDBITS; 118 while(i < bv->n && bv->b[i>>WORDSHIFT] == 0) 119 i += WORDBITS; 120 } 121 if(i >= bv->n) 122 return -1; 123 124 // Find 1 bit. 125 w = bv->b[i>>WORDSHIFT]>>(i&WORDMASK); 126 while((w&1) == 0) { 127 w>>=1; 128 i++; 129 } 130 return i; 131 } 132 133 int 134 bvisempty(Bvec *bv) 135 { 136 int32 i; 137 138 for(i = 0; i < bv->n; i += WORDBITS) 139 if(bv->b[i>>WORDSHIFT] != 0) 140 return 0; 141 return 1; 142 } 143 144 void 145 bvnot(Bvec *bv) 146 { 147 int32 i, w; 148 149 for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++) 150 bv->b[w] = ~bv->b[w]; 151 } 152 153 /* union */ 154 void 155 bvor(Bvec *dst, Bvec *src1, Bvec *src2) 156 { 157 int32 i, w; 158 159 if(dst->n != src1->n || dst->n != src2->n) 160 fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 161 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 162 dst->b[w] = src1->b[w] | src2->b[w]; 163 } 164 165 /* intersection */ 166 void 167 bvand(Bvec *dst, Bvec *src1, Bvec *src2) 168 { 169 int32 i, w; 170 171 if(dst->n != src1->n || dst->n != src2->n) 172 fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 173 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 174 dst->b[w] = src1->b[w] & src2->b[w]; 175 } 176 177 void 178 bvprint(Bvec *bv) 179 { 180 int32 i; 181 182 print("#*"); 183 for(i = 0; i < bv->n; i++) 184 print("%d", bvget(bv, i)); 185 } 186 187 void 188 bvreset(Bvec *bv, int32 i) 189 { 190 uint32 mask; 191 192 if(i < 0 || i >= bv->n) 193 fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n); 194 mask = ~(1 << (i % WORDBITS)); 195 bv->b[i / WORDBITS] &= mask; 196 } 197 198 void 199 bvresetall(Bvec *bv) 200 { 201 memset(bv->b, 0x00, bvsize(bv->n)); 202 } 203 204 void 205 bvset(Bvec *bv, int32 i) 206 { 207 uint32 mask; 208 209 if(i < 0 || i >= bv->n) 210 fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n); 211 mask = 1U << (i % WORDBITS); 212 bv->b[i / WORDBITS] |= mask; 213 }