diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-06-05 10:24:03 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-06-05 10:24:03 +0000 |
commit | 74666a14ff398025a5a35f0bf1c6480d7ee9e6a6 (patch) | |
tree | 619a5e6cc2340785ce05f2bf95307154e057626d /gcc/basic-block.h | |
parent | 97906c21abfa1666acb2fdc5106483d525b70cde (diff) | |
download | gcc-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.h | 221 |
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; |