/* CGEN generic opcode support.

   Copyright 2002, 2005
   Free Software Foundation, Inc.

   This file is part of the GNU Binutils and GDB, the GNU debugger.

   This program 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 2, or (at your option)
   any later version.

   This program 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 "opcode/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];
}
