diff options
author | synergydev <synergye@codefi.re> | 2013-10-17 18:16:42 -0700 |
---|---|---|
committer | synergydev <synergye@codefi.re> | 2013-10-17 18:16:42 -0700 |
commit | 61c0330cc243abf13fdd01f377a7f80bd3989eb1 (patch) | |
tree | 119b08ae76294f23e2b1b7e72ff9a06afa9e8509 /gcc-4.8/gcc/recog.c | |
parent | 1c712bf7621f3859c33fd3afaa61fdcaf3fdfd76 (diff) | |
download | toolchain_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.c | 84 |
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); |