(root)/
binutils-2.41/
opcodes/
cgen-bitset.c
       1  /* CGEN generic opcode support.
       2     Copyright (C) 2002-2023 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  }