aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/recog.c
diff options
context:
space:
mode:
authorsynergydev <synergye@codefi.re>2013-10-17 18:16:42 -0700
committersynergydev <synergye@codefi.re>2013-10-17 18:16:42 -0700
commit61c0330cc243abf13fdd01f377a7f80bd3989eb1 (patch)
tree119b08ae76294f23e2b1b7e72ff9a06afa9e8509 /gcc-4.8/gcc/recog.c
parent1c712bf7621f3859c33fd3afaa61fdcaf3fdfd76 (diff)
downloadtoolchain_gcc-61c0330cc243abf13fdd01f377a7f80bd3989eb1.tar.gz
toolchain_gcc-61c0330cc243abf13fdd01f377a7f80bd3989eb1.tar.bz2
toolchain_gcc-61c0330cc243abf13fdd01f377a7f80bd3989eb1.zip
[4.8] Merge GCC 4.8.2
Change-Id: I0f1fcf69c5076d8534c5c45562745e1a37adb197
Diffstat (limited to 'gcc-4.8/gcc/recog.c')
-rw-r--r--gcc-4.8/gcc/recog.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/gcc-4.8/gcc/recog.c b/gcc-4.8/gcc/recog.c
index ed359f672..f00859cf0 100644
--- a/gcc-4.8/gcc/recog.c
+++ b/gcc-4.8/gcc/recog.c
@@ -1949,9 +1949,6 @@ offsettable_address_addr_space_p (int strictp, enum machine_mode mode, rtx y,
(strictp ? strict_memory_address_addr_space_p
: memory_address_addr_space_p);
unsigned int mode_sz = GET_MODE_SIZE (mode);
-#ifdef POINTERS_EXTEND_UNSIGNED
- enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
-#endif
if (CONSTANT_ADDRESS_P (y))
return 1;
@@ -1962,6 +1959,13 @@ offsettable_address_addr_space_p (int strictp, enum machine_mode mode, rtx y,
if (mode_dependent_address_p (y, as))
return 0;
+ enum machine_mode address_mode = GET_MODE (y);
+ if (address_mode == VOIDmode)
+ address_mode = targetm.addr_space.address_mode (as);
+#ifdef POINTERS_EXTEND_UNSIGNED
+ enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+#endif
+
/* ??? How much offset does an offsettable BLKmode reference need?
Clearly that depends on the situation in which it's being used.
However, the current situation in which we test 0xffffffff is
@@ -1977,7 +1981,7 @@ offsettable_address_addr_space_p (int strictp, enum machine_mode mode, rtx y,
int good;
y1 = *y2;
- *y2 = plus_constant (GET_MODE (y), *y2, mode_sz - 1);
+ *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
/* Use QImode because an odd displacement may be automatically invalid
for any wider mode. But it should be valid for a single byte. */
good = (*addressp) (QImode, y, as);
@@ -1998,20 +2002,20 @@ offsettable_address_addr_space_p (int strictp, enum machine_mode mode, rtx y,
if (GET_CODE (y) == LO_SUM
&& mode != BLKmode
&& mode_sz <= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT)
- z = gen_rtx_LO_SUM (GET_MODE (y), XEXP (y, 0),
- plus_constant (GET_MODE (y), XEXP (y, 1),
+ z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
+ plus_constant (address_mode, XEXP (y, 1),
mode_sz - 1));
#ifdef POINTERS_EXTEND_UNSIGNED
/* Likewise for a ZERO_EXTEND from pointer_mode. */
else if (POINTERS_EXTEND_UNSIGNED > 0
&& GET_CODE (y) == ZERO_EXTEND
&& GET_MODE (XEXP (y, 0)) == pointer_mode)
- z = gen_rtx_ZERO_EXTEND (GET_MODE (y),
+ z = gen_rtx_ZERO_EXTEND (address_mode,
plus_constant (pointer_mode, XEXP (y, 0),
mode_sz - 1));
#endif
else
- z = plus_constant (GET_MODE (y), y, mode_sz - 1);
+ z = plus_constant (address_mode, y, mode_sz - 1);
/* Use QImode because an odd displacement may be automatically invalid
for any wider mode. But it should be valid for a single byte. */
@@ -3116,32 +3120,53 @@ peep2_find_free_register (int from, int to, const char *class_str,
regno = raw_regno;
#endif
- /* Don't allocate fixed registers. */
- if (fixed_regs[regno])
- continue;
- /* Don't allocate global registers. */
- if (global_regs[regno])
- continue;
- /* Make sure the register is of the right class. */
- if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno))
- continue;
- /* And can support the mode we need. */
+ /* Can it support the mode we need? */
if (! HARD_REGNO_MODE_OK (regno, mode))
continue;
- /* And that we don't create an extra save/restore. */
- if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno))
- continue;
- if (! targetm.hard_regno_scratch_ok (regno))
- continue;
-
- /* And we don't clobber traceback for noreturn functions. */
- if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM)
- && (! reload_completed || frame_pointer_needed))
- continue;
success = 1;
- for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--)
+ for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++)
{
+ /* Don't allocate fixed registers. */
+ if (fixed_regs[regno + j])
+ {
+ success = 0;
+ break;
+ }
+ /* Don't allocate global registers. */
+ if (global_regs[regno + j])
+ {
+ success = 0;
+ break;
+ }
+ /* Make sure the register is of the right class. */
+ if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
+ {
+ success = 0;
+ break;
+ }
+ /* And that we don't create an extra save/restore. */
+ if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j))
+ {
+ success = 0;
+ break;
+ }
+
+ if (! targetm.hard_regno_scratch_ok (regno + j))
+ {
+ success = 0;
+ break;
+ }
+
+ /* And we don't clobber traceback for noreturn functions. */
+ if ((regno + j == FRAME_POINTER_REGNUM
+ || regno + j == HARD_FRAME_POINTER_REGNUM)
+ && (! reload_completed || frame_pointer_needed))
+ {
+ success = 0;
+ break;
+ }
+
if (TEST_HARD_REG_BIT (*reg_set, regno + j)
|| TEST_HARD_REG_BIT (live, regno + j))
{
@@ -3149,6 +3174,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
break;
}
}
+
if (success)
{
add_to_hard_reg_set (reg_set, mode, regno);