aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1997-01-21 17:15:54 +0000
committerDoug Evans <dje@gnu.org>1997-01-21 17:15:54 +0000
commita12f68f4f21713eab33d5adb8c538d1e3a822464 (patch)
treef46252d0d92d72617c4cff7d3bf736a77fdfb44f /gcc
parente454beb74e176e1f4bff5b2980e646da38af0baf (diff)
downloadgcc-a12f68f4f21713eab33d5adb8c538d1e3a822464.zip
gcc-a12f68f4f21713eab33d5adb8c538d1e3a822464.tar.gz
gcc-a12f68f4f21713eab33d5adb8c538d1e3a822464.tar.bz2
reload1.c (eliminate_regs, case MINUS): Canonicalize (minus (plus reg const) reg) to (plus (minus reg reg) const).
* reload1.c (eliminate_regs, case MINUS): Canonicalize (minus (plus reg const) reg) to (plus (minus reg reg) const). * reload.c (find_reloads_address): Treat (plus (minus reg reg) const) the same as (plus (plus reg reg) const). From-SVN: r13539
Diffstat (limited to 'gcc')
-rw-r--r--gcc/reload.c12
-rw-r--r--gcc/reload1.c25
2 files changed, 32 insertions, 5 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 5bb39dc..e1f5f91 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4368,7 +4368,9 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
/* If we have an indexed stack slot, there are three possible reasons why
it might be invalid: The index might need to be reloaded, the address
might have been made by frame pointer elimination and hence have a
- constant out of range, or both reasons might apply.
+ constant out of range, or the address is the result of register
+ elimination and (plus (plus reg reg) const), which has been
+ canonicalized from (plus (plus reg const) reg), isn't a valid address.
We can easily check for an index needing reload, but even if that is the
case, we might also have an invalid constant. To avoid making the
@@ -4395,7 +4397,11 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
innermost PLUS. */
else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
- && GET_CODE (XEXP (ad, 0)) == PLUS
+ && (GET_CODE (XEXP (ad, 0)) == PLUS
+ /* MINUS can happen as a result of register elimination of
+ (minus eliminable reg) which gets canonicalized as
+ (plus (minus reg reg) const). */
+ || GET_CODE (XEXP (ad, 0)) == MINUS)
&& (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
|| XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
@@ -4406,7 +4412,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
|| XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
&& ! memory_address_p (mode, ad))
{
- *loc = ad = gen_rtx (PLUS, GET_MODE (ad),
+ *loc = ad = gen_rtx (GET_CODE (XEXP (ad, 0)), GET_MODE (ad),
plus_constant (XEXP (XEXP (ad, 0), 0),
INTVAL (XEXP (ad, 1))),
XEXP (XEXP (ad, 0), 1));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index b5e9394..d4f2140 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2853,7 +2853,7 @@ eliminate_regs (x, mem_mode, insn)
context.
If we have (plus (eliminable) (reg)), we want to produce
- (plus (plus (replacement) (reg) (const))). If this was part of a
+ (plus (plus (replacement) (reg)) (const)). If this was part of a
normal add insn, (plus (replacement) (reg)) will be pushed as a
reload. This is the desired action. */
@@ -2892,6 +2892,28 @@ eliminate_regs (x, mem_mode, insn)
}
return x;
+ case MINUS:
+ /* If we have (minus (eliminable) (reg)), we want to produce
+ (plus (minus (replacement) (reg)) (const)). The main reason being
+ to be consistent with what is done for PLUS. find_reloads_address
+ assumes that we do this. */
+ {
+ rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
+ rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
+
+ if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
+ {
+ if (GET_CODE (new0) == PLUS)
+ return gen_rtx (PLUS, GET_MODE (x),
+ gen_rtx (MINUS, GET_MODE (x),
+ XEXP (new0, 0), new1),
+ XEXP (new0, 1));
+ else
+ return gen_rtx (MINUS, GET_MODE (x), new0, new1);
+ }
+ }
+ return x;
+
case MULT:
/* If this is the product of an eliminable register and a
constant, apply the distribute law and move the constant out
@@ -2920,7 +2942,6 @@ eliminate_regs (x, mem_mode, insn)
case CALL:
case COMPARE:
- case MINUS:
case DIV: case UDIV:
case MOD: case UMOD:
case AND: case IOR: case XOR: