summaryrefslogtreecommitdiff
path: root/src/cmd/gc/bv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/bv.c')
-rw-r--r--src/cmd/gc/bv.c134
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;
+}