commit beda73643f21cc768f4f56e8ee205b704a019d6a
parent 649fb739fd994272df44891b785c417607eb62fb
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Thu, 25 Feb 2016 14:38:40 -0500
add some bitset functions
Diffstat:
| M | lisc/lisc.h | | | 1 | + |
| M | lisc/util.c | | | 106 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -9,6 +9,7 @@ typedef unsigned short ushort;
typedef unsigned long ulong;
typedef struct Bits Bits;
+typedef struct Bitset BSet;
typedef struct Ref Ref;
typedef struct OpDesc OpDesc;
typedef struct Ins Ins;
diff --git a/lisc/util.c b/lisc/util.c
@@ -1,7 +1,13 @@
#include "lisc.h"
+typedef struct Bitset Bitset;
typedef struct Vec Vec;
+struct Bitset {
+ uint nchunk;
+ ulong *chunk;
+};
+
struct Vec {
ulong mag;
size_t esz;
@@ -13,7 +19,6 @@ struct Vec {
} align[];
};
-
enum {
VMin = 2,
VMag = 0xcabba9e,
@@ -234,3 +239,102 @@ addcon(Con *c0, Con *c1)
c0->bits.i += c1->bits.i;
}
}
+
+void
+bsinit(BSet *bs, uint n)
+{
+ n = (n + NBit-1) / NBit;
+ bs->nchunk = n;
+ bs->chunk = alloc(n * sizeof bs->chunk[0]);
+}
+
+void
+bszero(BSet *bs)
+{
+ uint n;
+
+ for (n=0; n<bs->nchunk; n++)
+ bs->chunk[n] = 0;
+}
+
+uint
+bscount(BSet *bs)
+{
+ uint i, j, n;
+
+ n = 0;
+ for (i=0; i<bs->nchunk; i++)
+ for (j=0; j<NBit; j++)
+ if (bs->chunk[i] & BIT(j))
+ n++;
+ return n;
+}
+
+static inline uint
+bsmax(BSet *bs)
+{
+ return bs->nchunk * NBit;
+}
+
+int
+bshas(BSet *bs, uint elt)
+{
+ assert(elt < bsmax(bs));
+ return (bs->chunk[elt/NBit] & BIT(elt%NBit)) != 0;
+}
+
+void
+bsset(BSet *bs, uint elt)
+{
+ assert(elt < bsmax(bs));
+ bs->chunk[elt/NBit] |= BIT(elt%NBit);
+}
+
+void
+bsclr(BSet *bs, uint elt)
+{
+ assert(elt < bsmax(bs));
+ bs->chunk[elt/NBit] &= ~BIT(elt%NBit);
+}
+
+void
+bsunion(BSet *a, BSet *b)
+{
+ uint i;
+
+ assert(a->nchunk == b->nchunk);
+ for (i=0; i<a->nchunk; i++)
+ a->chunk[i] |= b->chunk[i];
+}
+
+void
+bsinter(BSet *a, BSet *b)
+{
+ uint i;
+
+ assert(a->nchunk == b->nchunk);
+ for (i=0; i<a->nchunk; i++)
+ a->chunk[i] &= b->chunk[i];
+}
+
+/* Iterates on a bitset, use as follows.
+ *
+ * for (i=0; bsiter(set, &i); i++)
+ * use(i);
+ *
+ */
+int
+bsiter(BSet *bs, uint *elt)
+{
+ uint i;
+
+ for (i = *elt; i < bsmax(bs); i++) {
+ while (i < bsmax(bs) && !bs->chunk[i/NBit])
+ i = (i + NBit) & -NBit;
+ if (bshas(bs, i)) {
+ *elt = i;
+ return 1;
+ }
+ }
+ return 0;
+}