summaryrefslogtreecommitdiff
path: root/gcc/basic-block.h
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>1997-06-05 10:24:03 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>1997-06-05 10:24:03 +0000
commit74666a14ff398025a5a35f0bf1c6480d7ee9e6a6 (patch)
tree619a5e6cc2340785ce05f2bf95307154e057626d /gcc/basic-block.h
parent97906c21abfa1666acb2fdc5106483d525b70cde (diff)
downloadgcc-74666a14ff398025a5a35f0bf1c6480d7ee9e6a6.tar.gz
abstract regset stuff into macros
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14147 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/basic-block.h')
-rw-r--r--gcc/basic-block.h221
1 files changed, 219 insertions, 2 deletions
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 3d1f3a9f30b..a6b8cf9dc52 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -19,9 +19,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Number of bits in each actual element of a regset. */
+/* Number of bits in each actual element of a regset. We get slightly
+ better code for reg%bits and reg/bits if bits is unsigned, assuming
+ it is a power of 2. */
-#define REGSET_ELT_BITS HOST_BITS_PER_WIDE_INT
+#define REGSET_ELT_BITS ((unsigned) HOST_BITS_PER_WIDE_INT)
/* Type to use for a regset element. Note that lots of code assumes
that the initial part of a regset that contains information on the
@@ -40,6 +42,221 @@ typedef REGSET_ELT_TYPE *regset;
extern int regset_bytes;
extern int regset_size;
+/* clear a register set */
+#define CLEAR_REG_SET(TO) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ = 0; } while (0)
+
+/* copy a register to another register */
+#define COPY_REG_SET(TO, FROM) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ = *scan_fp_++; } while (0)
+
+/* complent a register set, storing it in a second register set. */
+#define COMPL_REG_SET(TO, FROM) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ = ~ *scan_fp_++; } while (0)
+
+/* and a register set with a second register set. */
+#define AND_REG_SET(TO, FROM) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ &= *scan_fp_++; } while (0)
+
+/* and the complement of a register set to a register set. */
+#define AND_COMPL_REG_SET(TO, FROM) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ &= ~ *scan_fp_++; } while (0)
+
+/* inclusive or a register set with a second register set. */
+#define IOR_REG_SET(TO, FROM) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ |= *scan_fp_++; } while (0)
+
+/* complement two register sets and or in the result into a third. */
+#define IOR_AND_COMPL_REG_SET(TO, FROM1, FROM2) \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO); \
+ register REGSET_ELT_TYPE *scan_fp1_ = (FROM1); \
+ register REGSET_ELT_TYPE *scan_fp2_ = (FROM2); \
+ register int i_; \
+ for (i_ = 0; i_ < regset_size; i_++) \
+ *scan_tp_++ |= *scan_fp1_++ & ~ *scan_fp2_++; } while (0)
+
+/* Clear a single register in a register set. */
+#define CLEAR_REGNO_REG_SET(TO, REG) \
+do { \
+ register REGSET_ELT_TYPE *tp_ = (TO); \
+ tp_[ (REG) / REGSET_ELT_BITS ] \
+ &= ~ ((REGSET_ELT_TYPE) 1 << ((REG) % REGSET_ELT_BITS)); } while (0);
+
+/* Set a single register in a register set. */
+#define SET_REGNO_REG_SET(TO, REG) \
+do { \
+ register REGSET_ELT_TYPE *tp_ = (TO); \
+ tp_[ (REG) / REGSET_ELT_BITS ] \
+ |= ((REGSET_ELT_TYPE) 1 << ((REG) % REGSET_ELT_BITS)); } while (0);
+
+/* Return true if a register is set in a register set. */
+#define REGNO_REG_SET_P(TO, REG) \
+ (((TO)[ (REG) / REGSET_ELT_BITS ] \
+ & (((REGSET_ELT_TYPE)1) << (REG) % REGSET_ELT_BITS)) != 0)
+
+/* Copy the hard registers in a register set to the hard register set. */
+#define REG_SET_TO_HARD_REG_SET(TO, FROM) \
+do { \
+ int i_; \
+ CLEAR_HARD_REG_SET (TO); \
+ for (i_ = 0; i < FIRST_PSEUDO_REGISTER; i++) \
+ if (REGNO_REG_SET_P (FROM, i_)) \
+ SET_HARD_REG_BIT (TO, i_); \
+} while (0)
+
+/* Loop over all registers in REGSET, starting with MIN, setting REGNUM to the
+ register number and executing CODE for all registers that are set. */
+#define EXECUTE_IF_SET_IN_REG_SET(REGSET, MIN, REGNUM, CODE) \
+do { \
+ register REGSET_ELT_TYPE *scan_rs_ = (REGSET); \
+ register int i_; \
+ register int shift_ = (MIN) % REGSET_ELT_BITS; \
+ for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++) \
+ { \
+ REGSET_ELT_TYPE word_ = *scan_rs_++; \
+ if (word_) \
+ { \
+ REGSET_ELT_TYPE j_; \
+ REGNUM = (i_ * REGSET_ELT_BITS) + shift_; \
+ for (j_ = ((REGSET_ELT_TYPE)1) << shift_; \
+ j_ != 0; \
+ (j_ <<= 1), REGNUM++) \
+ { \
+ if (word_ & j_) \
+ { \
+ CODE; \
+ word_ &= ~ j_; \
+ if (!word_) \
+ break; \
+ } \
+ } \
+ } \
+ shift_ = 0; \
+ } \
+} while (0)
+
+/* Like EXECUTE_IF_SET_IN_REG_SET, but also clear the register set. */
+#define EXECUTE_IF_SET_AND_RESET_IN_REG_SET(REGSET, MIN, REGNUM, CODE) \
+do { \
+ register REGSET_ELT_TYPE *scan_rs_ = (REGSET); \
+ register int i_; \
+ register int shift_ = (MIN) % REGSET_ELT_BITS; \
+ for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++) \
+ { \
+ REGSET_ELT_TYPE word_ = *scan_rs_++; \
+ if (word_) \
+ { \
+ REGSET_ELT_TYPE j_; \
+ REGNUM = (i_ * REGSET_ELT_BITS) + shift_; \
+ scan_rs_[-1] = 0; \
+ for (j_ = ((REGSET_ELT_TYPE)1) << shift_; \
+ j_ != 0; \
+ (j_ <<= 1), REGNUM++) \
+ { \
+ if (word_ & j_) \
+ { \
+ CODE; \
+ word_ &= ~ j_; \
+ if (!word_) \
+ break; \
+ } \
+ } \
+ } \
+ shift_ = 0; \
+ } \
+} while (0)
+
+/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
+ REGNUM to the register number and executing CODE for all registers that are
+ set in both regsets. */
+#define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
+do { \
+ register REGSET_ELT_TYPE *scan_rs1_ = (REGSET1); \
+ register REGSET_ELT_TYPE *scan_rs2_ = (REGSET2); \
+ register int i_; \
+ register int shift_ = (MIN) % REGSET_ELT_BITS; \
+ for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++) \
+ { \
+ REGSET_ELT_TYPE word_ = *scan_rs1_++ & *scan_rs2_++; \
+ if (word_) \
+ { \
+ REGSET_ELT_TYPE j_; \
+ REGNUM = (i_ * REGSET_ELT_BITS) + shift_; \
+ for (j_ = ((REGSET_ELT_TYPE)1) << shift_; \
+ j_ != 0; \
+ (j_ <<= 1), REGNUM++) \
+ { \
+ if (word_ & j_) \
+ { \
+ CODE; \
+ word_ &= ~ j_; \
+ if (!word_) \
+ break; \
+ } \
+ } \
+ } \
+ shift_ = 0; \
+ } \
+} while (0)
+
+/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
+ REGNUM to the register number and executing CODE for all registers that are
+ set in the first regset and not set in the second. */
+#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
+do { \
+ register REGSET_ELT_TYPE *scan_rs1_ = (REGSET1); \
+ register REGSET_ELT_TYPE *scan_rs2_ = (REGSET2); \
+ register int i_; \
+ register int shift_ = (MIN) % REGSET_ELT_BITS; \
+ for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++) \
+ { \
+ REGSET_ELT_TYPE word_ = *scan_rs1_++ & ~ *scan_rs2_++; \
+ if (word_) \
+ { \
+ REGSET_ELT_TYPE j_; \
+ REGNUM = (i_ * REGSET_ELT_BITS) + shift_; \
+ for (j_ = ((REGSET_ELT_TYPE)1) << shift_; \
+ j_ != 0; \
+ (j_ <<= 1), REGNUM++) \
+ { \
+ if (word_ & j_) \
+ { \
+ CODE; \
+ word_ &= ~ j_; \
+ if (!word_) \
+ break; \
+ } \
+ } \
+ } \
+ shift_ = 0; \
+ } \
+} while (0)
+
+/* Allocate a register set with oballoc. */
+#define OBALLOC_REG_SET() \
+ ((regset) obstack_alloc (&flow_obstack, regset_bytes))
+
+/* Allocate a register set with alloca. */
+#define ALLOCA_REG_SET() ((regset) alloca (regset_bytes))
+
/* Number of basic blocks in the current function. */
extern int n_basic_blocks;