/* Sets (bit vectors) of hard registers, and operations on them.
   Copyright (C) 1987-2020 Free Software Foundation, Inc.

This file is part of GCC

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_HARD_REG_SET_H
#define GCC_HARD_REG_SET_H

#include "array-traits.h"

/* Define the type of a set of hard registers.  */

/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
   will be used for hard reg sets, either alone or in an array.

   If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,
   and it has enough bits to represent all the target machine's hard
   registers.  Otherwise, it is a typedef for a suitably sized array
   of HARD_REG_ELT_TYPEs.  HARD_REG_SET_LONGS is defined as how many.

   Note that lots of code assumes that the first part of a regset is
   the same format as a HARD_REG_SET.  To help make sure this is true,
   we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
   instead of all the smaller types.  This approach loses only if
   there are very few registers and then only in the few cases where
   we have an array of HARD_REG_SETs, so it needn't be as complex as
   it used to be.  */

typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;

#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT

typedef HARD_REG_ELT_TYPE HARD_REG_SET;
typedef const HARD_REG_SET const_hard_reg_set;

#else

#define HARD_REG_SET_LONGS \
 ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1)	\
  / HOST_BITS_PER_WIDEST_FAST_INT)

struct HARD_REG_SET
{
  HARD_REG_SET
  operator~ () const
  {
    HARD_REG_SET res;
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      res.elts[i] = ~elts[i];
    return res;
  }

  HARD_REG_SET
  operator& (const HARD_REG_SET &other) const
  {
    HARD_REG_SET res;
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      res.elts[i] = elts[i] & other.elts[i];
    return res;
  }

  HARD_REG_SET &
  operator&= (const HARD_REG_SET &other)
  {
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      elts[i] &= other.elts[i];
    return *this;
  }

  HARD_REG_SET
  operator| (const HARD_REG_SET &other) const
  {
    HARD_REG_SET res;
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      res.elts[i] = elts[i] | other.elts[i];
    return res;
  }

  HARD_REG_SET &
  operator|= (const HARD_REG_SET &other)
  {
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      elts[i] |= other.elts[i];
    return *this;
  }

  bool
  operator== (const HARD_REG_SET &other) const
  {
    HARD_REG_ELT_TYPE bad = 0;
    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
      bad |= (elts[i] ^ other.elts[i]);
    return bad == 0;
  }

  bool
  operator!= (const HARD_REG_SET &other) const
  {
    return !operator== (other);
  }

  HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS];
};
typedef const HARD_REG_SET &const_hard_reg_set;

template<>
struct array_traits<HARD_REG_SET>
{
  typedef HARD_REG_ELT_TYPE element_type;
  static const bool has_constant_size = true;
  static const size_t constant_size = HARD_REG_SET_LONGS;
  static const element_type *base (const HARD_REG_SET &x) { return x.elts; }
  static size_t size (const HARD_REG_SET &) { return HARD_REG_SET_LONGS; }
};

#endif

/* HARD_REG_SET wrapped into a structure, to make it possible to
   use HARD_REG_SET even in APIs that should not include
   hard-reg-set.h.  */
struct hard_reg_set_container
{
  HARD_REG_SET set;
};

/* HARD_CONST is used to cast a constant to the appropriate type
   for use with a HARD_REG_SET.  */

#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))

/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT
   to set, clear or test one bit in a hard reg set of type HARD_REG_SET.
   All three take two arguments: the set and the register number.

   In the case where sets are arrays of longs, the first argument
   is actually a pointer to a long.

   Define two macros for initializing a set:
   CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
   These take just one argument.

   Also define:

   hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
   hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
   hard_reg_set_empty_p (X), which returns true if X is empty.  */

#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)

#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT

#define SET_HARD_REG_BIT(SET, BIT)  \
 ((SET) |= HARD_CONST (1) << (BIT))
#define CLEAR_HARD_REG_BIT(SET, BIT)  \
 ((SET) &= ~(HARD_CONST (1) << (BIT)))
#define TEST_HARD_REG_BIT(SET, BIT)  \
 (!!((SET) & (HARD_CONST (1) << (BIT))))

#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))

static inline bool
hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y)
{
  return (x & ~y) == HARD_CONST (0);
}

static inline bool
hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y)
{
  return (x & y) != HARD_CONST (0);
}

static inline bool
hard_reg_set_empty_p (const_hard_reg_set x)
{
  return x == HARD_CONST (0);
}

#else

inline void
SET_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit)
{
  set.elts[bit / UHOST_BITS_PER_WIDE_INT]
    |= HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT);
}

inline void
CLEAR_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit)
{
  set.elts[bit / UHOST_BITS_PER_WIDE_INT]
    &= ~(HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT));
}

inline bool
TEST_HARD_REG_BIT (const_hard_reg_set set, unsigned int bit)
{
  return (set.elts[bit / UHOST_BITS_PER_WIDE_INT]
	  & (HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT)));
}

inline void
CLEAR_HARD_REG_SET (HARD_REG_SET &set)
{
  for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i)
    set.elts[i] = 0;
}

inline void
SET_HARD_REG_SET (HARD_REG_SET &set)
{
  for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i)
    set.elts[i] = -1;
}

static inline bool
hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y)
{
  HARD_REG_ELT_TYPE bad = 0;
  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
    bad |= (x.elts[i] & ~y.elts[i]);
  return bad == 0;
}

static inline bool
hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y)
{
  HARD_REG_ELT_TYPE good = 0;
  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
    good |= (x.elts[i] & y.elts[i]);
  return good != 0;
}

static inline bool
hard_reg_set_empty_p (const_hard_reg_set x)
{
  HARD_REG_ELT_TYPE bad = 0;
  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
    bad |= x.elts[i];
  return bad == 0;
}
#endif

/* Iterator for hard register sets.  */

struct hard_reg_set_iterator
{
  /* Pointer to the current element.  */
  const HARD_REG_ELT_TYPE *pelt;

  /* The length of the set.  */
  unsigned short length;

  /* Word within the current element.  */
  unsigned short word_no;

  /* Contents of the actually processed word.  When finding next bit
     it is shifted right, so that the actual bit is always the least
     significant bit of ACTUAL.  */
  HARD_REG_ELT_TYPE bits;
};

#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT

/* The implementation of the iterator functions is fully analogous to
   the bitmap iterators.  */
static inline void
hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
                        unsigned min, unsigned *regno)
{
#ifdef HARD_REG_SET_LONGS
  iter->pelt = set.elts;
  iter->length = HARD_REG_SET_LONGS;
#else
  iter->pelt = &set;
  iter->length = 1;
#endif
  iter->word_no = min / HARD_REG_ELT_BITS;
  if (iter->word_no < iter->length)
    {
      iter->bits = iter->pelt[iter->word_no];
      iter->bits >>= min % HARD_REG_ELT_BITS;

      /* This is required for correct search of the next bit.  */
      min += !iter->bits;
    }
  *regno = min;
}

static inline bool
hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
{
  while (1)
    {
      /* Return false when we're advanced past the end of the set.  */
      if (iter->word_no >= iter->length)
        return false;

      if (iter->bits)
        {
          /* Find the correct bit and return it.  */
          while (!(iter->bits & 1))
            {
              iter->bits >>= 1;
              *regno += 1;
            }
          return (*regno < FIRST_PSEUDO_REGISTER);
        }

      /* Round to the beginning of the next word.  */
      *regno = (*regno + HARD_REG_ELT_BITS - 1);
      *regno -= *regno % HARD_REG_ELT_BITS;

      /* Find the next non-zero word.  */
      while (++iter->word_no < iter->length)
        {
          iter->bits = iter->pelt[iter->word_no];
          if (iter->bits)
            break;
          *regno += HARD_REG_ELT_BITS;
        }
    }
}

static inline void
hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
{
  iter->bits >>= 1;
  *regno += 1;
}

#define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER)          \
  for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
       hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
       hard_reg_set_iter_next (&(ITER), &(REGNUM)))


/* Define some standard sets of registers.  */

/* Indexed by hard register number, contains 1 for registers
   that are being used for global register decls.
   These must be exempt from ordinary flow analysis
   and are also considered fixed.  */

extern char global_regs[FIRST_PSEUDO_REGISTER];

class simplifiable_subreg;
class subreg_shape;

struct simplifiable_subregs_hasher : nofree_ptr_hash <simplifiable_subreg>
{
  typedef const subreg_shape *compare_type;

  static inline hashval_t hash (const simplifiable_subreg *);
  static inline bool equal (const simplifiable_subreg *, const subreg_shape *);
};

struct target_hard_regs {
  void finalize ();

  /* The set of registers that actually exist on the current target.  */
  HARD_REG_SET x_accessible_reg_set;

  /* The set of registers that should be considered to be register
     operands.  It is a subset of x_accessible_reg_set.  */
  HARD_REG_SET x_operand_reg_set;

  /* Indexed by hard register number, contains 1 for registers
     that are fixed use (stack pointer, pc, frame pointer, etc.;.
     These are the registers that cannot be used to allocate
     a pseudo reg whose life does not cross calls.  */
  char x_fixed_regs[FIRST_PSEUDO_REGISTER];

  /* The same info as a HARD_REG_SET.  */
  HARD_REG_SET x_fixed_reg_set;

  /* Indexed by hard register number, contains 1 for registers
     that are fixed use or are clobbered by function calls.
     These are the registers that cannot be used to allocate
     a pseudo reg whose life crosses calls.  */
  char x_call_used_regs[FIRST_PSEUDO_REGISTER];

  /* For targets that use reload rather than LRA, this is the set
     of registers that we are able to save and restore around calls
     (i.e. those for which we know a suitable mode and set of
     load/store instructions exist).  For LRA targets it contains
     all registers.

     This is legacy information and should be removed if all targets
     switch to LRA.  */
  HARD_REG_SET x_savable_regs;

  /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but
     only if they are not merely part of that set because they are global
     regs.  Global regs that are not otherwise fixed can still take part
     in register allocation.  */
  HARD_REG_SET x_fixed_nonglobal_reg_set;

  /* Contains 1 for registers that are set or clobbered by calls.  */
  /* ??? Ideally, this would be just call_used_regs plus global_regs, but
     for someone's bright idea to have call_used_regs strictly include
     fixed_regs.  Which leaves us guessing as to the set of fixed_regs
     that are actually preserved.  We know for sure that those associated
     with the local stack frame are safe, but scant others.  */
  HARD_REG_SET x_regs_invalidated_by_call;

  /* Table of register numbers in the order in which to try to use them.  */
  int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];

  /* The inverse of reg_alloc_order.  */
  int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];

  /* For each reg class, a HARD_REG_SET saying which registers are in it.  */
  HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];

  /* For each reg class, a boolean saying whether the class contains only
     fixed registers.  */
  bool x_class_only_fixed_regs[N_REG_CLASSES];

  /* For each reg class, number of regs it contains.  */
  unsigned int x_reg_class_size[N_REG_CLASSES];

  /* For each reg class, table listing all the classes contained in it.  */
  enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];

  /* For each pair of reg classes,
     a largest reg class contained in their union.  */
  enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];

  /* For each pair of reg classes,
     the smallest reg class that contains their union.  */
  enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];

  /* Vector indexed by hardware reg giving its name.  */
  const char *x_reg_names[FIRST_PSEUDO_REGISTER];

  /* Records which registers can form a particular subreg, with the subreg
     being identified by its outer mode, inner mode and offset.  */
  hash_table <simplifiable_subregs_hasher> *x_simplifiable_subregs;
};

extern struct target_hard_regs default_target_hard_regs;
#if SWITCHABLE_TARGET
extern struct target_hard_regs *this_target_hard_regs;
#else
#define this_target_hard_regs (&default_target_hard_regs)
#endif

#define accessible_reg_set \
  (this_target_hard_regs->x_accessible_reg_set)
#define operand_reg_set \
  (this_target_hard_regs->x_operand_reg_set)
#define fixed_regs \
  (this_target_hard_regs->x_fixed_regs)
#define fixed_reg_set \
  (this_target_hard_regs->x_fixed_reg_set)
#define fixed_nonglobal_reg_set \
  (this_target_hard_regs->x_fixed_nonglobal_reg_set)
#ifdef IN_TARGET_CODE
#define call_used_regs \
  (this_target_hard_regs->x_call_used_regs)
#endif
#define savable_regs \
  (this_target_hard_regs->x_savable_regs)
#ifdef IN_TARGET_CODE
#define regs_invalidated_by_call \
  (this_target_hard_regs->x_regs_invalidated_by_call)
#define call_used_or_fixed_regs \
  (regs_invalidated_by_call | fixed_reg_set)
#endif
#define reg_alloc_order \
  (this_target_hard_regs->x_reg_alloc_order)
#define inv_reg_alloc_order \
  (this_target_hard_regs->x_inv_reg_alloc_order)
#define reg_class_contents \
  (this_target_hard_regs->x_reg_class_contents)
#define class_only_fixed_regs \
  (this_target_hard_regs->x_class_only_fixed_regs)
#define reg_class_size \
  (this_target_hard_regs->x_reg_class_size)
#define reg_class_subclasses \
  (this_target_hard_regs->x_reg_class_subclasses)
#define reg_class_subunion \
  (this_target_hard_regs->x_reg_class_subunion)
#define reg_class_superunion \
  (this_target_hard_regs->x_reg_class_superunion)
#define reg_names \
  (this_target_hard_regs->x_reg_names)

/* Vector indexed by reg class giving its name.  */

extern const char * reg_class_names[];

/* Given a hard REGN a FROM mode and a TO mode, return true if
   REGN can change from mode FROM to mode TO.  */
#define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO)                          \
  (targetm.can_change_mode_class (FROM, TO, REGNO_REG_CLASS (REGN)))

#ifdef IN_TARGET_CODE
/* Return true if register REGNO is either fixed or call-used
   (aka call-clobbered).  */

inline bool
call_used_or_fixed_reg_p (unsigned int regno)
{
  return fixed_regs[regno] || this_target_hard_regs->x_call_used_regs[regno];
}
#endif

#endif /* ! GCC_HARD_REG_SET_H */
