aboutsummaryrefslogtreecommitdiff
path: root/gcc/reginfo.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2011-11-27 10:09:15 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2011-11-27 10:09:15 +0000
commit006b72bffc64518d4e486982c548ec831dae2392 (patch)
tree550c92021f891ad0b45cc382f700d0d14027acd1 /gcc/reginfo.c
parenta58371f313034981ebdcdbd6e7604a41df281a00 (diff)
downloadgcc-006b72bffc64518d4e486982c548ec831dae2392.zip
gcc-006b72bffc64518d4e486982c548ec831dae2392.tar.gz
gcc-006b72bffc64518d4e486982c548ec831dae2392.tar.bz2
hard-reg-set.h (target_hard_regs): Add x_accessible_reg_set and x_operand_reg_set.
gcc/ * hard-reg-set.h (target_hard_regs): Add x_accessible_reg_set and x_operand_reg_set. (accessible_reg_set, operand_reg_set): New macros. * reginfo.c (init_reg_sets): Initialize accessible_reg_set and operand_reg_set. (saved_accessible_reg_set, saved_operand_reg_set): New variables. (save_register_info): Save them. (restore_register_info): Restore them. (init_reg_sets_1): Limit operand_reg_set to accessible_reg_set. Remove NO_REGS registers from operand_reg_set. Treat members of operand_reg_set as fixed. * recog.c (general_operand): Check operand_reg_set rather than NO_REGS. (register_operand, nonmemory_operand): Likewise. * varasm.c (make_decl_rtl): Always use DECL_MODE as the mode of register variables. Check accessible_reg_set and operand_reg_set. * config/mips/mips.c (mips_conditional_register_usage): Remove inaccessible register from accessible_reg_set, rather than just making them fixed. gcc/testsuite/ * gcc.target/mips/mips.exp (mips-dg-options): Make -mno-dsp imply -mno-dspr2. * gcc.target/mips/no-dsp-1.c: New test. * gcc.target/mips/soft-float-1.c: Likewise. From-SVN: r181760
Diffstat (limited to 'gcc/reginfo.c')
-rw-r--r--gcc/reginfo.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index e9bf65f..f6f91a9 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -192,6 +192,9 @@ init_reg_sets (void)
memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order);
#endif
memcpy (reg_names, initial_reg_names, sizeof reg_names);
+
+ SET_HARD_REG_SET (accessible_reg_set);
+ SET_HARD_REG_SET (operand_reg_set);
}
/* Initialize may_move_cost and friends for mode M. */
@@ -292,6 +295,8 @@ static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER];
#endif
static const char *saved_reg_names[FIRST_PSEUDO_REGISTER];
+static HARD_REG_SET saved_accessible_reg_set;
+static HARD_REG_SET saved_operand_reg_set;
/* Save the register information. */
void
@@ -315,6 +320,8 @@ save_register_info (void)
/* And similarly for reg_names. */
gcc_assert (sizeof reg_names == sizeof saved_reg_names);
memcpy (saved_reg_names, reg_names, sizeof reg_names);
+ COPY_HARD_REG_SET (saved_accessible_reg_set, accessible_reg_set);
+ COPY_HARD_REG_SET (saved_operand_reg_set, operand_reg_set);
}
/* Restore the register information. */
@@ -330,6 +337,8 @@ restore_register_info (void)
#endif
memcpy (reg_names, saved_reg_names, sizeof reg_names);
+ COPY_HARD_REG_SET (accessible_reg_set, saved_accessible_reg_set);
+ COPY_HARD_REG_SET (operand_reg_set, saved_operand_reg_set);
}
/* After switches have been processed, which perhaps alter
@@ -459,8 +468,27 @@ init_reg_sets_1 (void)
else
CLEAR_REG_SET (fixed_reg_set_regset);
+ AND_HARD_REG_SET (operand_reg_set, accessible_reg_set);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
+ /* As a special exception, registers whose class is NO_REGS are
+ not accepted by `register_operand'. The reason for this change
+ is to allow the representation of special architecture artifacts
+ (such as a condition code register) without extending the rtl
+ definitions. Since registers of class NO_REGS cannot be used
+ as registers in any case where register classes are examined,
+ it is better to apply this exception in a target-independent way. */
+ if (REGNO_REG_CLASS (i) == NO_REGS)
+ CLEAR_HARD_REG_BIT (operand_reg_set, i);
+
+ /* If a register is too limited to be treated as a register operand,
+ then it should never be allocated to a pseudo. */
+ if (!TEST_HARD_REG_BIT (operand_reg_set, i))
+ {
+ fixed_regs[i] = 1;
+ call_used_regs[i] = 1;
+ }
+
/* call_used_regs must include fixed_regs. */
gcc_assert (!fixed_regs[i] || call_used_regs[i]);
#ifdef CALL_REALLY_USED_REGISTERS