github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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 }; 13 14 static uintptr 15 bvsize(uintptr n) 16 { 17 return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE; 18 } 19 20 int32 21 bvbits(Bvec *bv) 22 { 23 return bv->n; 24 } 25 26 int32 27 bvwords(Bvec *bv) 28 { 29 return (bv->n + WORDBITS - 1) / WORDBITS; 30 } 31 32 Bvec* 33 bvalloc(int32 n) 34 { 35 Bvec *bv; 36 uintptr nbytes; 37 38 if(n < 0) 39 fatal("bvalloc: initial size is negative\n"); 40 nbytes = sizeof(Bvec) + bvsize(n); 41 bv = malloc(nbytes); 42 if(bv == nil) 43 fatal("bvalloc: malloc failed\n"); 44 memset(bv, 0, nbytes); 45 bv->n = n; 46 return bv; 47 } 48 49 /* difference */ 50 void 51 bvandnot(Bvec *dst, Bvec *src1, Bvec *src2) 52 { 53 int32 i, w; 54 55 if(dst->n != src1->n || dst->n != src2->n) 56 fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 57 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 58 dst->b[w] = src1->b[w] & ~src2->b[w]; 59 } 60 61 int 62 bvcmp(Bvec *bv1, Bvec *bv2) 63 { 64 uintptr nbytes; 65 66 if(bv1->n != bv2->n) 67 fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n); 68 nbytes = bvsize(bv1->n); 69 return memcmp(bv1->b, bv2->b, nbytes); 70 } 71 72 void 73 bvcopy(Bvec *dst, Bvec *src) 74 { 75 memmove(dst->b, src->b, bvsize(dst->n)); 76 } 77 78 Bvec* 79 bvconcat(Bvec *src1, Bvec *src2) 80 { 81 Bvec *dst; 82 int32 i; 83 84 dst = bvalloc(src1->n + src2->n); 85 for(i = 0; i < src1->n; i++) 86 if(bvget(src1, i)) 87 bvset(dst, i); 88 for(i = 0; i < src2->n; i++) 89 if(bvget(src2, i)) 90 bvset(dst, i + src1->n); 91 return dst; 92 } 93 94 int 95 bvget(Bvec *bv, int32 i) 96 { 97 uint32 mask, word; 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 mask = 1U << (i % WORDBITS); 102 word = bv->b[i / WORDBITS] & mask; 103 return word ? 1 : 0; 104 } 105 106 int 107 bvisempty(Bvec *bv) 108 { 109 int32 i; 110 111 for(i = 0; i < bv->n; i += WORDBITS) 112 if(bv->b[i / WORDBITS] != 0) 113 return 0; 114 return 1; 115 } 116 117 void 118 bvnot(Bvec *bv) 119 { 120 int32 i, w; 121 122 for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++) 123 bv->b[w] = ~bv->b[w]; 124 } 125 126 /* union */ 127 void 128 bvor(Bvec *dst, Bvec *src1, Bvec *src2) 129 { 130 int32 i, w; 131 132 if(dst->n != src1->n || dst->n != src2->n) 133 fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 134 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 135 dst->b[w] = src1->b[w] | src2->b[w]; 136 } 137 138 /* intersection */ 139 void 140 bvand(Bvec *dst, Bvec *src1, Bvec *src2) 141 { 142 int32 i, w; 143 144 if(dst->n != src1->n || dst->n != src2->n) 145 fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); 146 for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) 147 dst->b[w] = src1->b[w] & src2->b[w]; 148 } 149 150 void 151 bvprint(Bvec *bv) 152 { 153 int32 i; 154 155 print("#*"); 156 for(i = 0; i < bv->n; i++) 157 print("%d", bvget(bv, i)); 158 } 159 160 void 161 bvreset(Bvec *bv, int32 i) 162 { 163 uint32 mask; 164 165 if(i < 0 || i >= bv->n) 166 fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n); 167 mask = ~(1 << (i % WORDBITS)); 168 bv->b[i / WORDBITS] &= mask; 169 } 170 171 void 172 bvresetall(Bvec *bv) 173 { 174 memset(bv->b, 0x00, bvsize(bv->n)); 175 } 176 177 void 178 bvset(Bvec *bv, int32 i) 179 { 180 uint32 mask; 181 182 if(i < 0 || i >= bv->n) 183 fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n); 184 mask = 1U << (i % WORDBITS); 185 bv->b[i / WORDBITS] |= mask; 186 }