aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel1@de.ibm.com>2008-08-06 06:51:11 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2008-08-06 06:51:11 +0000
commite0a17959335723628c929e5feefbe964249f4fb6 (patch)
tree0813ab73429e00265c8dc79f46b2a719a885ac7b /gcc/reload.c
parentc275297bdd09468bb84ab839e89f585ca9541fee (diff)
downloadgcc-e0a17959335723628c929e5feefbe964249f4fb6.zip
gcc-e0a17959335723628c929e5feefbe964249f4fb6.tar.gz
gcc-e0a17959335723628c929e5feefbe964249f4fb6.tar.bz2
reload.c (find_reloads): Force constants into literal pool also if they are wrapped in a SUBREG.
2008-08-06 Andreas Krebbel <krebbel1@de.ibm.com> * reload.c (find_reloads): Force constants into literal pool also if they are wrapped in a SUBREG. 2008-08-06 Andreas Krebbel <krebbel1@de.ibm.com> * gcc.c-torture/compile/20080806-1.c: New testcase. From-SVN: r138763
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index a6ea4ff..93fff404 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -3843,49 +3843,61 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* Any constants that aren't allowed and can't be reloaded
into registers are here changed into memory references. */
for (i = 0; i < noperands; i++)
- if (! goal_alternative_win[i]
- && CONST_POOL_OK_P (recog_data.operand[i])
- && ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
- (enum reg_class) goal_alternative[i])
- == NO_REGS)
- || no_input_reloads)
- && operand_mode[i] != VOIDmode)
+ if (! goal_alternative_win[i])
{
- int this_address_reloaded;
+ rtx op = recog_data.operand[i];
+ rtx subreg = NULL_RTX;
+ rtx plus = NULL_RTX;
+ enum machine_mode mode = operand_mode[i];
+
+ /* Reloads of SUBREGs of CONSTANT RTXs are handled later in
+ push_reload so we have to let them pass here. */
+ if (GET_CODE (op) == SUBREG)
+ {
+ subreg = op;
+ op = SUBREG_REG (op);
+ mode = GET_MODE (op);
+ }
- this_address_reloaded = 0;
- substed_operand[i] = recog_data.operand[i]
- = find_reloads_toplev (force_const_mem (operand_mode[i],
- recog_data.operand[i]),
- i, address_type[i], ind_levels, 0, insn,
- &this_address_reloaded);
- if (alternative_allows_const_pool_ref (this_address_reloaded == 0
- ? substed_operand[i]
- : NULL,
- recog_data.constraints[i],
- goal_alternative_number))
- goal_alternative_win[i] = 1;
- }
+ if (GET_CODE (op) == PLUS)
+ {
+ plus = op;
+ op = XEXP (op, 1);
+ }
- /* Likewise any invalid constants appearing as operand of a PLUS
- that is to be reloaded. */
- for (i = 0; i < noperands; i++)
- if (! goal_alternative_win[i]
- && GET_CODE (recog_data.operand[i]) == PLUS
- && CONST_POOL_OK_P (XEXP (recog_data.operand[i], 1))
- && (PREFERRED_RELOAD_CLASS (XEXP (recog_data.operand[i], 1),
- (enum reg_class) goal_alternative[i])
- == NO_REGS)
- && operand_mode[i] != VOIDmode)
- {
- rtx tem = force_const_mem (operand_mode[i],
- XEXP (recog_data.operand[i], 1));
- tem = gen_rtx_PLUS (operand_mode[i],
- XEXP (recog_data.operand[i], 0), tem);
+ if (CONST_POOL_OK_P (op)
+ && ((PREFERRED_RELOAD_CLASS (op,
+ (enum reg_class) goal_alternative[i])
+ == NO_REGS)
+ || no_input_reloads)
+ && mode != VOIDmode)
+ {
+ int this_address_reloaded;
+ rtx tem = force_const_mem (mode, op);
- substed_operand[i] = recog_data.operand[i]
- = find_reloads_toplev (tem, i, address_type[i],
- ind_levels, 0, insn, NULL);
+ /* If we stripped a SUBREG or a PLUS above add it back. */
+ if (plus != NULL_RTX)
+ tem = gen_rtx_PLUS (mode, XEXP (plus, 0), tem);
+
+ if (subreg != NULL_RTX)
+ tem = gen_rtx_SUBREG (operand_mode[i], tem, SUBREG_BYTE (subreg));
+
+ this_address_reloaded = 0;
+ substed_operand[i] = recog_data.operand[i]
+ = find_reloads_toplev (tem, i, address_type[i], ind_levels,
+ 0, insn, &this_address_reloaded);
+
+ /* If the alternative accepts constant pool refs directly
+ there will be no reload needed at all. */
+ if (plus == NULL_RTX
+ && subreg == NULL_RTX
+ && alternative_allows_const_pool_ref (this_address_reloaded == 0
+ ? substed_operand[i]
+ : NULL,
+ recog_data.constraints[i],
+ goal_alternative_number))
+ goal_alternative_win[i] = 1;
+ }
}
/* Record the values of the earlyclobber operands for the caller. */