Home | History | Annotate | Download | only in opcodes
      1 /* CGEN generic opcode support.
      2    Copyright (C) 2002-2016 Free Software Foundation, Inc.
      3 
      4    This file is part of libopcodes.
      5 
      6    This library is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    It is distributed in the hope that it will be useful, but WITHOUT
     12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14    License for more details.
     15 
     16    You should have received a copy of the GNU General Public License along
     17    with this program; if not, write to the Free Software Foundation, Inc.,
     18    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     19 
     20 /* Functions for manipulating CGEN_BITSET.  */
     21 
     22 #include "libiberty.h"
     23 #include "cgen/bitset.h"
     24 #include <string.h>
     25 
     26 /* Create a bit mask.  */
     27 
     28 CGEN_BITSET *
     29 cgen_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 
     38 void
     39 cgen_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 
     50 void
     51 cgen_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 
     64 void
     65 cgen_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 
     80 void
     81 cgen_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 
     92 int
     93 cgen_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 
    110 int
    111 cgen_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 
    125 int
    126 cgen_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 
    145 CGEN_BITSET *
    146 cgen_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 
    159 void
    160 cgen_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