summaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1994-02-28 13:43:23 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1994-02-28 13:43:23 +0000
commit7f24d2b8d76caa278ae7bc104af7741e5cda2a40 (patch)
tree71bfce3c8b9f494b26086257e0cba9566f518bf8 /gcc/reload1.c
parent33b3d5c97b670a061ccb429b7f9889afb0817ed3 (diff)
downloadgcc-7f24d2b8d76caa278ae7bc104af7741e5cda2a40.tar.gz
(eliminate_regs, case MULT): New case, to apply distributive law, when
needed. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@6676 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c67
1 files changed, 46 insertions, 21 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index ac75a5181e1..90a4573282e 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2800,33 +2800,35 @@ eliminate_regs (x, mem_mode, insn)
}
return x;
- case EXPR_LIST:
- /* If we have something in XEXP (x, 0), the usual case, eliminate it. */
- if (XEXP (x, 0))
- {
- new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
- if (new != XEXP (x, 0))
- x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1));
- }
+ case MULT:
+ /* If this is the product of an eliminable register and a
+ constant, apply the distribute law and move the constant out
+ so that we have (plus (mult ..) ..). This is needed in order
+ to keep load-address insns valid. This case is pathalogical.
+ We ignore the possibility of overflow here. */
+ if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+ ep++)
+ if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
+ {
+ if (! mem_mode
+ /* Refs inside notes don't count for this purpose. */
+ && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
+ || GET_CODE (insn) == INSN_LIST)))
+ ep->ref_outside_mem = 1;
+
+ return
+ plus_constant (gen_rtx (MULT, Pmode, ep->to_rtx, XEXP (x, 1)),
+ ep->previous_offset * INTVAL (XEXP (x, 1)));
+ }
/* ... fall through ... */
- case INSN_LIST:
- /* Now do eliminations in the rest of the chain. If this was
- an EXPR_LIST, this might result in allocating more memory than is
- strictly needed, but it simplifies the code. */
- if (XEXP (x, 1))
- {
- new = eliminate_regs (XEXP (x, 1), mem_mode, insn);
- if (new != XEXP (x, 1))
- return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
- }
- return x;
-
case CALL:
case COMPARE:
case MINUS:
- case MULT:
case DIV: case UDIV:
case MOD: case UMOD:
case AND: case IOR: case XOR:
@@ -2845,6 +2847,29 @@ eliminate_regs (x, mem_mode, insn)
}
return x;
+ case EXPR_LIST:
+ /* If we have something in XEXP (x, 0), the usual case, eliminate it. */
+ if (XEXP (x, 0))
+ {
+ new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
+ if (new != XEXP (x, 0))
+ x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1));
+ }
+
+ /* ... fall through ... */
+
+ case INSN_LIST:
+ /* Now do eliminations in the rest of the chain. If this was
+ an EXPR_LIST, this might result in allocating more memory than is
+ strictly needed, but it simplifies the code. */
+ if (XEXP (x, 1))
+ {
+ new = eliminate_regs (XEXP (x, 1), mem_mode, insn);
+ if (new != XEXP (x, 1))
+ return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
+ }
+ return x;
+
case PRE_INC:
case POST_INC:
case PRE_DEC: