#include <assert.h>
#include <stddef.h>
-#include "firm_config.h"
#include "obst.h"
#include "fourcc.h"
#include "align.h"
* @note The differences to bsearch(3) which does not give proper insert locations
* in the case that the element is not conatined in the array.
*/
-static INLINE __attribute__((const, unused)) int
+static inline __attribute__((const, unused)) int
ir_arr_bsearch(const void *arr, size_t elm_size, ir_arr_cmp_func_t *cmp, const void *elm)
{
int hi = ARR_LEN(arr);
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @date 28.9.2004
- * @brief Functions from hackers delight.
- * @author Sebastian Hack, Matthias Braun
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITFIDDLE_H
-#define FIRM_ADT_BITFIDDLE_H
-
-#include "firm_config.h"
-
-#include <limits.h>
-#include <assert.h>
-#include "compiler.h"
-
-/* some functions here assume ints are 32 bit wide */
-#define HACKDEL_WORDSIZE 32
-COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
-COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
-
-/**
- * Add saturated.
- * @param x Summand 1.
- * @param y Summand 2.
- * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
- *
- * @note See hacker's delight, page 27.
- */
-static INLINE PURE
-int add_saturated(int x, int y)
-{
- int sum = x + y;
- /*
- An overflow occurs, if the sign of the both summands is equal
- and the one of the sum is different from the summand's one.
- The sign bit is 1, if an overflow occurred, 0 otherwise.
- int overflow = ~(x ^ y) & (sum ^ x);
- */
- int overflow = (x ^ sum) & (y ^ sum);
-
- /*
- The infinity to use.
- Make a mask of the sign bit of x and y (they are the same if an
- overflow occurred).
- INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
- INT_MIN.
- */
- int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
-
- return overflow < 0 ? inf : sum;
-}
-
-/**
- * Compute the count of set bits in a 32-bit word.
- * @param x A 32-bit word.
- * @return The number of bits set in x.
- */
-static INLINE PURE
-unsigned popcnt(unsigned x) {
- x -= ((x >> 1) & 0x55555555);
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
- x = (x + (x >> 4)) & 0x0f0f0f0f;
- x += x >> 8;
- x += x >> 16;
- return x & 0x3f;
-}
-
-/**
- * Compute the number of leading zeros in a word.
- * @param x The word.
- * @return The number of leading (from the most significant bit) zeros.
- */
-static INLINE PURE
-unsigned nlz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
- unsigned res;
- if(x == 0)
- return 32;
-
- __asm__("bsrl %1,%0"
- : "=r" (res)
- : "r" (x));
- return 31 - res;
-#else
- unsigned y;
- int n = 32;
-
- y = x >>16; if (y != 0) { n -= 16; x = y; }
- y = x >> 8; if (y != 0) { n -= 8; x = y; }
- y = x >> 4; if (y != 0) { n -= 4; x = y; }
- y = x >> 2; if (y != 0) { n -= 2; x = y; }
- y = x >> 1; if (y != 0) return n - 2;
- return n - x;
-#endif
-}
-
-/**
- * Compute the number of trailing zeros in a word.
- * @param x The word.
- * @return The number of trailing zeros.
- */
-static INLINE PURE
-unsigned ntz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
- unsigned res;
- if(x == 0)
- return 32;
-
- __asm__("bsfl %1,%0"
- : "=r" (res)
- : "r" (x));
- return res;
-#else
- return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
-#endif
-}
-
-/**
- * Compute the greatest power of 2 smaller or equal to a value.
- * This is also known as the binary logarithm.
- * @param x The value.
- * @return The power of two.
- */
-#define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
-
-/**
- * Compute the smallest power of 2 greater or equal to a value.
- * This is also known as the binary logarithm.
- * @param x The value.
- * @return The power of two.
- */
-#define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
-
-/**
- * Round up to the next multiple of a power of two.
- * @param x A value.
- * @param pot A power of two.
- * @return x rounded up to the next multiple of pot.
- */
-#define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
-
-/**
- * Returns the biggest power of 2 that is equal or smaller than @p x
- * (see hackers delight power-of-2 boundaries, page 48)
- */
-static INLINE PURE
-unsigned floor_po2(unsigned x)
-{
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
- if(x == 0)
- return 0;
- // note that x != 0 here, so nlz(x) < 32!
- return 0x80000000U >> nlz(x);
-#else
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x - (x >> 1);
-#endif
-}
-
-/**
- * Returns the smallest power of 2 that is equal or greater than x
- * @remark x has to be <= 0x8000000 of course
- * @note see hackers delight power-of-2 boundaries, page 48
- */
-static INLINE PURE
-unsigned ceil_po2(unsigned x)
-{
- if(x == 0)
- return 0;
- assert(x < (1U << 31));
-
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
- // note that x != 0 here!
- return 0x80000000U >> (nlz(x-1) - 1);
-#else
- x = x - 1;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x + 1;
-#endif
-}
-
-/**
- * Tests whether @p x is a power of 2
- */
-static INLINE PURE
-int is_po2(unsigned x)
-{
- return (x & (x-1)) == 0;
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief A bitset implementation.
- * @author Sebastian Hack
- * @date 15.10.2004
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITSET_H
-#define FIRM_ADT_BITSET_H
-
-#include "firm_config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
-#include "xmalloc.h"
-#include "bitfiddle.h"
-
-typedef unsigned int bitset_pos_t;
-
-#include "bitset_std.h"
-
-#if defined(__GNUC__) && defined(__i386__)
-#include "bitset_ia32.h"
-#endif
-
-typedef struct _bitset_t {
- bitset_pos_t units;
- bitset_pos_t size;
-} 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_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.
- * This functions should not be called.
- *
- * Note that this function needs three macros which must be provided by the
- * bitfield implementor:
- * - _bitset_overall_size(size) The overall size that must be
- * allocated for the bitfield in bytes.
- * - _bitset_units(size) The number of units that will be
- * present in the bitfield for a given highest bit.
- * - _bitset_data_ptr(data, size) This produces as pointer to the
- * first unit in the allocated memory area. The main reason for this
- * macro is, that some bitset implementors want control over memory
- * alignment.
- *
- * @param area A pointer to memory reserved for the bitset.
- * @param size The size of the bitset in bits.
- * @return A pointer to the initialized bitset.
- */
-static INLINE bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
-{
- bitset_t *ptr = area;
- memset(ptr, 0, BS_TOTAL_SIZE(size));
- ptr->units = BS_UNITS(size);
- ptr->size = size;
- return ptr;
-}
-
-/**
- * Mask out all bits, which are only there, because the number
- * of bits in the set didn't match a unit size boundary.
- * @param bs The bitset.
- * @return The masked bitset.
- */
-static INLINE bitset_t *_bitset_mask_highest(bitset_t *bs)
-{
- bitset_pos_t rest = bs->size & BS_UNIT_MASK;
- if (rest)
- BS_DATA(bs)[bs->units - 1] &= (1 << rest) - 1;
- return bs;
-}
-
-/**
- * Get the capacity of the bitset in bits.
- * @param bs The bitset.
- * @return The capacity in bits of the bitset.
- */
-#define bitset_capacity(bs) ((bs)->units * BS_UNIT_SIZE_BITS)
-
-/**
- * Get the size of the bitset in bits.
- * @note Note the difference between capacity and size.
- * @param bs The bitset.
- * @return The highest bit which can be set or cleared plus 1.
- */
-#define bitset_size(bs) ((bs)->size)
-
-/**
- * Allocate a bitset on an obstack.
- * @param obst The obstack.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_obstack_alloc(obst,size) \
- _bitset_prepare(obstack_alloc(obst, BS_TOTAL_SIZE(size)), size)
-
-/**
- * Allocate a bitset via malloc.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_malloc(size) \
- _bitset_prepare(xmalloc(BS_TOTAL_SIZE(size)), size)
-
-/**
- * Free a bitset allocated with bitset_malloc().
- * @param bs The bitset.
- */
-#define bitset_free(bs) free(bs)
-
-/**
- * Allocate a bitset on the stack via alloca.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_alloca(size) \
- _bitset_prepare(alloca(BS_TOTAL_SIZE(size)), size)
-
-
-/**
- * Get the unit which contains a specific bit.
- * This function is internal.
- * @param bs The bitset.
- * @param bit The bit.
- * @return A pointer to the unit containing the bit.
- */
-static INLINE bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
-{
- assert(bit <= bs->size && "Bit to large");
- return BS_DATA(bs) + bit / BS_UNIT_SIZE_BITS;
-}
-
-/**
- * Set a bit in the bitset.
- * @param bs The bitset.
- * @param bit The bit to set.
- */
-static INLINE void bitset_set(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_set(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Clear a bit in the bitset.
- * @param bs The bitset.
- * @param bit The bit to clear.
- */
-static INLINE void bitset_clear(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_clear(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Check, if a bit is set.
- * @param bs The bitset.
- * @param bit The bit to check for.
- * @return 1, if the bit was set, 0 if not.
- */
-static INLINE int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- return _bitset_inside_is_set(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Flip a bit in a bitset.
- * @param bs The bitset.
- * @param bit The bit to flip.
- */
-static INLINE void bitset_flip(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_flip(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Flip the whole bitset.
- * @param bs The bitset.
- */
-static INLINE void bitset_flip_all(bitset_t *bs)
-{
- bitset_pos_t i;
- for(i = 0; i < bs->units; i++)
- _bitset_inside_flip_unit(&BS_DATA(bs)[i]);
- _bitset_mask_highest(bs);
-}
-
-/**
- * Copy a bitset to another.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return The target bitset.
- */
-static INLINE bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
-{
- bitset_pos_t tu = tgt->units;
- bitset_pos_t su = src->units;
- bitset_pos_t min_units = tu < su ? tu : su;
- memcpy(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE);
- if(tu > min_units)
- memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
- return _bitset_mask_highest(tgt);
-}
-
-/**
- * Find the next set bit from a given bit.
- * @note Note that if pos is set, pos is returned.
- * @param bs The bitset.
- * @param pos The bit from which to search for the next set bit.
- * @return The next set bit from pos on, or -1, if no set bit was found
- * after pos.
- */
-static INLINE bitset_pos_t _bitset_next(const bitset_t *bs,
- bitset_pos_t pos, int set)
-{
- bitset_pos_t unit_number = pos / BS_UNIT_SIZE_BITS;
- bitset_pos_t res;
-
- if(pos >= bs->size)
- return -1;
-
- {
- bitset_pos_t bit_in_unit = pos & BS_UNIT_MASK;
- bitset_pos_t 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.
- */
- bitset_unit_t curr_unit = BS_DATA(bs)[unit_number];
-
- /*
- * Find the next bit set in the unit.
- * Mind that this function returns 0, if the unit is -1 and
- * counts the bits from 1 on.
- */
- bitset_pos_t next_in_this_unit =
- _bitset_inside_ntz_value((set ? curr_unit : ~curr_unit) & ~in_unit_mask);
-
- /* If there is a bit set in the current unit, exit. */
- if (next_in_this_unit < BS_UNIT_SIZE_BITS) {
- res = next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
- return res < bs->size ? res : (bitset_pos_t) -1;
- }
-
- /* Else search for set bits in the next units. */
- else {
- bitset_pos_t i;
- for(i = unit_number + 1; i < bs->units; ++i) {
- bitset_unit_t data = BS_DATA(bs)[i];
- bitset_pos_t first_set =
- _bitset_inside_ntz_value(set ? data : ~data);
-
- if (first_set < BS_UNIT_SIZE_BITS) {
- res = first_set + i * BS_UNIT_SIZE_BITS;
- return res < bs->size ? res : (bitset_pos_t) -1;
- }
- }
- }
- }
-
- return -1;
-}
-
-#define bitset_next_clear(bs,pos) _bitset_next((bs), (pos), 0)
-#define bitset_next_set(bs,pos) _bitset_next((bs), (pos), 1)
-
-/**
- * Convenience macro for bitset iteration.
- * @param bitset The bitset.
- * @param elm A unsigned long variable.
- */
-#define bitset_foreach(bitset,elm) \
- for(elm = bitset_next_set(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_set(bitset,elm+1))
-
-
-#define bitset_foreach_clear(bitset,elm) \
- for(elm = bitset_next_clear(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_clear(bitset,elm+1))
-
-/**
- * Count the bits set.
- * This can also be seen as the cardinality of the set.
- * @param bs The bitset.
- * @return The number of bits set in the bitset.
- */
-static INLINE unsigned bitset_popcnt(const bitset_t *bs)
-{
- bitset_pos_t i;
- bitset_unit_t *unit;
- unsigned pop = 0;
-
- for (i = 0, unit = BS_DATA(bs); i < bs->units; ++i, ++unit)
- pop += _bitset_inside_pop(unit);
-
- return pop;
-}
-
-/**
- * Clear the bitset.
- * This sets all bits to zero.
- * @param bs The bitset.
- */
-static INLINE bitset_t *bitset_clear_all(bitset_t *bs)
-{
- memset(BS_DATA(bs), 0, BS_UNIT_SIZE * bs->units);
- return bs;
-}
-
-/**
- * Set the bitset.
- * This sets all bits to one.
- * @param bs The bitset.
- */
-static INLINE bitset_t *bitset_set_all(bitset_t *bs)
-{
- memset(BS_DATA(bs), -1, bs->units * BS_UNIT_SIZE);
- return _bitset_mask_highest(bs);
-}
-
-/**
- * Check, if one bitset is contained by another.
- * That is, each bit set in lhs is also set in rhs.
- * @param lhs A bitset.
- * @param rhs Another bitset.
- * @return 1, if all bits in lhs are also set in rhs, 0 otherwise.
- */
-static INLINE int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
-{
- bitset_pos_t n = lhs->units < rhs->units ? lhs->units : rhs->units;
- bitset_pos_t i;
-
- for(i = 0; i < n; ++i) {
- bitset_unit_t lu = BS_DATA(lhs)[i];
- bitset_unit_t ru = BS_DATA(rhs)[i];
-
- if((lu | ru) & ~ru)
- return 0;
- }
-
- /*
- * If the left hand sinde is a larger bitset than rhs,
- * we have to check, that all extra bits in lhs are 0
- */
- if(lhs->units > n) {
- for(i = n; i < lhs->units; ++i) {
- if(BS_DATA(lhs)[i] != 0)
- return 0;
- }
- }
-
- return 1;
-}
-
-/**
- * Treat the bitset as a number and subtract 1.
- * @param bs The bitset.
- * @return The same bitset.
- */
-static INLINE void bitset_minus1(bitset_t *bs)
-{
-#define _SH (sizeof(bitset_unit_t) * 8 - 1)
-
- bitset_pos_t i;
-
- for(i = 0; i < bs->units; ++i) {
- bitset_unit_t unit = BS_DATA(bs)[i];
- bitset_unit_t um1 = unit - 1;
-
- BS_DATA(bs)[i] = um1;
-
- if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
- break;
- }
-#undef _SH
-}
-
-/**
- * Check if two bitsets intersect.
- * @param a The first bitset.
- * @param b The second bitset.
- * @return 1 if they have a bit in common, 0 if not.
- */
-static INLINE int bitset_intersect(const bitset_t *a, const bitset_t *b)
-{
- bitset_pos_t n = a->units < b->units ? a->units : b->units;
- bitset_pos_t i;
-
- for (i = 0; i < n; ++i)
- if (BS_DATA(a)[i] & BS_DATA(b)[i])
- return 1;
-
- return 0;
-}
-
-/**
- * set or clear all bits in the range [from;to[.
- * @param a The bitset.
- * @param from The first index to set to one.
- * @param to The last index plus one to set to one.
- * @param do_set If 1 the bits are set, if 0, they are cleared.
- */
-static INLINE void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t to, int do_set)
-{
- bitset_pos_t from_unit, to_unit, i;
- bitset_unit_t from_unit_mask, to_unit_mask;
-
- if (from == to)
- return;
-
- if (to < from) {
- bitset_pos_t tmp = from;
- from = to;
- to = tmp;
- }
-
- if (to > a->size)
- to = a->size;
-
- /*
- * A small example (for cleaning bits in the same unit).
- * from = 7
- * to = 19
- * do_set = 0
- * result: xxxxxxx000000000000xxxxxxxxxxxxx
- * from_unit_mask: 00000001111111111111111111111111
- * to_unit_mask: 11111111111111111110000000000000
- * scale: 01234567890123456789012345678901
- * 1 2 3
- */
-
- from_unit = from / BS_UNIT_SIZE_BITS;
- from_unit_mask = ~((1 << from) - 1);
- from = from & BS_UNIT_MASK;
-
- to_unit = to / BS_UNIT_SIZE_BITS;
- to_unit_mask = (1 << to) - 1;
- to = to & BS_UNIT_MASK;
-
- /* do we want to set the bits in the range? */
- if (do_set) {
- /* If from and to are in the same unit: */
- if (from_unit == to_unit)
- BS_DATA(a)[from_unit] |= from_unit_mask & to_unit_mask;
-
- /* Else, we have to treat the from and to units seperately */
- else {
- BS_DATA(a)[from_unit] |= from_unit_mask;
- BS_DATA(a)[to_unit] |= to_unit_mask;
- for (i = from_unit + 1; i < to_unit; i++)
- BS_DATA(a)[i] = BITSET_UNIT_ALL_ONE;
- }
- }
-
- /* ... or clear them? */
- else {
- if (from_unit == to_unit)
- BS_DATA(a)[from_unit] &= ~(from_unit_mask & to_unit_mask);
-
- else {
- BS_DATA(a)[from_unit] &= ~from_unit_mask;
- BS_DATA(a)[to_unit] &= ~to_unit_mask;
- for (i = from_unit + 1; i < to_unit; i++)
- BS_DATA(a)[i] = 0;
- }
- }
-}
-
-#define bitset_set_range(bs, from, to) bitset_mod_range((bs), (from), (to), 1)
-#define bitset_clear_range(bs, from, to) bitset_mod_range((bs), (from), (to), 0)
-
-/**
- * Check, if a bitset is empty.
- * @param a The bitset.
- * @return 1, if the bitset is empty, 0 if not.
- */
-static INLINE int bitset_is_empty(const bitset_t *a)
-{
- bitset_pos_t i;
- for (i = 0; i < a->units; ++i)
- if (BS_DATA(a)[i] != 0)
- return 0;
- return 1;
-}
-
-/**
- * Print a bitset to a stream.
- * The bitset is printed as a comma separated list of bits set.
- * @param file The stream.
- * @param bs The bitset.
- */
-static INLINE void bitset_fprint(FILE *file, const bitset_t *bs)
-{
- const char *prefix = "";
- int i;
-
- putc('{', file);
- for(i = bitset_next_set(bs, 0); i != -1; i = bitset_next_set(bs, i + 1)) {
- fprintf(file, "%s%u", prefix, i);
- prefix = ",";
- }
- putc('}', file);
-}
-
-static INLINE void bitset_debug_fprint(FILE *file, const bitset_t *bs)
-{
- bitset_pos_t i;
-
- fprintf(file, "%u:", bs->units);
- for(i = 0; i < bs->units; ++i)
- fprintf(file, " " BITSET_UNIT_FMT, BS_DATA(bs)[i]);
-}
-
-/**
- * Perform tgt = tgt \ src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
-
-/**
- * Perform Union, tgt = tgt u src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_or(bitset_t *tgt, const bitset_t *src);
-
-/**
- * Perform tgt = tgt ^ ~src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_xor(bitset_t *tgt, const bitset_t *src);
-
-/*
- * 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) \
-{ \
- 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(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \
- if(n < tgt->units) \
- _bitset_clear_rest(&BS_DATA(tgt)[i], tgt->units - i); \
- return _bitset_mask_highest(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) do { } while(0)
-
-BINARY_OP(andnot)
-BINARY_OP(or)
-BINARY_OP(xor)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief intel 80x86 implementation of bitsets
- * @version $Id$
- */
-#ifndef _BITSET_IA32_H
-#define _BITSET_IA32_H
-
-#undef _bitset_inside_clear
-#undef _bitset_inside_set
-#undef _bitset_inside_flip
-
-#define _bitset_inside_set(unit, bit) \
- __asm__ __volatile__( "btsl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#define _bitset_inside_clear(unit, bit) \
- __asm__ __volatile__( "btrl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#define _bitset_inside_flip(unit, bit) \
- __asm__ __volatile__( "btcl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#undef _bitset_inside_is_set
-#undef _bitset_inside_nlz
-#undef _bitset_inside_ntz
-#undef _bitset_inside_ntz_value
-
-#define _bitset_inside_is_set(unit, bit) _bitset_ia32_inside_is_set(unit, bit)
-#define _bitset_inside_nlz(unit) _bitset_ia32_inside_nlz(unit)
-#define _bitset_inside_ntz(unit) _bitset_ia32_inside_ntz(unit)
-#define _bitset_inside_ntz_value(unit) _bitset_ia32_inside_ntz_value(unit)
-
-static INLINE int _bitset_ia32_inside_is_set(bitset_unit_t *unit, unsigned bit)
-{
- int res;
- __asm__("bt %2, %1\n\t"
- "rcl $1, %0\n\t"
- "and $1, %0"
- : "=r" (res)
- : "m" (*unit), "Ir" (bit)
- : "cc");
- return res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit)
-{
- unsigned res;
- __asm__("bsr %1, %0\n\t"
- "cmovz %2, %0\n\t"
- "neg %0\n\t"
- "add $31, %0"
- : "=&r" (res)
- : "m" (*unit), "r" (-1)
- : "cc");
- return res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) {
- unsigned res;
- __asm__("bsfl %1, %0\n\t"
- "cmovz %2, %0\n\t"
- : "=&r" (res)
- : "m" (*unit), "r" (32)
- : "cc");
- return res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) {
- unsigned res;
- __asm__("bsfl %1, %0\n\t"
- "cmovz %2, %0\n\t"
- : "=&r" (res)
- : "r" (unit), "r" (32)
- : "cc");
- return res;
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief ANSI-C compliant implementation of bitsets
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITSET_STD_H
-#define FIRM_ADT_BITSET_STD_H
-
-#include "bitfiddle.h"
-
-/** Use ordinary ints as unit types. */
-typedef unsigned int bitset_unit_t;
-
-#define BITSET_UNIT_FMT "%0x"
-#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
-
-/**
- * Clear some units from a certain address on.
- * @param addr The address from where to clear.
- * @param n The number of units to set to 0.
- */
-#define _bitset_inside_clear_units(addr,n) \
- memset(addr, 0, n * BS_UNIT_SIZE)
-
-/**
- * Set a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_set(unit_ptr,bit) (*unit_ptr) |= (1 << (bit))
-
-/**
- * Clear a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_clear(unit_ptr,bit) (*unit_ptr) &= ~(1 << (bit))
-
-/**
- * Flip a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_flip(unit_ptr,bit) (*unit_ptr) ^= (1 << (bit))
-
-/**
- * Flip a whole unit.
- * @param unit_ptr The pointer to the unit.
- */
-#define _bitset_inside_flip_unit(unit_ptr) (*unit_ptr) = ~(*unit_ptr)
-
-/**
- * Count the number of leading zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_nlz(unit_ptr) (nlz(*unit_ptr))
-
-
-/**
- * Count the number of trailing zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz(unit_ptr) _bitset_std_inside_ntz(unit_ptr)
-static INLINE unsigned _bitset_std_inside_ntz(bitset_unit_t *unit_ptr)
-{
- unsigned long data = *unit_ptr;
- return 32 - (unsigned) nlz(~data & (data - 1));
-}
-
-/**
- * Count the number of trailing zeroes in a unit (whereas the unit is no
- * pointer but a value).
- * @param unit A unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz_value(unit) (32 - nlz(~(unit) & ((unit) - 1)))
-
-/**
- * test if a bit is set in a unit.
- * @param unit_ptr The pointer to the unit.
- * @param bit The bit to check.
- * @return 1, if the bit is set, 0 otherise.
- */
-#define _bitset_inside_is_set(unit_ptr,bit) \
- (((*unit_ptr) & (1 << (bit))) != 0)
-
-/**
- * count the number of bits set in a unit.
- * @param unit_ptr The pointer to a unit.
- * @return The number of bits set in the unit.
- */
-#define _bitset_inside_pop(unit_ptr) (popcnt(*unit_ptr))
-
-#define _BITSET_BINOP_UNITS_INC 1
-
-#define _bitset_inside_binop_and(tgt,src) ((*tgt) &= (*src))
-#define _bitset_inside_binop_andnot(tgt,src) ((*tgt) &= ~(*src))
-#define _bitset_inside_binop_or(tgt,src) ((*tgt) |= (*src))
-#define _bitset_inside_binop_xor(tgt,src) ((*tgt) ^= (*src))
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @date 04.06.2007
- * @author Matthias Braun, Sebastian Hack
- * @brief Macros to instruct the compiler compiling libFirm.
- */
-
-#ifndef FIRM_COMPILER_H
-#define FIRM_COMPILER_H
-
-/**
- * Asserts that the constant expression x is not zero at compiletime. name has
- * to be a unique identifier.
- *
- * @note This uses the fact, that double case labels are not allowed.
- */
-#define COMPILETIME_ASSERT(x, name) \
- static __attribute__((unused)) void compiletime_assert_##name (int h) { \
- switch(h) { case 0: case (x): ; } \
- }
-
-#ifdef __GNUC__
-/**
- * Indicates to the compiler that the value of x is very likely 1
- * @note Only use this in speed critical code and when you are sure x is often 1
- */
-#define LIKELY(x) __builtin_expect((x), 1)
-
-/**
- * Indicates to the compiler that it's very likely that x is 0
- * @note Only use this in speed critical code and when you are sure x is often 0
- */
-#define UNLIKELY(x) __builtin_expect((x), 0)
-
-/**
- * Tell the compiler, that a function is pure, i.e. it only
- * uses its parameters and never modifies the "state".
- * Add this macro after the return type.
- */
-#define PURE __attribute__((const))
-
-#else
-#define LIKELY(x) x
-#define UNLIKELY(x) x
-#define PURE
-#endif
-
-#endif
#ifndef FIRM_ADT_HASHPTR_H
#define FIRM_ADT_HASHPTR_H
-#include "firm_config.h"
-#include "compiler.h"
-
#define _FIRM_FNV_OFFSET_BASIS 2166136261U
#define _FIRM_FNV_FNV_PRIME 16777619U
/* Computing x * _FIRM_FNV_FNV_PRIME */
#define _FIRM_FNV_TIMES_PRIME(x) ((x) * _FIRM_FNV_FNV_PRIME)
-static INLINE unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes)
+static inline unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes)
{
unsigned i;
unsigned hash = _FIRM_FNV_OFFSET_BASIS;
return hash;
}
-static INLINE unsigned firm_fnv_hash_str(const char *data)
+static inline unsigned firm_fnv_hash_str(const char *data)
{
unsigned i;
unsigned hash = _FIRM_FNV_OFFSET_BASIS;
#pragma warning(disable:4307)
#endif /* _MSC_VER */
-static INLINE unsigned _hash_combine(unsigned x, unsigned y)
+static inline unsigned _hash_combine(unsigned x, unsigned y)
{
unsigned hash = _FIRM_FNV_TIMES_PRIME(_FIRM_FNV_OFFSET_BASIS);
hash ^= x;
#ifndef FIRM_ADT_LIST_H
#define FIRM_ADT_LIST_H
-#include "firm_config.h"
#include <stdlib.h>
typedef struct list_head list_head;
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-static INLINE void __list_add(struct list_head *new_node,
+static inline void __list_add(struct list_head *new_node,
struct list_head *prev,
struct list_head *next)
{
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
-static INLINE void list_add(struct list_head *new_node, struct list_head *head)
+static inline void list_add(struct list_head *new_node, struct list_head *head)
{
__list_add(new_node, head, head->next);
}
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
-static INLINE void list_add_tail(struct list_head *new_node, struct list_head *head)
+static inline void list_add_tail(struct list_head *new_node, struct list_head *head)
{
__list_add(new_node, head->prev, head);
}
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-static INLINE void __list_del(struct list_head * prev, struct list_head * next)
+static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
* list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
-static INLINE void list_del(struct list_head *entry)
+static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
* list_del_init - deletes entry from list and reinitialize it.
* @param entry the element to delete from the list.
*/
-static INLINE void list_del_init(struct list_head *entry)
+static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
* @param list the entry to move
* @param head the head that will precede our entry
*/
-static INLINE void list_move(struct list_head *list, struct list_head *head)
+static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
* @param list the entry to move
* @param head the head that will follow our entry
*/
-static INLINE void list_move_tail(struct list_head *list,
+static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
* list_empty - tests whether a list is empty
* @param head the list to test.
*/
-static INLINE int list_empty(const struct list_head *head)
+static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
-static INLINE void __list_splice(struct list_head *list,
+static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
* @param list the new list to add.
* @param head the place to add it in the first list.
*/
-static INLINE void list_splice(struct list_head *list, struct list_head *head)
+static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
*
* The list at list is reinitialized
*/
-static INLINE void list_splice_init(struct list_head *list,
+static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
*
* @return the new bitset
*/
-static INLINE unsigned *rbitset_malloc(unsigned size) {
+static inline unsigned *rbitset_malloc(unsigned size) {
unsigned size_bytes = BITSET_SIZE_BYTES(size);
unsigned *res = xmalloc(size_bytes);
memset(res, 0, size_bytes);
*
* @return the new bitset
*/
-static INLINE unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size) {
+static inline unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size) {
unsigned size_bytes = BITSET_SIZE_BYTES(size);
unsigned *res = obstack_alloc(obst, size_bytes);
memset(res, 0, size_bytes);
*
* @return the new bitset
*/
-static INLINE unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size) {
+static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size) {
unsigned size_bytes = BITSET_SIZE_BYTES(size);
unsigned *res = obstack_alloc(obst, size_bytes + sizeof(unsigned));
*res = size;
*
* @return the new bitset
*/
-static INLINE
+static inline
unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
const unsigned *old_bitset,
unsigned size)
/**
* Check if a bitset is empty, ie all bits cleared.
*/
-static INLINE int rbitset_is_empty(unsigned *bitset, unsigned size) {
+static inline int rbitset_is_empty(unsigned *bitset, unsigned size) {
unsigned i, size_bytes = BITSET_SIZE_BYTES(size);
for (i = 0; i < size_bytes; ++i)
if (bitset[i]) return 0;
* @param bitset the bitset
* @param pos the position of the bit to be set
*/
-static INLINE void rbitset_set(unsigned *bitset, unsigned pos) {
+static inline void rbitset_set(unsigned *bitset, unsigned pos) {
BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
}
* @param bitset the bitset
* @param pos the position of the bit to be clear
*/
-static INLINE void rbitset_clear(unsigned *bitset, unsigned pos) {
+static inline void rbitset_clear(unsigned *bitset, unsigned pos) {
BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM));
}
* @param bitset the bitset
* @param size number of bits in the bitset
*/
-static INLINE void rbitset_clear_all(unsigned *bitset, unsigned size) {
+static inline void rbitset_clear_all(unsigned *bitset, unsigned size) {
unsigned size_bytes = BITSET_SIZE_BYTES(size);
memset(bitset, 0, size_bytes);
}
* @param bitset the bitset
* @param pos the position of the bit to check
*/
-static INLINE int rbitset_is_set(const unsigned *bitset, unsigned pos) {
+static inline int rbitset_is_set(const unsigned *bitset, unsigned pos) {
return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
}
*
* @param bitset the bitset
*/
-static INLINE unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) {
+static inline unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) {
unsigned pos;
unsigned n = BITSET_SIZE_ELEMS(size);
unsigned res = 0;
return res;
}
-static INLINE unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set) {
+static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set) {
unsigned p;
unsigned elem_pos = pos / BITS_PER_ELEM;
unsigned bit_pos = pos % BITS_PER_ELEM;
/**
* Inplace Intersection of two sets.
*/
-static INLINE void rbitset_and(unsigned *bitset1, const unsigned *bitset2,
+static inline void rbitset_and(unsigned *bitset1, const unsigned *bitset2,
unsigned size)
{
unsigned i, n = BITSET_SIZE_ELEMS(size);
/**
* Inplace Union of two sets.
*/
-static INLINE void rbitset_or(unsigned *bitset1, const unsigned *bitset2,
+static inline void rbitset_or(unsigned *bitset1, const unsigned *bitset2,
unsigned size)
{
unsigned i, n = BITSET_SIZE_ELEMS(size);
/**
* Remove all bits in bitset2 from bitset 1.
*/
-static INLINE void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2,
+static inline void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2,
unsigned size)
{
unsigned i, n = BITSET_SIZE_ELEMS(size);
/**
* Xor of two bitsets.
*/
-static INLINE void rbitset_xor(unsigned *bitset1, const unsigned *bitset2,
+static inline void rbitset_xor(unsigned *bitset1, const unsigned *bitset2,
unsigned size)
{
unsigned i, n = BITSET_SIZE_ELEMS(size);
}
}
-static INLINE int rbitset_equal(const unsigned *bitset1,
+static inline int rbitset_equal(const unsigned *bitset1,
const unsigned *bitset2, size_t size)
{
unsigned i, n = BITSET_SIZE_ELEMS(size);
*
* @deprecated
*/
-static INLINE void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset) {
+static inline void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset) {
// TODO optimize me (or remove me)
unsigned i, n = bitset_size(bitset);
for(i = 0; i < n; ++i) {
* @param from The first element that should be initialized
* @param to the index of the first element which is not initialized anymore
*/
-static INLINE void uf_init(int* data, int from, int to) {
+static inline void uf_init(int* data, int from, int to) {
int i;
for(i = from; i < to; ++i) {
data[i] = -1;
* @return 0 if the new union set is represented by set1, 1 if it is
* represented by set2
*/
-static INLINE int uf_union(int* data, int set1, int set2) {
+static inline int uf_union(int* data, int set1, int set2) {
int d1 = data[set1];
int d2 = data[set2];
int newcount;
* @param e The element
* @return The representative of the set that contains @p e
*/
-static INLINE int uf_find(int* data, int e) {
+static inline int uf_find(int* data, int e) {
/* go through list to find representative */
int repr = e;
while(data[repr] >= 0) {
#ifndef FIRM_ADT_UTIL_H
#define FIRM_ADT_UTIL_H
-#include "firm_config.h"
-
/**
* Get the offset of a member of a struct.
* @param type The type of the struct member is in.
#ifndef FIRM_IR_IRCGCONS_H
#define FIRM_IR_IRCGCONS_H
-#include "firm_config.h"
-
#ifdef INTERPROCEDURAL_VIEW
#include "firm_types.h"
#include <stddef.h>
-#include "firm_config.h"
#include "firm_types.h"
#include "irop.h"
#include "iropt.h"
#ifndef FIRM_IR_IRHOOKS_H
#define FIRM_IR_IRHOOKS_H
-#include "firm_config.h"
#include "irop.h"
#include "irnode.h"
#include "irgraph.h"
#ifndef FIRM_IR_IRPRINTF_H
#define FIRM_IR_IRPRINTF_H
-#include "firm_config.h"
-
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @date 28.9.2004
+ * @brief Functions from hackers delight.
+ * @author Sebastian Hack, Matthias Braun
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITFIDDLE_H
+#define FIRM_ADT_BITFIDDLE_H
+
+#include "compiler.h"
+
+#include <limits.h>
+#include <assert.h>
+
+/* some functions here assume ints are 32 bit wide */
+#define HACKDEL_WORDSIZE 32
+COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
+COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
+
+/**
+ * Add saturated.
+ * @param x Summand 1.
+ * @param y Summand 2.
+ * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
+ *
+ * @note See hacker's delight, page 27.
+ */
+static inline
+int add_saturated(int x, int y)
+{
+ int sum = x + y;
+ /*
+ An overflow occurs, if the sign of the both summands is equal
+ and the one of the sum is different from the summand's one.
+ The sign bit is 1, if an overflow occurred, 0 otherwise.
+ int overflow = ~(x ^ y) & (sum ^ x);
+ */
+ int overflow = (x ^ sum) & (y ^ sum);
+
+ /*
+ The infinity to use.
+ Make a mask of the sign bit of x and y (they are the same if an
+ overflow occurred).
+ INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
+ INT_MIN.
+ */
+ int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
+
+ return overflow < 0 ? inf : sum;
+}
+
+/**
+ * Compute the count of set bits in a 32-bit word.
+ * @param x A 32-bit word.
+ * @return The number of bits set in x.
+ */
+static inline
+unsigned popcnt(unsigned x) {
+ x -= ((x >> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ x = (x + (x >> 4)) & 0x0f0f0f0f;
+ x += x >> 8;
+ x += x >> 16;
+ return x & 0x3f;
+}
+
+/**
+ * Compute the number of leading zeros in a word.
+ * @param x The word.
+ * @return The number of leading (from the most significant bit) zeros.
+ */
+static inline
+unsigned nlz(unsigned x) {
+#ifdef USE_X86_ASSEMBLY
+ unsigned res;
+ if(x == 0)
+ return 32;
+
+ __asm__("bsrl %1,%0"
+ : "=r" (res)
+ : "r" (x));
+ return 31 - res;
+#else
+ unsigned y;
+ int n = 32;
+
+ y = x >>16; if (y != 0) { n -= 16; x = y; }
+ y = x >> 8; if (y != 0) { n -= 8; x = y; }
+ y = x >> 4; if (y != 0) { n -= 4; x = y; }
+ y = x >> 2; if (y != 0) { n -= 2; x = y; }
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+#endif
+}
+
+/**
+ * Compute the number of trailing zeros in a word.
+ * @param x The word.
+ * @return The number of trailing zeros.
+ */
+static inline
+unsigned ntz(unsigned x) {
+#ifdef USE_X86_ASSEMBLY
+ unsigned res;
+ if(x == 0)
+ return 32;
+
+ __asm__("bsfl %1,%0"
+ : "=r" (res)
+ : "r" (x));
+ return res;
+#else
+ return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
+#endif
+}
+
+/**
+ * Compute the greatest power of 2 smaller or equal to a value.
+ * This is also known as the binary logarithm.
+ * @param x The value.
+ * @return The power of two.
+ */
+#define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
+
+/**
+ * Compute the smallest power of 2 greater or equal to a value.
+ * This is also known as the binary logarithm.
+ * @param x The value.
+ * @return The power of two.
+ */
+#define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
+
+/**
+ * Round up to the next multiple of a power of two.
+ * @param x A value.
+ * @param pot A power of two.
+ * @return x rounded up to the next multiple of pot.
+ */
+#define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
+
+/**
+ * Returns the biggest power of 2 that is equal or smaller than @p x
+ * (see hackers delight power-of-2 boundaries, page 48)
+ */
+static inline
+unsigned floor_po2(unsigned x)
+{
+#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+ if(x == 0)
+ return 0;
+ // note that x != 0 here, so nlz(x) < 32!
+ return 0x80000000U >> nlz(x);
+#else
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x - (x >> 1);
+#endif
+}
+
+/**
+ * Returns the smallest power of 2 that is equal or greater than x
+ * @remark x has to be <= 0x8000000 of course
+ * @note see hackers delight power-of-2 boundaries, page 48
+ */
+static inline
+unsigned ceil_po2(unsigned x)
+{
+ if(x == 0)
+ return 0;
+ assert(x < (1U << 31));
+
+#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+ // note that x != 0 here!
+ return 0x80000000U >> (nlz(x-1) - 1);
+#else
+ x = x - 1;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
+#endif
+}
+
+/**
+ * Tests whether @p x is a power of 2
+ */
+static inline
+int is_po2(unsigned x)
+{
+ return (x & (x-1)) == 0;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief A bitset implementation.
+ * @author Sebastian Hack
+ * @date 15.10.2004
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITSET_H
+#define FIRM_ADT_BITSET_H
+
+#include "firm_config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "xmalloc.h"
+#include "bitfiddle.h"
+
+typedef unsigned int bitset_pos_t;
+
+#include "bitset_std.h"
+
+#if defined(__GNUC__) && defined(__i386__)
+#include "bitset_ia32.h"
+#endif
+
+typedef struct _bitset_t {
+ bitset_pos_t units;
+ bitset_pos_t size;
+} 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_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.
+ * This functions should not be called.
+ *
+ * Note that this function needs three macros which must be provided by the
+ * bitfield implementor:
+ * - _bitset_overall_size(size) The overall size that must be
+ * allocated for the bitfield in bytes.
+ * - _bitset_units(size) The number of units that will be
+ * present in the bitfield for a given highest bit.
+ * - _bitset_data_ptr(data, size) This produces as pointer to the
+ * first unit in the allocated memory area. The main reason for this
+ * macro is, that some bitset implementors want control over memory
+ * alignment.
+ *
+ * @param area A pointer to memory reserved for the bitset.
+ * @param size The size of the bitset in bits.
+ * @return A pointer to the initialized bitset.
+ */
+static inline bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
+{
+ bitset_t *ptr = area;
+ memset(ptr, 0, BS_TOTAL_SIZE(size));
+ ptr->units = BS_UNITS(size);
+ ptr->size = size;
+ return ptr;
+}
+
+/**
+ * Mask out all bits, which are only there, because the number
+ * of bits in the set didn't match a unit size boundary.
+ * @param bs The bitset.
+ * @return The masked bitset.
+ */
+static inline bitset_t *_bitset_mask_highest(bitset_t *bs)
+{
+ bitset_pos_t rest = bs->size & BS_UNIT_MASK;
+ if (rest)
+ BS_DATA(bs)[bs->units - 1] &= (1 << rest) - 1;
+ return bs;
+}
+
+/**
+ * Get the capacity of the bitset in bits.
+ * @param bs The bitset.
+ * @return The capacity in bits of the bitset.
+ */
+#define bitset_capacity(bs) ((bs)->units * BS_UNIT_SIZE_BITS)
+
+/**
+ * Get the size of the bitset in bits.
+ * @note Note the difference between capacity and size.
+ * @param bs The bitset.
+ * @return The highest bit which can be set or cleared plus 1.
+ */
+#define bitset_size(bs) ((bs)->size)
+
+/**
+ * Allocate a bitset on an obstack.
+ * @param obst The obstack.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_obstack_alloc(obst,size) \
+ _bitset_prepare(obstack_alloc(obst, BS_TOTAL_SIZE(size)), size)
+
+/**
+ * Allocate a bitset via malloc.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_malloc(size) \
+ _bitset_prepare(xmalloc(BS_TOTAL_SIZE(size)), size)
+
+/**
+ * Free a bitset allocated with bitset_malloc().
+ * @param bs The bitset.
+ */
+#define bitset_free(bs) free(bs)
+
+/**
+ * Allocate a bitset on the stack via alloca.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_alloca(size) \
+ _bitset_prepare(alloca(BS_TOTAL_SIZE(size)), size)
+
+
+/**
+ * Get the unit which contains a specific bit.
+ * This function is internal.
+ * @param bs The bitset.
+ * @param bit The bit.
+ * @return A pointer to the unit containing the bit.
+ */
+static inline bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
+{
+ assert(bit <= bs->size && "Bit to large");
+ return BS_DATA(bs) + bit / BS_UNIT_SIZE_BITS;
+}
+
+/**
+ * Set a bit in the bitset.
+ * @param bs The bitset.
+ * @param bit The bit to set.
+ */
+static inline void bitset_set(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_set(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Clear a bit in the bitset.
+ * @param bs The bitset.
+ * @param bit The bit to clear.
+ */
+static inline void bitset_clear(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_clear(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Check, if a bit is set.
+ * @param bs The bitset.
+ * @param bit The bit to check for.
+ * @return 1, if the bit was set, 0 if not.
+ */
+static inline int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ return _bitset_inside_is_set(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Flip a bit in a bitset.
+ * @param bs The bitset.
+ * @param bit The bit to flip.
+ */
+static inline void bitset_flip(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_flip(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Flip the whole bitset.
+ * @param bs The bitset.
+ */
+static inline void bitset_flip_all(bitset_t *bs)
+{
+ bitset_pos_t i;
+ for(i = 0; i < bs->units; i++)
+ _bitset_inside_flip_unit(&BS_DATA(bs)[i]);
+ _bitset_mask_highest(bs);
+}
+
+/**
+ * Copy a bitset to another.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return The target bitset.
+ */
+static inline bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
+{
+ bitset_pos_t tu = tgt->units;
+ bitset_pos_t su = src->units;
+ bitset_pos_t min_units = tu < su ? tu : su;
+ memcpy(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE);
+ if(tu > min_units)
+ memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
+ return _bitset_mask_highest(tgt);
+}
+
+/**
+ * Find the next set bit from a given bit.
+ * @note Note that if pos is set, pos is returned.
+ * @param bs The bitset.
+ * @param pos The bit from which to search for the next set bit.
+ * @return The next set bit from pos on, or -1, if no set bit was found
+ * after pos.
+ */
+static inline bitset_pos_t _bitset_next(const bitset_t *bs,
+ bitset_pos_t pos, int set)
+{
+ bitset_pos_t unit_number = pos / BS_UNIT_SIZE_BITS;
+ bitset_pos_t res;
+
+ if(pos >= bs->size)
+ return -1;
+
+ {
+ bitset_pos_t bit_in_unit = pos & BS_UNIT_MASK;
+ bitset_pos_t 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.
+ */
+ bitset_unit_t curr_unit = BS_DATA(bs)[unit_number];
+
+ /*
+ * Find the next bit set in the unit.
+ * Mind that this function returns 0, if the unit is -1 and
+ * counts the bits from 1 on.
+ */
+ bitset_pos_t next_in_this_unit =
+ _bitset_inside_ntz_value((set ? curr_unit : ~curr_unit) & ~in_unit_mask);
+
+ /* If there is a bit set in the current unit, exit. */
+ if (next_in_this_unit < BS_UNIT_SIZE_BITS) {
+ res = next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
+ return res < bs->size ? res : (bitset_pos_t) -1;
+ }
+
+ /* Else search for set bits in the next units. */
+ else {
+ bitset_pos_t i;
+ for(i = unit_number + 1; i < bs->units; ++i) {
+ bitset_unit_t data = BS_DATA(bs)[i];
+ bitset_pos_t first_set =
+ _bitset_inside_ntz_value(set ? data : ~data);
+
+ if (first_set < BS_UNIT_SIZE_BITS) {
+ res = first_set + i * BS_UNIT_SIZE_BITS;
+ return res < bs->size ? res : (bitset_pos_t) -1;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+#define bitset_next_clear(bs,pos) _bitset_next((bs), (pos), 0)
+#define bitset_next_set(bs,pos) _bitset_next((bs), (pos), 1)
+
+/**
+ * Convenience macro for bitset iteration.
+ * @param bitset The bitset.
+ * @param elm A unsigned long variable.
+ */
+#define bitset_foreach(bitset,elm) \
+ for(elm = bitset_next_set(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_set(bitset,elm+1))
+
+
+#define bitset_foreach_clear(bitset,elm) \
+ for(elm = bitset_next_clear(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_clear(bitset,elm+1))
+
+/**
+ * Count the bits set.
+ * This can also be seen as the cardinality of the set.
+ * @param bs The bitset.
+ * @return The number of bits set in the bitset.
+ */
+static inline unsigned bitset_popcnt(const bitset_t *bs)
+{
+ bitset_pos_t i;
+ bitset_unit_t *unit;
+ unsigned pop = 0;
+
+ for (i = 0, unit = BS_DATA(bs); i < bs->units; ++i, ++unit)
+ pop += _bitset_inside_pop(unit);
+
+ return pop;
+}
+
+/**
+ * Clear the bitset.
+ * This sets all bits to zero.
+ * @param bs The bitset.
+ */
+static inline bitset_t *bitset_clear_all(bitset_t *bs)
+{
+ memset(BS_DATA(bs), 0, BS_UNIT_SIZE * bs->units);
+ return bs;
+}
+
+/**
+ * Set the bitset.
+ * This sets all bits to one.
+ * @param bs The bitset.
+ */
+static inline bitset_t *bitset_set_all(bitset_t *bs)
+{
+ memset(BS_DATA(bs), -1, bs->units * BS_UNIT_SIZE);
+ return _bitset_mask_highest(bs);
+}
+
+/**
+ * Check, if one bitset is contained by another.
+ * That is, each bit set in lhs is also set in rhs.
+ * @param lhs A bitset.
+ * @param rhs Another bitset.
+ * @return 1, if all bits in lhs are also set in rhs, 0 otherwise.
+ */
+static inline int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
+{
+ bitset_pos_t n = lhs->units < rhs->units ? lhs->units : rhs->units;
+ bitset_pos_t i;
+
+ for(i = 0; i < n; ++i) {
+ bitset_unit_t lu = BS_DATA(lhs)[i];
+ bitset_unit_t ru = BS_DATA(rhs)[i];
+
+ if((lu | ru) & ~ru)
+ return 0;
+ }
+
+ /*
+ * If the left hand sinde is a larger bitset than rhs,
+ * we have to check, that all extra bits in lhs are 0
+ */
+ if(lhs->units > n) {
+ for(i = n; i < lhs->units; ++i) {
+ if(BS_DATA(lhs)[i] != 0)
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Treat the bitset as a number and subtract 1.
+ * @param bs The bitset.
+ * @return The same bitset.
+ */
+static inline void bitset_minus1(bitset_t *bs)
+{
+#define _SH (sizeof(bitset_unit_t) * 8 - 1)
+
+ bitset_pos_t i;
+
+ for(i = 0; i < bs->units; ++i) {
+ bitset_unit_t unit = BS_DATA(bs)[i];
+ bitset_unit_t um1 = unit - 1;
+
+ BS_DATA(bs)[i] = um1;
+
+ if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
+ break;
+ }
+#undef _SH
+}
+
+/**
+ * Check if two bitsets intersect.
+ * @param a The first bitset.
+ * @param b The second bitset.
+ * @return 1 if they have a bit in common, 0 if not.
+ */
+static inline int bitset_intersect(const bitset_t *a, const bitset_t *b)
+{
+ bitset_pos_t n = a->units < b->units ? a->units : b->units;
+ bitset_pos_t i;
+
+ for (i = 0; i < n; ++i)
+ if (BS_DATA(a)[i] & BS_DATA(b)[i])
+ return 1;
+
+ return 0;
+}
+
+/**
+ * set or clear all bits in the range [from;to[.
+ * @param a The bitset.
+ * @param from The first index to set to one.
+ * @param to The last index plus one to set to one.
+ * @param do_set If 1 the bits are set, if 0, they are cleared.
+ */
+static inline void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t to, int do_set)
+{
+ bitset_pos_t from_unit, to_unit, i;
+ bitset_unit_t from_unit_mask, to_unit_mask;
+
+ if (from == to)
+ return;
+
+ if (to < from) {
+ bitset_pos_t tmp = from;
+ from = to;
+ to = tmp;
+ }
+
+ if (to > a->size)
+ to = a->size;
+
+ /*
+ * A small example (for cleaning bits in the same unit).
+ * from = 7
+ * to = 19
+ * do_set = 0
+ * result: xxxxxxx000000000000xxxxxxxxxxxxx
+ * from_unit_mask: 00000001111111111111111111111111
+ * to_unit_mask: 11111111111111111110000000000000
+ * scale: 01234567890123456789012345678901
+ * 1 2 3
+ */
+
+ from_unit = from / BS_UNIT_SIZE_BITS;
+ from_unit_mask = ~((1 << from) - 1);
+ from = from & BS_UNIT_MASK;
+
+ to_unit = to / BS_UNIT_SIZE_BITS;
+ to_unit_mask = (1 << to) - 1;
+ to = to & BS_UNIT_MASK;
+
+ /* do we want to set the bits in the range? */
+ if (do_set) {
+ /* If from and to are in the same unit: */
+ if (from_unit == to_unit)
+ BS_DATA(a)[from_unit] |= from_unit_mask & to_unit_mask;
+
+ /* Else, we have to treat the from and to units seperately */
+ else {
+ BS_DATA(a)[from_unit] |= from_unit_mask;
+ BS_DATA(a)[to_unit] |= to_unit_mask;
+ for (i = from_unit + 1; i < to_unit; i++)
+ BS_DATA(a)[i] = BITSET_UNIT_ALL_ONE;
+ }
+ }
+
+ /* ... or clear them? */
+ else {
+ if (from_unit == to_unit)
+ BS_DATA(a)[from_unit] &= ~(from_unit_mask & to_unit_mask);
+
+ else {
+ BS_DATA(a)[from_unit] &= ~from_unit_mask;
+ BS_DATA(a)[to_unit] &= ~to_unit_mask;
+ for (i = from_unit + 1; i < to_unit; i++)
+ BS_DATA(a)[i] = 0;
+ }
+ }
+}
+
+#define bitset_set_range(bs, from, to) bitset_mod_range((bs), (from), (to), 1)
+#define bitset_clear_range(bs, from, to) bitset_mod_range((bs), (from), (to), 0)
+
+/**
+ * Check, if a bitset is empty.
+ * @param a The bitset.
+ * @return 1, if the bitset is empty, 0 if not.
+ */
+static inline int bitset_is_empty(const bitset_t *a)
+{
+ bitset_pos_t i;
+ for (i = 0; i < a->units; ++i)
+ if (BS_DATA(a)[i] != 0)
+ return 0;
+ return 1;
+}
+
+/**
+ * Print a bitset to a stream.
+ * The bitset is printed as a comma separated list of bits set.
+ * @param file The stream.
+ * @param bs The bitset.
+ */
+static inline void bitset_fprint(FILE *file, const bitset_t *bs)
+{
+ const char *prefix = "";
+ int i;
+
+ putc('{', file);
+ for(i = bitset_next_set(bs, 0); i != -1; i = bitset_next_set(bs, i + 1)) {
+ fprintf(file, "%s%u", prefix, i);
+ prefix = ",";
+ }
+ putc('}', file);
+}
+
+static inline void bitset_debug_fprint(FILE *file, const bitset_t *bs)
+{
+ bitset_pos_t i;
+
+ fprintf(file, "%u:", bs->units);
+ for(i = 0; i < bs->units; ++i)
+ fprintf(file, " " BITSET_UNIT_FMT, BS_DATA(bs)[i]);
+}
+
+/**
+ * Perform tgt = tgt \ src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static inline bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
+
+/**
+ * Perform Union, tgt = tgt u src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static inline bitset_t *bitset_or(bitset_t *tgt, const bitset_t *src);
+
+/**
+ * Perform tgt = tgt ^ ~src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static inline bitset_t *bitset_xor(bitset_t *tgt, const bitset_t *src);
+
+/*
+ * 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) \
+{ \
+ 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(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \
+ if(n < tgt->units) \
+ _bitset_clear_rest(&BS_DATA(tgt)[i], tgt->units - i); \
+ return _bitset_mask_highest(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) do { } while(0)
+
+BINARY_OP(andnot)
+BINARY_OP(or)
+BINARY_OP(xor)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief intel 80x86 implementation of bitsets
+ * @version $Id$
+ */
+#ifndef _BITSET_IA32_H
+#define _BITSET_IA32_H
+
+#undef _bitset_inside_clear
+#undef _bitset_inside_set
+#undef _bitset_inside_flip
+
+#define _bitset_inside_set(unit, bit) \
+ __asm__ __volatile__( "btsl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
+
+#define _bitset_inside_clear(unit, bit) \
+ __asm__ __volatile__( "btrl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
+
+#define _bitset_inside_flip(unit, bit) \
+ __asm__ __volatile__( "btcl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
+
+#undef _bitset_inside_is_set
+#undef _bitset_inside_nlz
+#undef _bitset_inside_ntz
+#undef _bitset_inside_ntz_value
+
+#define _bitset_inside_is_set(unit, bit) _bitset_ia32_inside_is_set(unit, bit)
+#define _bitset_inside_nlz(unit) _bitset_ia32_inside_nlz(unit)
+#define _bitset_inside_ntz(unit) _bitset_ia32_inside_ntz(unit)
+#define _bitset_inside_ntz_value(unit) _bitset_ia32_inside_ntz_value(unit)
+
+static inline int _bitset_ia32_inside_is_set(bitset_unit_t *unit, unsigned bit)
+{
+ int res;
+ __asm__("bt %2, %1\n\t"
+ "rcl $1, %0\n\t"
+ "and $1, %0"
+ : "=r" (res)
+ : "m" (*unit), "Ir" (bit)
+ : "cc");
+ return res;
+}
+
+static inline unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit)
+{
+ unsigned res;
+ __asm__("bsr %1, %0\n\t"
+ "cmovz %2, %0\n\t"
+ "neg %0\n\t"
+ "add $31, %0"
+ : "=&r" (res)
+ : "m" (*unit), "r" (-1)
+ : "cc");
+ return res;
+}
+
+static inline unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) {
+ unsigned res;
+ __asm__("bsfl %1, %0\n\t"
+ "cmovz %2, %0\n\t"
+ : "=&r" (res)
+ : "m" (*unit), "r" (32)
+ : "cc");
+ return res;
+}
+
+static inline unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) {
+ unsigned res;
+ __asm__("bsfl %1, %0\n\t"
+ "cmovz %2, %0\n\t"
+ : "=&r" (res)
+ : "r" (unit), "r" (32)
+ : "cc");
+ return res;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief ANSI-C compliant implementation of bitsets
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITSET_STD_H
+#define FIRM_ADT_BITSET_STD_H
+
+#include "bitfiddle.h"
+
+/** Use ordinary ints as unit types. */
+typedef unsigned int bitset_unit_t;
+
+#define BITSET_UNIT_FMT "%0x"
+#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
+
+/**
+ * Clear some units from a certain address on.
+ * @param addr The address from where to clear.
+ * @param n The number of units to set to 0.
+ */
+#define _bitset_inside_clear_units(addr,n) \
+ memset(addr, 0, n * BS_UNIT_SIZE)
+
+/**
+ * Set a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_set(unit_ptr,bit) (*unit_ptr) |= (1 << (bit))
+
+/**
+ * Clear a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_clear(unit_ptr,bit) (*unit_ptr) &= ~(1 << (bit))
+
+/**
+ * Flip a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_flip(unit_ptr,bit) (*unit_ptr) ^= (1 << (bit))
+
+/**
+ * Flip a whole unit.
+ * @param unit_ptr The pointer to the unit.
+ */
+#define _bitset_inside_flip_unit(unit_ptr) (*unit_ptr) = ~(*unit_ptr)
+
+/**
+ * Count the number of leading zeroes in a unit.
+ * @param unit A pointer to the unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_nlz(unit_ptr) (nlz(*unit_ptr))
+
+
+/**
+ * Count the number of trailing zeroes in a unit.
+ * @param unit A pointer to the unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_ntz(unit_ptr) _bitset_std_inside_ntz(unit_ptr)
+static inline unsigned _bitset_std_inside_ntz(bitset_unit_t *unit_ptr)
+{
+ unsigned long data = *unit_ptr;
+ return 32 - (unsigned) nlz(~data & (data - 1));
+}
+
+/**
+ * Count the number of trailing zeroes in a unit (whereas the unit is no
+ * pointer but a value).
+ * @param unit A unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_ntz_value(unit) (32 - nlz(~(unit) & ((unit) - 1)))
+
+/**
+ * test if a bit is set in a unit.
+ * @param unit_ptr The pointer to the unit.
+ * @param bit The bit to check.
+ * @return 1, if the bit is set, 0 otherise.
+ */
+#define _bitset_inside_is_set(unit_ptr,bit) \
+ (((*unit_ptr) & (1 << (bit))) != 0)
+
+/**
+ * count the number of bits set in a unit.
+ * @param unit_ptr The pointer to a unit.
+ * @return The number of bits set in the unit.
+ */
+#define _bitset_inside_pop(unit_ptr) (popcnt(*unit_ptr))
+
+#define _BITSET_BINOP_UNITS_INC 1
+
+#define _bitset_inside_binop_and(tgt,src) ((*tgt) &= (*src))
+#define _bitset_inside_binop_andnot(tgt,src) ((*tgt) &= ~(*src))
+#define _bitset_inside_binop_or(tgt,src) ((*tgt) |= (*src))
+#define _bitset_inside_binop_xor(tgt,src) ((*tgt) ^= (*src))
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @date 04.06.2007
+ * @author Matthias Braun, Sebastian Hack
+ * @brief Macros to instruct the compiler compiling libFirm.
+ */
+
+#ifndef FIRM_COMPILER_H
+#define FIRM_COMPILER_H
+
+/**
+ * Asserts that the constant expression x is not zero at compiletime. name has
+ * to be a unique identifier.
+ *
+ * @note This uses the fact, that double case labels are not allowed.
+ */
+#define COMPILETIME_ASSERT(x, name) \
+ static __attribute__((unused)) void compiletime_assert_##name (int h) { \
+ switch(h) { case 0: case (x): ; } \
+ }
+
+#ifdef __GNUC__
+/**
+ * Indicates to the compiler that the value of x is very likely 1
+ * @note Only use this in speed critical code and when you are sure x is often 1
+ */
+#define LIKELY(x) __builtin_expect((x), 1)
+
+/**
+ * Indicates to the compiler that it's very likely that x is 0
+ * @note Only use this in speed critical code and when you are sure x is often 0
+ */
+#define UNLIKELY(x) __builtin_expect((x), 0)
+
+/**
+ * Tell the compiler, that a function is pure, i.e. it only
+ * uses its parameters and never modifies the "state".
+ * Add this macro after the return type.
+ */
+#define PURE __attribute__((const))
+
+#else
+#define LIKELY(x) x
+#define UNLIKELY(x) x
+#define PURE
+#endif
+
+#endif