/* CGEN generic opcode support. Copyright (C) 2002-2014 Free Software Foundation, Inc. This file is part of libopcodes. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Functions for manipulating CGEN_BITSET. */ #include "libiberty.h" #include "cgen/bitset.h" #include <string.h> /* Create a bit mask. */ CGEN_BITSET * cgen_bitset_create (unsigned bit_count) { CGEN_BITSET * mask = xmalloc (sizeof (* mask)); cgen_bitset_init (mask, bit_count); return mask; } /* Initialize an existing bit mask. */ void cgen_bitset_init (CGEN_BITSET * mask, unsigned bit_count) { if (! mask) return; mask->length = (bit_count / 8) + 1; mask->bits = xmalloc (mask->length); cgen_bitset_clear (mask); } /* Clear the bits of a bit mask. */ void cgen_bitset_clear (CGEN_BITSET * mask) { unsigned i; if (! mask) return; for (i = 0; i < mask->length; ++i) mask->bits[i] = 0; } /* Add a bit to a bit mask. */ void cgen_bitset_add (CGEN_BITSET * mask, unsigned bit_num) { int byte_ix, bit_ix; int bit_mask; if (! mask) return; byte_ix = bit_num / 8; bit_ix = bit_num % 8; bit_mask = 1 << (7 - bit_ix); mask->bits[byte_ix] |= bit_mask; } /* Set a bit mask. */ void cgen_bitset_set (CGEN_BITSET * mask, unsigned bit_num) { if (! mask) return; cgen_bitset_clear (mask); cgen_bitset_add (mask, bit_num); } /* Test for a bit in a bit mask. Returns 1 if the bit is found */ int cgen_bitset_contains (CGEN_BITSET * mask, unsigned bit_num) { int byte_ix, bit_ix; int bit_mask; if (! mask) return 1; /* No bit restrictions. */ byte_ix = bit_num / 8; bit_ix = 7 - (bit_num % 8); bit_mask = 1 << bit_ix; return (mask->bits[byte_ix] & bit_mask) >> bit_ix; } /* Compare two bit masks for equality. Returns 0 if they are equal. */ int cgen_bitset_compare (CGEN_BITSET * mask1, CGEN_BITSET * mask2) { if (mask1 == mask2) return 0; if (! mask1 || ! mask2) return 1; if (mask1->length != mask2->length) return 1; return memcmp (mask1->bits, mask2->bits, mask1->length); } /* Test two bit masks for common bits. Returns 1 if a common bit is found. */ int cgen_bitset_intersect_p (CGEN_BITSET * mask1, CGEN_BITSET * mask2) { unsigned i, limit; if (mask1 == mask2) return 1; if (! mask1 || ! mask2) return 0; limit = mask1->length < mask2->length ? mask1->length : mask2->length; for (i = 0; i < limit; ++i) if ((mask1->bits[i] & mask2->bits[i])) return 1; return 0; } /* Make a copy of a bit mask. */ CGEN_BITSET * cgen_bitset_copy (CGEN_BITSET * mask) { CGEN_BITSET* newmask; if (! mask) return NULL; newmask = cgen_bitset_create ((mask->length * 8) - 1); memcpy (newmask->bits, mask->bits, mask->length); return newmask; } /* Combine two bit masks. */ void cgen_bitset_union (CGEN_BITSET * mask1, CGEN_BITSET * mask2, CGEN_BITSET * result) { unsigned i; if (! mask1 || ! mask2 || ! result || mask1->length != mask2->length || mask1->length != result->length) return; for (i = 0; i < result->length; ++i) result->bits[i] = mask1->bits[i] | mask2->bits[i]; }