1/* CGEN generic opcode support. 2 Copyright 2002, 2005, 2007 3 Free Software Foundation, Inc. 4 5 This file is part of libopcodes. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with this program; if not, write to the Free Software Foundation, Inc., 19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21/* Functions for manipulating CGEN_BITSET. */ 22 23#include "libiberty.h" 24#include "opcode/cgen-bitset.h" 25#include <string.h> 26 27/* Create a bit mask. */ 28CGEN_BITSET * 29cgen_bitset_create (unsigned bit_count) 30{ 31 CGEN_BITSET * mask = xmalloc (sizeof (* mask)); 32 cgen_bitset_init (mask, bit_count); 33 return mask; 34} 35 36/* Initialize an existing bit mask. */ 37 38void 39cgen_bitset_init (CGEN_BITSET * mask, unsigned bit_count) 40{ 41 if (! mask) 42 return; 43 mask->length = (bit_count / 8) + 1; 44 mask->bits = xmalloc (mask->length); 45 cgen_bitset_clear (mask); 46} 47 48/* Clear the bits of a bit mask. */ 49 50void 51cgen_bitset_clear (CGEN_BITSET * mask) 52{ 53 unsigned i; 54 55 if (! mask) 56 return; 57 58 for (i = 0; i < mask->length; ++i) 59 mask->bits[i] = 0; 60} 61 62/* Add a bit to a bit mask. */ 63 64void 65cgen_bitset_add (CGEN_BITSET * mask, unsigned bit_num) 66{ 67 int byte_ix, bit_ix; 68 int bit_mask; 69 70 if (! mask) 71 return; 72 byte_ix = bit_num / 8; 73 bit_ix = bit_num % 8; 74 bit_mask = 1 << (7 - bit_ix); 75 mask->bits[byte_ix] |= bit_mask; 76} 77 78/* Set a bit mask. */ 79 80void 81cgen_bitset_set (CGEN_BITSET * mask, unsigned bit_num) 82{ 83 if (! mask) 84 return; 85 cgen_bitset_clear (mask); 86 cgen_bitset_add (mask, bit_num); 87} 88 89/* Test for a bit in a bit mask. 90 Returns 1 if the bit is found */ 91 92int 93cgen_bitset_contains (CGEN_BITSET * mask, unsigned bit_num) 94{ 95 int byte_ix, bit_ix; 96 int bit_mask; 97 98 if (! mask) 99 return 1; /* No bit restrictions. */ 100 101 byte_ix = bit_num / 8; 102 bit_ix = 7 - (bit_num % 8); 103 bit_mask = 1 << bit_ix; 104 return (mask->bits[byte_ix] & bit_mask) >> bit_ix; 105} 106 107/* Compare two bit masks for equality. 108 Returns 0 if they are equal. */ 109 110int 111cgen_bitset_compare (CGEN_BITSET * mask1, CGEN_BITSET * mask2) 112{ 113 if (mask1 == mask2) 114 return 0; 115 if (! mask1 || ! mask2) 116 return 1; 117 if (mask1->length != mask2->length) 118 return 1; 119 return memcmp (mask1->bits, mask2->bits, mask1->length); 120} 121 122/* Test two bit masks for common bits. 123 Returns 1 if a common bit is found. */ 124 125int 126cgen_bitset_intersect_p (CGEN_BITSET * mask1, CGEN_BITSET * mask2) 127{ 128 unsigned i, limit; 129 130 if (mask1 == mask2) 131 return 1; 132 if (! mask1 || ! mask2) 133 return 0; 134 limit = mask1->length < mask2->length ? mask1->length : mask2->length; 135 136 for (i = 0; i < limit; ++i) 137 if ((mask1->bits[i] & mask2->bits[i])) 138 return 1; 139 140 return 0; 141} 142 143/* Make a copy of a bit mask. */ 144 145CGEN_BITSET * 146cgen_bitset_copy (CGEN_BITSET * mask) 147{ 148 CGEN_BITSET* newmask; 149 150 if (! mask) 151 return NULL; 152 newmask = cgen_bitset_create ((mask->length * 8) - 1); 153 memcpy (newmask->bits, mask->bits, mask->length); 154 return newmask; 155} 156 157/* Combine two bit masks. */ 158 159void 160cgen_bitset_union (CGEN_BITSET * mask1, CGEN_BITSET * mask2, 161 CGEN_BITSET * result) 162{ 163 unsigned i; 164 165 if (! mask1 || ! mask2 || ! result 166 || mask1->length != mask2->length 167 || mask1->length != result->length) 168 return; 169 170 for (i = 0; i < result->length; ++i) 171 result->bits[i] = mask1->bits[i] | mask2->bits[i]; 172} 173