#include "params.h"
#include "target.h"
-#ifndef REGNO_MODE_OK_FOR_BASE_P
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
-#endif
-
-#ifndef REG_MODE_OK_FOR_BASE_P
-#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
-#endif
-
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
(CONSTANT_P (X) \
mode = outmode;
if (mode == VOIDmode)
{
- error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
+ error_for_asm (this_insn, "cannot reload integer constant "
+ "operand in %<asm%>");
mode = word_mode;
if (in != 0)
inmode = word_mode;
}
if (i == FIRST_PSEUDO_REGISTER)
{
- error_for_asm (this_insn, "impossible register constraint in `asm'");
+ error_for_asm (this_insn, "impossible register constraint "
+ "in %<asm%>");
class = ALL_REGS;
}
}
this_alternative_earlyclobber[i] = 0;
gcc_assert (this_insn_is_asm);
error_for_asm (this_insn,
- "`&' constraint used with no register class");
+ "%<&%> constraint used with no register class");
}
for (j = 0; j < noperands; j++)
/* No alternative works with reloads?? */
if (insn_code_number >= 0)
fatal_insn ("unable to generate reloads for:", insn);
- error_for_asm (insn, "inconsistent operand constraints in an `asm'");
+ error_for_asm (insn, "inconsistent operand constraints in an %<asm%>");
/* Avoid further trouble with this insn. */
PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
n_reloads = 0;
goal_alternative_win[i] = 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);
+
+ substed_operand[i] = recog_data.operand[i]
+ = find_reloads_toplev (tem, i, address_type[i],
+ ind_levels, 0, insn, NULL);
+ }
+
/* Record the values of the earlyclobber operands for the caller. */
if (goal_earlyclobber)
for (i = 0; i < noperands; i++)
else
{
gcc_assert (insn_code_number < 0);
- error_for_asm (insn, "inconsistent operand constraints in an `asm'");
+ error_for_asm (insn, "inconsistent operand constraints "
+ "in an %<asm%>");
/* Avoid further trouble with this insn. */
PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
n_reloads = 0;
is strictly valid.)
CONTEXT = 1 means we are considering regs as index regs,
- = 0 means we are considering them as base regs.
+ = 0 means we are considering them as base regs, = 2 means we
+ are considering them as base regs for REG + REG.
OPNUM and TYPE specify the purpose of any reloads made.
rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx insn)
{
+#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE) \
+ ((CONTEXT) == 2 \
+ ? REGNO_MODE_OK_FOR_REG_BASE_P (REGNO, MODE) \
+ : (CONTEXT) == 1 \
+ ? REGNO_OK_FOR_INDEX_P (REGNO) \
+ : REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE))
+
+ enum reg_class context_reg_class;
RTX_CODE code = GET_CODE (x);
+ if (context == 2)
+ context_reg_class = MODE_BASE_REG_REG_CLASS (mode);
+ else if (context == 1)
+ context_reg_class = INDEX_REG_CLASS;
+ else
+ context_reg_class = MODE_BASE_REG_CLASS (mode);
+
switch (code)
{
case PLUS:
register remateralization for expression like &localvar*4. Reload it.
It may be possible to combine the displacement on the outer level,
but it is probably not worthwhile to do so. */
- if (context)
+ if (context == 1)
{
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
else if (code0 == REG && code1 == REG)
{
if (REG_OK_FOR_INDEX_P (op0)
- && REG_MODE_OK_FOR_BASE_P (op1, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
return 0;
else if (REG_OK_FOR_INDEX_P (op1)
- && REG_MODE_OK_FOR_BASE_P (op0, mode))
+ && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
return 0;
- else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels, insn);
- else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
+ else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op1))
- find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
+ find_reloads_address_1 (mode, orig_op0, 2, &XEXP (x, 0), opnum,
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op0))
- find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
+ find_reloads_address_1 (mode, orig_op1, 2, &XEXP (x, 1), opnum,
type, ind_levels, insn);
else
{
if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno];
- if ((regno >= FIRST_PSEUDO_REGISTER
- || !(context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+ if (regno >= FIRST_PSEUDO_REGISTER
+ || !REG_OK_FOR_CONTEXT (context, regno, mode))
{
int reloadnum;
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
}
{
reloadnum
= push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type);
rld[reloadnum].inc
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
rld[reloadnum].inc
= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
if (reg_equiv_constant[regno] != 0)
{
find_reloads_address_part (reg_equiv_constant[regno], loc,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), opnum, type, ind_levels);
return 1;
}
if (reg_equiv_mem[regno] != 0)
{
push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno];
- if ((regno >= FIRST_PSEUDO_REGISTER
- || !(context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+ if (regno >= FIRST_PSEUDO_REGISTER
+ || !REG_OK_FOR_CONTEXT (context, regno, mode))
{
push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
{
push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
{
int regno ATTRIBUTE_UNUSED = subreg_regno (x);
- if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
+ if (! REG_OK_FOR_CONTEXT (context, regno, mode))
{
push_reload (x, NULL_RTX, loc, (rtx*) 0,
- (context ? INDEX_REG_CLASS :
- MODE_BASE_REG_CLASS (mode)),
+ context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
is larger than the class size, then reload the whole SUBREG. */
else
{
- enum reg_class class = (context ? INDEX_REG_CLASS
- : MODE_BASE_REG_CLASS (mode));
+ enum reg_class class = context_reg_class;
if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class])
{
}
}
+#undef REG_OK_FOR_CONTEXT
return 0;
}
\f