typedef struct _bitset_t {
bitset_pos_t units;
bitset_pos_t size;
- bitset_unit_t *data;
} bitset_t;
-#define BS_UNIT_SIZE sizeof(bitset_unit_t)
-#define BS_UNIT_SIZE_BITS (BS_UNIT_SIZE * 8)
-#define BS_UNIT_MASK (BS_UNIT_SIZE_BITS - 1)
+#define BS_UNIT_SIZE sizeof(bitset_unit_t)
+#define BS_UNIT_SIZE_BITS (BS_UNIT_SIZE * 8)
+#define BS_UNIT_MASK (BS_UNIT_SIZE_BITS - 1)
+
+#define BS_DATA(bs) ((bitset_unit_t *) ((char *) (bs) + sizeof(bitset_t)))
+#define BS_UNITS(bits) (round_up2(bits, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS)
+#define BS_TOTAL_SIZE(bits) (sizeof(bitset_t) + BS_UNITS(bits) * BS_UNIT_SIZE)
/**
* Initialize a bitset.
static INLINE bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
{
bitset_t *ptr = area;
- memset(area, 0, _bitset_overall_size(sizeof(bitset_t), size));
- ptr->units = _bitset_units(size);
- ptr->size = size;
- ptr->data = _bitset_data_ptr(area, sizeof(bitset_t), size);
+ memset(area, 0, BS_TOTAL_SIZE(size));
+ ptr->units = BS_UNITS(size);
+ ptr->size = size;
return ptr;
}
{
bitset_pos_t rest = bs->size & BS_UNIT_MASK;
if (rest)
- bs->data[bs->units - 1] &= (1 << rest) - 1;
+ BS_DATA(bs)[bs->units - 1] &= (1 << rest) - 1;
return bs;
}
* @return A pointer to an empty initialized bitset.
*/
#define bitset_obstack_alloc(obst,size) \
- _bitset_prepare(obstack_alloc(obst, _bitset_overall_size(sizeof(bitset_t), size)), size)
+ _bitset_prepare(obstack_alloc(obst, BS_TOTAL_SIZE(size)), size)
/**
* Allocate a bitset via malloc.
* @return A pointer to an empty initialized bitset.
*/
#define bitset_malloc(size) \
- _bitset_prepare(xmalloc(_bitset_overall_size(sizeof(bitset_t), size)), size)
+ _bitset_prepare(xmalloc(BS_TOTAL_SIZE(size)), size)
/**
* Free a bitset allocated with bitset_malloc().
* @return A pointer to an empty initialized bitset.
*/
#define bitset_alloca(size) \
- _bitset_prepare(alloca(_bitset_overall_size(sizeof(bitset_t), size)), size)
+ _bitset_prepare(alloca(BS_TOTAL_SIZE(size)), size)
/**
*/
static INLINE bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
{
- /* assert(bit < bs->units * BS_UNIT_SIZE_BITS && "Bit too large"); */
assert(bit <= bs->size && "Bit to large");
- return bs->data + bit / BS_UNIT_SIZE_BITS;
+ return BS_DATA(bs) + bit / BS_UNIT_SIZE_BITS;
}
/**
{
bitset_pos_t i;
for(i = 0; i < bs->units; i++)
- _bitset_inside_flip_unit(&bs->data[i]);
+ _bitset_inside_flip_unit(&BS_DATA(bs)[i]);
_bitset_mask_highest(bs);
}
bitset_pos_t tu = tgt->units;
bitset_pos_t su = src->units;
bitset_pos_t min_units = tu < su ? tu : su;
- memcpy(tgt->data, src->data, min_units * BS_UNIT_SIZE);
+ memcpy(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE);
if(tu > min_units)
- memset(tgt->data + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
+ memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
return _bitset_mask_highest(tgt);
}
bitset_pos_t i, ofs = 0;
for(i = 0; i < bs->units; ++i) {
- bitset_unit_t *unit = &bs->data[i];
+ bitset_unit_t *unit = &BS_DATA(bs)[i];
bitset_pos_t pos = _bitset_inside_ntz(unit);
if(pos > 0)
return ofs + pos;
bitset_pos_t i, max = 0, ofs = 0;
for(i = 0; i < bs->units; ++i) {
- bitset_unit_t *unit = &bs->data[i];
+ bitset_unit_t *unit = &BS_DATA(bs)[i];
bitset_pos_t pos = _bitset_inside_nlz(unit);
if(pos > 0)
max = ofs + pos;
* Mask out the bits smaller than pos in the current unit.
* We are only interested in bits set higher than pos.
*/
- bitset_unit_t curr_unit = bs->data[unit_number];
+ bitset_unit_t curr_unit = BS_DATA(bs)[unit_number];
/*
* Find the next bit set in the unit.
else {
bitset_pos_t i;
for(i = unit_number + 1; i < bs->units; ++i) {
- bitset_unit_t data = bs->data[i];
+ bitset_unit_t data = BS_DATA(bs)[i];
bitset_pos_t first_set =
_bitset_inside_ntz_value(set ? data : ~data);
bitset_unit_t *unit;
unsigned pop = 0;
- for (i = 0, unit = bs->data; i < bs->units; ++i, ++unit)
+ for (i = 0, unit = BS_DATA(bs); i < bs->units; ++i, ++unit)
pop += _bitset_inside_pop(unit);
return pop;
*/
static INLINE bitset_t *bitset_clear_all(bitset_t *bs)
{
- memset(bs->data, 0, BS_UNIT_SIZE * bs->units);
+ memset(BS_DATA(bs), 0, BS_UNIT_SIZE * bs->units);
return bs;
}
*/
static INLINE bitset_t *bitset_set_all(bitset_t *bs)
{
- memset(bs->data, -1, bs->units * BS_UNIT_SIZE);
+ memset(BS_DATA(bs), -1, bs->units * BS_UNIT_SIZE);
return _bitset_mask_highest(bs);
}
bitset_pos_t i;
for(i = 0; i < n; ++i) {
- bitset_unit_t lu = lhs->data[i];
- bitset_unit_t ru = rhs->data[i];
+ bitset_unit_t lu = BS_DATA(lhs)[i];
+ bitset_unit_t ru = BS_DATA(rhs)[i];
if((lu | ru) & ~ru)
return 0;
*/
if(lhs->units > n) {
for(i = n; i < lhs->units; ++i) {
- if(lhs->data[i] != 0)
+ if(BS_DATA(lhs)[i] != 0)
return 0;
}
}
bitset_pos_t i;
for(i = 0; i < bs->units; ++i) {
- bitset_unit_t unit = bs->data[i];
+ bitset_unit_t unit = BS_DATA(bs)[i];
bitset_unit_t um1 = unit - 1;
- bs->data[i] = um1;
+ BS_DATA(bs)[i] = um1;
if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
break;
bitset_pos_t i;
for (i = 0; i < n; ++i)
- if (a->data[i] & b->data[i])
+ if (BS_DATA(a)[i] & BS_DATA(b)[i])
return 1;
return 0;
{
bitset_pos_t i;
for (i = 0; i < a->units; ++i)
- if (a->data[i] != 0)
+ if (BS_DATA(a)[i] != 0)
return 0;
return 1;
}
fprintf(file, "%u:", bs->units);
for(i = 0; i < bs->units; ++i)
- fprintf(file, " " BITSET_UNIT_FMT, bs->data[i]);
+ fprintf(file, " " BITSET_UNIT_FMT, BS_DATA(bs)[i]);
}
/**
bitset_pos_t i; \
bitset_pos_t 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]); \
+ _bitset_inside_binop_ ## op(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \
if(n < tgt->units) \
- _bitset_clear_rest(&tgt->data[i], tgt->units - i); \
+ _bitset_clear_rest(&BS_DATA(tgt)[i], tgt->units - i); \
return _bitset_mask_highest(tgt); \
}
return res;
}
-#if defined(__GNUC__) && defined(__SSE2__)
-
-#include <stddef.h>
-#include <xmmintrin.h>
-
-#undef _bitset_units
-#undef _bitset_overall_size
-#undef _bitset_data_ptr
-
-#undef _BITSET_BINOP_UNITS_INC
-
-#undef _bitset_inside_binop_and
-#undef _bitset_inside_binop_andnot
-#undef _bitset_inside_binop_or
-#undef _bitset_inside_binop_xor
-
-#define _bitset_units(highest_bit) (round_up2(highest_bit, 128) / BS_UNIT_SIZE_BITS)
-
-#define _bitset_overall_size(bitset_base_size,highest_bit) \
- ((bitset_base_size) + 16 + _bitset_units(highest_bit) * BS_UNIT_SIZE)
-
-#define _bitset_data_ptr(data,bitset_base_size,highest_bit) \
- _bitset_sse_data_ptr(data, bitset_base_size, highest_bit)
-
-static INLINE bitset_unit_t *_bitset_sse_data_ptr(void *data, size_t bitset_base_size,
- bitset_pos_t highest_bit)
-{
- ptrdiff_t diff;
- char *units = data;
-
- diff = (units - (char *) 0) + bitset_base_size;
- diff = round_up2(diff, 16);
- units = (char *) 0 + diff;
- return (bitset_unit_t *) units;
-}
-
-#define _BITSET_BINOP_UNITS_INC 4
-#define _bitset_inside_binop_and(tgt,src) _bitset_sse_inside_binop_and(tgt,src)
-#define _bitset_inside_binop_andnot(tgt,src) _bitset_sse_inside_binop_andnot(tgt,src)
-#define _bitset_inside_binop_or(tgt,src) _bitset_sse_inside_binop_or(tgt,src)
-#define _bitset_inside_binop_xor(tgt,src) _bitset_sse_inside_binop_xor(tgt,src)
-
-#define _BITSET_SSE_BINOP(name) \
-static INLINE void _bitset_sse_inside_binop_ ## name(bitset_unit_t *tgt, bitset_unit_t *src) \
-{ \
- __m128i src_op = _mm_load_si128((__m128i *) src); \
- __m128i tgt_op = _mm_load_si128((__m128i *) tgt); \
- __m128i res = _mm_ ## name ## _si128(tgt_op, src_op); \
- _mm_store_si128((void *) tgt, res); \
-}
-
-
-static INLINE void _bitset_sse_inside_binop_with_zero_and(bitset_unit_t *tgt)
-{
- tgt[0] = 0;
- tgt[1] = 0;
- tgt[2] = 0;
- tgt[3] = 0;
-}
-
-static INLINE void _bitset_sse_inside_binop_andnot(bitset_unit_t *tgt, bitset_unit_t *src)
-{
- __m128i src_op = _mm_load_si128((void *) src);
- __m128i tgt_op = _mm_load_si128((void *) tgt);
- __m128i res = _mm_andnot_si128(src_op, tgt_op);
- _mm_store_si128((__m128i *) tgt, res);
-}
-
-_BITSET_SSE_BINOP(and)
-_BITSET_SSE_BINOP(or)
-_BITSET_SSE_BINOP(xor)
-
-
-#endif
#endif
#define BITSET_UNIT_FMT "%0x"
#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
-/**
- * Units needed for a given highest bit.
- * This implementation always allocates units in a multiple of 16 bytes.
- * @param size The size of the bitset in bits.
- * @return The number of units needed.
- */
-#define _bitset_units(size) (round_up2(size, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS)
-
-/**
- * Compute the size in bytes needed for a bitseti, overall.
- * This also include the size for the bitset data structure.
- * This implementation computes the size in wat, that the bitset units
- * can be aligned to 16 bytes.
- * @param size The size of the bitset in bits.
- * @return The overall amount of bytes needed for that bitset.
- */
-#define _bitset_overall_size(bitset_base_size,size) \
- (bitset_base_size + _bitset_units(size) * BS_UNIT_SIZE)
-
-/**
- * calculate the pointer to the data space of the bitset.
- * @param data The base address of the allocated memory
- * @param bitset_base_size The size of the basical bitset data structure
- * which has to be taken into account.
- * @param size The size of the bitset in bits.
- */
-#define _bitset_data_ptr(data,bitset_base_size,size) \
- ((bitset_unit_t *) ((char *) data + bitset_base_size))
-
-
/**
* Clear some units from a certain address on.
* @param addr The address from where to clear.