diff options
Diffstat (limited to 'src/cmd/gc/bv.c')
-rw-r--r-- | src/cmd/gc/bv.c | 134 |
1 files changed, 120 insertions, 14 deletions
diff --git a/src/cmd/gc/bv.c b/src/cmd/gc/bv.c index 92834a97b..2efbbc565 100644 --- a/src/cmd/gc/bv.c +++ b/src/cmd/gc/bv.c @@ -11,12 +11,24 @@ enum { WORDBITS = 32, }; -uintptr +static uintptr bvsize(uintptr n) { return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE; } +int32 +bvbits(Bvec *bv) +{ + return bv->n; +} + +int32 +bvwords(Bvec *bv) +{ + return (bv->n + WORDBITS - 1) / WORDBITS; +} + Bvec* bvalloc(int32 n) { @@ -34,26 +46,49 @@ bvalloc(int32 n) return bv; } +/* difference */ void -bvset(Bvec *bv, int32 i) +bvandnot(Bvec *dst, Bvec *src1, Bvec *src2) { - uint32 mask; + int32 i, w; - if(i < 0 || i >= bv->n) - fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n); - mask = 1U << (i % WORDBITS); - bv->b[i / WORDBITS] |= mask; + if(dst->n != src1->n || dst->n != src2->n) + fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); + for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) + dst->b[w] = src1->b[w] & ~src2->b[w]; +} + +int +bvcmp(Bvec *bv1, Bvec *bv2) +{ + uintptr nbytes; + + if(bv1->n != bv2->n) + fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n); + nbytes = bvsize(bv1->n); + return memcmp(bv1->b, bv2->b, nbytes); } void -bvres(Bvec *bv, int32 i) +bvcopy(Bvec *dst, Bvec *src) { - uint32 mask; + memmove(dst->b, src->b, bvsize(dst->n)); +} - if(i < 0 || i >= bv->n) - fatal("bvres: index %d is out of bounds with length %d\n", i, bv->n); - mask = ~(1 << (i % WORDBITS)); - bv->b[i / WORDBITS] &= mask; +Bvec* +bvconcat(Bvec *src1, Bvec *src2) +{ + Bvec *dst; + int32 i; + + dst = bvalloc(src1->n + src2->n); + for(i = 0; i < src1->n; i++) + if(bvget(src1, i)) + bvset(dst, i); + for(i = 0; i < src2->n; i++) + if(bvget(src2, i)) + bvset(dst, i + src1->n); + return dst; } int @@ -63,7 +98,7 @@ bvget(Bvec *bv, int32 i) if(i < 0 || i >= bv->n) fatal("bvget: index %d is out of bounds with length %d\n", i, bv->n); - mask = 1 << (i % WORDBITS); + mask = 1U << (i % WORDBITS); word = bv->b[i / WORDBITS] & mask; return word ? 1 : 0; } @@ -78,3 +113,74 @@ bvisempty(Bvec *bv) return 0; return 1; } + +void +bvnot(Bvec *bv) +{ + int32 i, w; + + for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++) + bv->b[w] = ~bv->b[w]; +} + +/* union */ +void +bvor(Bvec *dst, Bvec *src1, Bvec *src2) +{ + int32 i, w; + + if(dst->n != src1->n || dst->n != src2->n) + fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); + for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) + dst->b[w] = src1->b[w] | src2->b[w]; +} + +/* intersection */ +void +bvand(Bvec *dst, Bvec *src1, Bvec *src2) +{ + int32 i, w; + + if(dst->n != src1->n || dst->n != src2->n) + fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n); + for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++) + dst->b[w] = src1->b[w] & src2->b[w]; +} + +void +bvprint(Bvec *bv) +{ + int32 i; + + print("#*"); + for(i = 0; i < bv->n; i++) + print("%d", bvget(bv, i)); +} + +void +bvreset(Bvec *bv, int32 i) +{ + uint32 mask; + + if(i < 0 || i >= bv->n) + fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n); + mask = ~(1 << (i % WORDBITS)); + bv->b[i / WORDBITS] &= mask; +} + +void +bvresetall(Bvec *bv) +{ + memset(bv->b, 0x00, bvsize(bv->n)); +} + +void +bvset(Bvec *bv, int32 i) +{ + uint32 mask; + + if(i < 0 || i >= bv->n) + fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n); + mask = 1U << (i % WORDBITS); + bv->b[i / WORDBITS] |= mask; +} |