#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "rtl.h"
+#include "rtl-error.h"
#include "tm_p.h"
#include "insn-config.h"
#include "expr.h"
#include "optabs.h"
#include "recog.h"
+#include "df.h"
#include "reload.h"
#include "regs.h"
#include "addresses.h"
#include "hard-reg-set.h"
#include "flags.h"
-#include "real.h"
#include "output.h"
#include "function.h"
-#include "toplev.h"
#include "params.h"
#include "target.h"
-#include "df.h"
#include "ira.h"
+#include "toplev.h" /* exact_log2 may be used by targets */
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
sri.icode = CODE_FOR_nothing;
sri.prev_sri = prev_sri;
- rclass = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
+ rclass = (enum reg_class) targetm.secondary_reload (in_p, x, reload_class,
+ reload_mode, &sri);
icode = (enum insn_code) sri.icode;
/* If we don't need any secondary registers, done. */
|| (! in_p && rld[s_reload].secondary_out_reload == t_reload))
&& ((in_p && rld[s_reload].secondary_in_icode == t_icode)
|| (! in_p && rld[s_reload].secondary_out_icode == t_icode))
- && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass)
+ || targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
opnum, rld[s_reload].opnum))
{
sri.icode = CODE_FOR_nothing;
sri.prev_sri = NULL;
- rclass = targetm.secondary_reload (in_p, x, rclass, mode, &sri);
+ rclass
+ = (enum reg_class) targetm.secondary_reload (in_p, x, rclass, mode, &sri);
icode = (enum insn_code) sri.icode;
/* If there are no secondary reloads at all, we return NO_REGS.
if (bad || !good)
continue;
- cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class);
+ cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);
if ((reg_class_size[rclass] > best_size
&& (best_cost < 0 || best_cost >= cost))
{
best_class = (enum reg_class) rclass;
best_size = reg_class_size[rclass];
- best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass,
+ best_cost = register_move_cost (outer, (enum reg_class) rclass,
dest_class);
}
}
and the other is at worst neutral.
(A zero compared against anything is neutral.)
- If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
- for the same thing since that can cause us to need more reload registers
- than we otherwise would. */
+ For targets with small register classes, don't use existing reloads
+ unless they are for the same thing since that can cause us to need
+ more reload registers than we otherwise would. */
for (i = 0; i < n_reloads; i++)
if ((reg_class_subset_p (rclass, rld[i].rclass)
|| (out != 0 && MATCHES (rld[i].out, out)
&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass)
+ || targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
return i;
&& GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
&& MATCHES (XEXP (in, 0), rld[i].in)))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass)
+ || targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed,
opnum, rld[i].opnum))
{
Returning zero here ought to be safe as we take care in
find_reloads to not process the reloads when instruction was
replaced by USE. */
-
+
return 0;
}
}
|| rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
#endif
- && (SMALL_REGISTER_CLASSES
+ && (targetm.small_register_classes_for_mode_p (VOIDmode)
? (rld[i].rclass == rld[output_reload].rclass)
: (reg_class_subset_p (rld[i].rclass,
rld[output_reload].rclass)
&& ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
rld[i].when_needed != RELOAD_FOR_INPUT)
&& (reg_class_size[(int) rld[i].rclass]
- || SMALL_REGISTER_CLASSES)
+ || targetm.small_register_classes_for_mode_p (VOIDmode))
/* We will allow making things slightly worse by combining an
input and an output, but no worse than that. */
&& (rld[i].when_needed == RELOAD_FOR_INPUT
{
rtx base = NULL_RTX, offset = 0;
rtx addr = XEXP (x, 0);
-
+
if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
|| GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
{
val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
return val;
}
-
+
if (GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
{
if (GET_CODE (XEXP (addr, 1)) == PLUS
return val;
}
}
-
+
if (GET_CODE (addr) == CONST)
{
addr = XEXP (addr, 0);
offset = XEXP (addr, 1);
}
}
-
+
if (offset == 0)
{
base = addr;
base = gen_rtx_PLUS (GET_MODE (base), base, offset);
offset = const0_rtx;
}
-
+
if (all_const && GET_CODE (base) == PLUS)
base = gen_rtx_CONST (GET_MODE (base), base);
-
+
gcc_assert (CONST_INT_P (offset));
-
+
val.start = INTVAL (offset);
val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
val.base = base;
}
break;
-
+
case REG:
val.reg_flag = 1;
val.start = true_regnum (x);
a register. */
enum reg_class preferred_class[MAX_RECOG_OPERANDS];
char pref_or_nothing[MAX_RECOG_OPERANDS];
- /* Nonzero for a MEM operand whose entire address needs a reload.
+ /* Nonzero for a MEM operand whose entire address needs a reload.
May be -1 to indicate the entire address may or may not need a reload. */
int address_reloaded[MAX_RECOG_OPERANDS];
/* Nonzero for an address operand that needs to be completely reloaded.
char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int goal_alternative_swapped;
int best;
- int best_small_class_operands_num;
int commutative;
char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
rtx substed_operand[MAX_RECOG_OPERANDS];
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
&& REG_P (SET_SRC (body))
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
- && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
+ && register_move_cost (GET_MODE (SET_SRC (body)),
REGNO_REG_CLASS (REGNO (SET_SRC (body))),
REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
return 0;
all the operands together against the register constraints. */
best = MAX_RECOG_OPERANDS * 2 + 600;
- best_small_class_operands_num = 0;
swapped = 0;
goal_alternative_swapped = 0;
/* If this operand could be handled with a reg,
and some reg is allowed, then this operand can be handled. */
- if (winreg && this_alternative[i] != NO_REGS)
+ if (winreg && this_alternative[i] != NO_REGS
+ && (win || !class_only_fixed_regs[this_alternative[i]]))
badop = 0;
/* Record which operands fit this alternative. */
|| modified[j] != RELOAD_WRITE)
&& j != i
/* Ignore things like match_operator operands. */
- && *recog_data.constraints[j] != 0
+ && !recog_data.is_operator[j]
/* Don't count an input operand that is constrained to match
the early clobber operand. */
&& ! (this_alternative_matches[j] == i
record it as the chosen goal for reloading. */
if (! bad)
{
- bool change_p = false;
- int small_class_operands_num = 0;
-
- if (best >= losers)
- {
- for (i = 0; i < noperands; i++)
- small_class_operands_num
- += SMALL_REGISTER_CLASS_P (this_alternative[i]) ? 1 : 0;
- if (best > losers
- || (best == losers
- /* If the cost of the reloads is the same,
- prefer alternative which requires minimal
- number of small register classes for the
- operands. This improves chances of reloads
- for insn requiring small register
- classes. */
- && (small_class_operands_num
- < best_small_class_operands_num)))
- change_p = true;
- }
- if (change_p)
+ if (best > losers)
{
for (i = 0; i < noperands; i++)
{
}
goal_alternative_swapped = swapped;
best = losers;
- best_small_class_operands_num = small_class_operands_num;
goal_alternative_number = this_alternative_number;
goal_earlyclobber = this_earlyclobber;
}
continue;
inner_code = GET_CODE (XEXP (ad, 0));
- if (!(GET_CODE (ad) == PLUS
+ if (!(GET_CODE (ad) == PLUS
&& CONST_INT_P (XEXP (ad, 1))
&& (inner_code == PLUS || inner_code == LO_SUM)))
continue;
/* Form the adjusted address. */
if (GET_CODE (XEXP (ad, 0)) == PLUS)
- ad = gen_rtx_PLUS (GET_MODE (ad),
- op_index == 0 ? offset_reg : addend,
+ 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,
+ ad = gen_rtx_LO_SUM (GET_MODE (ad),
+ op_index == 0 ? offset_reg : addend,
op_index == 0 ? addend : offset_reg);
*loc = ad;
cls = base_reg_class (mode, MEM, GET_CODE (addend));
- find_reloads_address_part (XEXP (ad, op_index),
+ find_reloads_address_part (XEXP (ad, op_index),
&XEXP (ad, op_index), cls,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode,
if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
{
enum machine_mode address_mode = GET_MODE (ad);
- if (ad == VOIDmode)
+ if (address_mode == VOIDmode)
address_mode = targetm.addr_space.address_mode (as);
/* If AD is an address in the constant pool, the MEM rtx may be shared.
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX) \
((CONTEXT) == 0 \
? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX) \
- : REGNO_OK_FOR_INDEX_P (REGNO))
+ : REGNO_OK_FOR_INDEX_P (REGNO))
enum reg_class context_reg_class;
RTX_CODE code = GET_CODE (x);
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
- int icode
- = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
+ int icode = (int) optab_handler (add_optab, GET_MODE (x));
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x)))
> reg_class_size[rclass])
{
- x = find_reloads_subreg_address (x, 0, opnum,
+ x = find_reloads_subreg_address (x, 0, opnum,
ADDR_TYPE (type),
ind_levels, insn);
push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
PUT_MODE (tem, GET_MODE (x));
if (MEM_OFFSET (tem))
set_mem_offset (tem, plus_constant (MEM_OFFSET (tem), offset));
+ if (MEM_SIZE (tem)
+ && INTVAL (MEM_SIZE (tem)) != (HOST_WIDE_INT) outer_size)
+ set_mem_size (tem, GEN_INT (outer_size));
/* If this was a paradoxical subreg that we replaced, the
resulting memory must be sufficiently aligned to allow
else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
- else
+ else
{
gcc_assert (GET_CODE (x) == PLUS);
REG_INC note in insn INSN. REGNO must refer to a hard register. */
#ifdef AUTO_INC_DEC
-static int
+static int
reg_inc_found_and_valid_p (unsigned int regno, unsigned int endregno,
rtx insn)
{
if (! INSN_P (insn))
return 0;
-
+
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
{
unsigned int test = (int) REGNO (XEXP (link, 0));
if (test >= regno && test < endregno)
- return 1;
+ return 1;
}
return 0;
}
#define reg_inc_found_and_valid_p(regno,endregno,insn) 0
-#endif
+#endif
/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
If SETS is 1, also consider SETs. If SETS is 2, enable checking
}
if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, insn))
- return 1;
-
+ return 1;
+
if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
int i = XVECLEN (PATTERN (insn), 0) - 1;
}
if (sets == 2
&& reg_inc_found_and_valid_p (regno, endregno, elt))
- return 1;
+ return 1;
}
}
/* These functions are used to print the variables set by 'find_reloads' */
-void
+DEBUG_FUNCTION void
debug_reload_to_stream (FILE *f)
{
int r;
}
}
-void
+DEBUG_FUNCTION void
debug_reload (void)
{
debug_reload_to_stream (stderr);