#include <assert.h>
#include <string.h>
-#include "config.h"
+#include "firm_config.h"
#include "bitfiddle.h"
#include "bitset_std.h"
-/* #if defined(__GNUC__) && defined(__i386__) */
-#if 0
+/*
+#if defined(__GNUC__) && defined(__i386__)
#include "bitset_ia32.h"
#endif
+*/
typedef struct _bitset_t {
unsigned long units;
unsigned long pos, int set)
{
unsigned long unit_number = pos / BS_UNIT_SIZE_BITS;
- unsigned long bit_in_unit = pos & BS_UNIT_MASK;
- unsigned long in_unit_mask = (1 << bit_in_unit) - 1;
- /*
- * Mask out the bits smaller than pos in the current unit.
- * We are only interested in bits set higher than pos.
- */
- unsigned long curr_unit = bs->data[unit_number] & ~in_unit_mask;
-
- /* Find the next bit set in the unit. */
- unsigned long next_in_this_unit
- = _bitset_inside_ntz_value(set ? curr_unit : ~curr_unit);
-
- /* If there is a bit set in the current unit, exit. */
- if(next_in_this_unit < BS_UNIT_SIZE_BITS)
- return next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
-
- /* Else search for set bits in the next units. */
- else {
- unsigned long i;
- for(i = unit_number + 1; i < bs->units; ++i) {
- unsigned long data = bs->data[i];
- unsigned long first_set = _bitset_inside_ntz_value(set ? data : ~data);
- if(first_set < BS_UNIT_SIZE_BITS)
- return first_set + i * BS_UNIT_SIZE_BITS;
+ if(unit_number >= bs->units)
+ return -1;
+
+ {
+ unsigned long bit_in_unit = pos & BS_UNIT_MASK;
+ unsigned long in_unit_mask = (1 << bit_in_unit) - 1;
+
+ /*
+ * Mask out the bits smaller than pos in the current unit.
+ * We are only interested in bits set higher than pos.
+ */
+ unsigned long curr_unit = bs->data[unit_number] & ~in_unit_mask;
+
+ /* Find the next bit set in the unit. */
+ unsigned long next_in_this_unit
+ = _bitset_inside_ntz_value(set ? curr_unit : ~curr_unit);
+
+ /* If there is a bit set in the current unit, exit. */
+ if(next_in_this_unit < BS_UNIT_SIZE_BITS)
+ return next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
+
+ /* Else search for set bits in the next units. */
+ else {
+ unsigned long i;
+ for(i = unit_number + 1; i < bs->units; ++i) {
+ unsigned long data = bs->data[i];
+ unsigned long first_set = _bitset_inside_ntz_value(set ? data : ~data);
+ if(first_set < BS_UNIT_SIZE_BITS)
+ return first_set + i * BS_UNIT_SIZE_BITS;
+ }
}
}
putc(']', file);
}
+static INLINE void bitset_debug_fprint(FILE *file, const bitset_t *bs)
+{
+ int i;
+
+ fprintf(file, "%d:", bs->units);
+ for(i = 0; i < bs->units; ++i)
+ fprintf(file, " %0lx", bs->data[i]);
+}
+
/*
* Here, the binary operations follow.
* And, Or, And Not, Xor are available.
*/
-
#define BINARY_OP(op) \
static INLINE bitset_t *bitset_ ## op(bitset_t *tgt, const bitset_t *src) \
{ \
int n = tgt->units > src->units ? src->units : tgt->units; \
for(i = 0; i < n; i += _BITSET_BINOP_UNITS_INC) \
_bitset_inside_binop_ ## op(&tgt->data[i], &src->data[i]); \
- for(i = n; i < tgt->units; i += _BITSET_BINOP_UNITS_INC) \
- _bitset_inside_binop_with_zero_ ## op(&tgt->data[i]); \
+ if(n < tgt->units) \
+ _bitset_clear_rest(&tgt->data[i], tgt->units - i); \
return tgt; \
}
+/*
+ * Define the clear rest macro for the and, since it is the only case,
+ * were non existed (treated as 0) units in the src must be handled.
+ * For all other operations holds: x Op 0 = x for Op in { Andnot, Or, Xor }
+ *
+ * For and, each bitset implementer has to provide the macro
+ * _bitset_clear_units(data, n), which clears n units from the pointer
+ * data on.
+ */
+#define _bitset_clear_rest(data,n) _bitset_inside_clear_units(data, n)
BINARY_OP(and)
+#undef _bitset_clear_rest
+#define _bitset_clear_rest(data,n)
+
BINARY_OP(andnot)
BINARY_OP(or)
BINARY_OP(xor)