summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-20 23:34:10 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-20 23:34:10 +0000
commitf25bee5a48a12a3a55c9b911c549e8d0b64d6a7d (patch)
tree9fbd6951ec335b2e9c4bc5c74e765668d5ee5d8d /gcc/reload.c
parentba453b31f7e8c5b8ea6628512d7d8a5f6464fad8 (diff)
downloadgcc-f25bee5a48a12a3a55c9b911c549e8d0b64d6a7d.tar.gz
* reload.c (find_reloads_address): Reload the sum of a LO_SUM and
a CONST_INT. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@86342 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c102
1 files changed, 53 insertions, 49 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index b114dc2b148..715e58fa127 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4647,6 +4647,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
{
int regno;
int removed_and = 0;
+ int op_index;
rtx tem;
/* If the address is a register, see if it is a legitimate address and
@@ -4892,7 +4893,9 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
Handle all base registers here, not just fp/ap/sp, because on some
targets (namely SPARC) we can also get invalid addresses from preventive
- subreg big-endian corrections made by find_reloads_toplev.
+ subreg big-endian corrections made by find_reloads_toplev. We
+ can also get expressions involving LO_SUM (rather than PLUS) from
+ find_reloads_subreg_address.
If we decide to do something, it must be that `double_reg_address_ok'
is true. We generate a reload of the base register + constant and
@@ -4900,62 +4903,63 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
This is safe because we know the address isn't shared.
We check for the base register as both the first and second operand of
- the innermost PLUS. */
-
- else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
- && GET_CODE (XEXP (ad, 0)) == PLUS
- && REG_P (XEXP (XEXP (ad, 0), 0))
- && REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER
- && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
- || 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
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
-#endif
- || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
- && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 1)))
+ the innermost PLUS and/or LO_SUM. */
+
+ for (op_index = 0; op_index < 2; ++op_index)
{
- *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
- plus_constant (XEXP (XEXP (ad, 0), 0),
- INTVAL (XEXP (ad, 1))),
- XEXP (XEXP (ad, 0), 1));
- find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
- MODE_BASE_REG_CLASS (mode),
- GET_MODE (ad), opnum, type, ind_levels);
- find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
- type, 0, insn);
+ rtx operand;
- return 0;
- }
+ if (!(GET_CODE (ad) == PLUS
+ && GET_CODE (XEXP (ad, 1)) == CONST_INT
+ && (GET_CODE (XEXP (ad, 0)) == PLUS
+ || GET_CODE (XEXP (ad, 0)) == LO_SUM)))
+ continue;
- else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
- && GET_CODE (XEXP (ad, 0)) == PLUS
- && REG_P (XEXP (XEXP (ad, 0), 1))
- && REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER
- && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
- || XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
+ operand = XEXP (XEXP (ad, 0), op_index);
+ if (!(REG_P (operand)
+ || REGNO (operand) < FIRST_PSEUDO_REGISTER))
+ continue;
+
+ if ((REG_MODE_OK_FOR_BASE_P (operand, mode)
+ || operand == frame_pointer_rtx
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
+ || operand == hard_frame_pointer_rtx
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
+ || operand == arg_pointer_rtx
#endif
- || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
- && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 0)))
- {
- *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
- XEXP (XEXP (ad, 0), 0),
- plus_constant (XEXP (XEXP (ad, 0), 1),
- INTVAL (XEXP (ad, 1))));
- find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
- MODE_BASE_REG_CLASS (mode),
- GET_MODE (ad), opnum, type, ind_levels);
- find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
- type, 0, insn);
+ || operand == stack_pointer_rtx)
+ && ! maybe_memory_address_p (mode, ad,
+ &XEXP (XEXP (ad, 0), op_index)))
+ {
+ rtx offset_reg;
+ rtx addend;
+
+ offset_reg = plus_constant (operand, INTVAL (XEXP (ad, 1)));
+ addend = XEXP (XEXP (ad, 0), 1 - op_index);
+
+ /* Form the adjusted address. */
+ if (GET_CODE (XEXP (ad, 0)) == PLUS)
+ ad = gen_rtx_PLUS (GET_MODE (ad),
+ op_index == 0 ? offset_reg : addend,
+ op_index == 0 ? addend : offset_reg);
+ else
+ ad = gen_rtx_LO_SUM (GET_MODE (ad),
+ op_index == 0 ? offset_reg : addend,
+ op_index == 0 ? addend : offset_reg);
+ *loc = ad;
+
+ find_reloads_address_part (XEXP (ad, op_index),
+ &XEXP (ad, op_index),
+ MODE_BASE_REG_CLASS (mode),
+ GET_MODE (ad), opnum, type, ind_levels);
+ find_reloads_address_1 (mode,
+ XEXP (ad, 1 - op_index), 1,
+ &XEXP (ad, 1 - op_index), opnum,
+ type, 0, insn);
- return 0;
+ return 0;
+ }
}
/* See if address becomes valid when an eliminable register