aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2012-08-09 13:18:05 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2012-08-09 13:18:05 +0000
commit82ad0aaf6e6d671b8dab3fd9ae3b496f1c70aea7 (patch)
treedc0e08837a77bf368d263bcde301c676189919de /gcc/reload1.c
parent62d6a5bbc851e99b69cf6899e02ac46e66a3b50c (diff)
downloadgcc-82ad0aaf6e6d671b8dab3fd9ae3b496f1c70aea7.zip
gcc-82ad0aaf6e6d671b8dab3fd9ae3b496f1c70aea7.tar.gz
gcc-82ad0aaf6e6d671b8dab3fd9ae3b496f1c70aea7.tar.bz2
reload.c (find_valid_class_1): New static function.
* reload.c (find_valid_class_1): New static function. (push_reload): Use it when reloading a SYMBOL_REG as the inner of a subreg. Keep better track of needed classes for the secondary memory case. * config/i386/i386.h (LIMIT_RELOAD_CLASS): Limit INT_SSE_REGS to GENERAL_REGS. * reload1.c (replaced_subreg): New static function. (gen_reload): Use it when deciding whether to use secondary memory. * gcc.c-torture/compile/20120727-1.c: New test. From-SVN: r190252
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index e6d3a71..bf5d3d3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -8469,6 +8469,18 @@ emit_insn_if_valid_for_reload (rtx insn)
return NULL;
}
+/* If X is not a subreg, return it unmodified. If it is a subreg,
+ look up whether we made a replacement for the SUBREG_REG. Return
+ either the replacement or the SUBREG_REG. */
+
+static rtx
+replaced_subreg (rtx x)
+{
+ if (GET_CODE (x) == SUBREG)
+ return find_replacement (&SUBREG_REG (x));
+ return x;
+}
+
/* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE.
@@ -8479,7 +8491,7 @@ static rtx
gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
{
rtx last = get_last_insn ();
- rtx tem;
+ rtx tem, tem1, tem2;
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
@@ -8616,14 +8628,12 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
#ifdef SECONDARY_MEMORY_NEEDED
/* If we need a memory location to do the move, do it that way. */
- else if ((REG_P (in)
- || (GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))))
- && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
- && (REG_P (out)
- || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
- && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
- && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
- REGNO_REG_CLASS (reg_or_subregno (out)),
+ else if ((tem1 = replaced_subreg (in), tem2 = replaced_subreg (out),
+ (REG_P (tem1) && REG_P (tem2)))
+ && REGNO (tem1) < FIRST_PSEUDO_REGISTER
+ && REGNO (tem2) < FIRST_PSEUDO_REGISTER
+ && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem1)),
+ REGNO_REG_CLASS (REGNO (tem2)),
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */