/* Search an insn for pseudo regs that must be in hard regs and are not.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
ought to be used instead.
Before processing the first insn of the function, call `init_reload'.
+ init_reload actually has to be called earlier anyway.
To scan an insn, call `find_reloads'. This does two things:
1. sets up tables describing which values must be reloaded
#include "output.h"
#include "function.h"
#include "toplev.h"
+#include "params.h"
#include "target.h"
#ifndef REGNO_MODE_OK_FOR_BASE_P
#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) \
+ && GET_CODE (X) != HIGH \
+ && !targetm.cannot_force_const_mem (X))
\f
/* All reloads of the current insn are recorded here. See reload.h for
comments. */
static rtx secondary_memlocs[NUM_MACHINE_MODES];
static rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
+static int secondary_memlocs_elim_used = 0;
#endif
/* The instruction we are doing reloads for;
/* Compare two RTX's. */
#define MATCHES(x, y) \
- (x == y || (x != 0 && (GET_CODE (x) == REG \
- ? GET_CODE (y) == REG && REGNO (x) == REGNO (y) \
+ (x == y || (x != 0 && (REG_P (x) \
+ ? REG_P (y) && REGNO (x) == REGNO (y) \
: rtx_equal_p (x, y) && ! side_effects_p (x))))
/* Indicates if two reloads purposes are for similar enough things that we
a secondary reload is needed since whether or not a reload is needed
might be sensitive to the form of the MEM. */
- if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
+ if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
&& reg_equiv_mem[REGNO (x)] != 0)
x = reg_equiv_mem[REGNO (x)];
}
secondary_memlocs_elim[(int) mode][opnum] = loc;
+ if (secondary_memlocs_elim_used <= (int)mode)
+ secondary_memlocs_elim_used = (int)mode + 1;
return loc;
}
|| TEST_HARD_REG_BIT (reg_class_contents[(int) class],
true_regnum (rld[i].reg_rtx)))
&& out == 0 && rld[i].out == 0 && rld[i].in != 0
- && ((GET_CODE (in) == REG
- && GET_RTX_CLASS (GET_CODE (rld[i].in)) == 'a'
+ && ((REG_P (in)
+ && GET_RTX_CLASS (GET_CODE (rld[i].in)) == RTX_AUTOINC
&& MATCHES (XEXP (rld[i].in, 0), in))
- || (GET_CODE (rld[i].in) == REG
- && GET_RTX_CLASS (GET_CODE (in)) == 'a'
+ || (REG_P (rld[i].in)
+ && 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))
&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
{
/* Make sure reload_in ultimately has the increment,
not the plain register. */
- if (GET_CODE (in) == REG)
+ if (REG_P (in))
*p_in = rld[i].in;
return i;
}
/* If INNER is not a hard register, then INNER will not need to
be reloaded. */
- if (GET_CODE (inner) != REG
+ if (!REG_P (inner)
|| REGNO (inner) >= FIRST_PSEUDO_REGISTER)
return 0;
&& output
&& GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
&& ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
- != (int) HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
+ != (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
}
/* Return nonzero if IN can be reloaded into REGNO with mode MODE without
technically this is a non-optional input-output reload, but IN is
already a valid register, and has been chosen as the reload register.
Speed this up, since it trivially works. */
- if (GET_CODE (in) == REG)
+ if (REG_P (in))
return 1;
/* To test MEMs properly, we'd have to take into account all the reloads
that are already scheduled, which can become quite complicated.
And since we've already handled address reloads for this MEM, it
should always succeed anyway. */
- if (GET_CODE (in) == MEM)
+ if (MEM_P (in))
return 1;
/* If we can make a simple SET insn that does the job, everything should
it is not in a hard register, reload straight from the constant,
since we want to get rid of such pseudo registers.
Often this is done earlier, but not always in find_reloads_address. */
- if (in != 0 && GET_CODE (in) == REG)
+ if (in != 0 && REG_P (in))
{
int regno = REGNO (in);
/* Likewise for OUT. Of course, OUT will never be equivalent to
an actual constant, but it might be equivalent to a memory location
(in the case of a parameter). */
- if (out != 0 && GET_CODE (out) == REG)
+ if (out != 0 && REG_P (out))
{
int regno = REGNO (out);
/* If we have a read-write operand with an address side-effect,
change either IN or OUT so the side-effect happens only once. */
- if (in != 0 && out != 0 && GET_CODE (in) == MEM && rtx_equal_p (in, out))
+ if (in != 0 && out != 0 && MEM_P (in) && rtx_equal_p (in, out))
switch (GET_CODE (XEXP (in, 0)))
{
case POST_INC: case POST_DEC: case POST_MODIFY:
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
|| strict_low
- || (((GET_CODE (SUBREG_REG (in)) == REG
+ || (((REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
- || GET_CODE (SUBREG_REG (in)) == MEM)
+ || MEM_P (SUBREG_REG (in)))
&& ((GET_MODE_SIZE (inmode)
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
#ifdef LOAD_EXTEND_OP
/ UNITS_PER_WORD)))
#endif
))
- || (GET_CODE (SUBREG_REG (in)) == REG
+ || (REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
/* The case where out is nonzero
is handled differently in the following statement. */
> UNITS_PER_WORD)
&& ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
/ UNITS_PER_WORD)
- != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
- GET_MODE (SUBREG_REG (in)))))
+ != (int) hard_regno_nregs[REGNO (SUBREG_REG (in))]
+ [GET_MODE (SUBREG_REG (in))]))
|| ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
#ifdef SECONDARY_INPUT_RELOAD_CLASS
|| (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
== NO_REGS))
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
- || (GET_CODE (SUBREG_REG (in)) == REG
+ || (REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P
(REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
inloc = &SUBREG_REG (in);
in = *inloc;
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
- if (GET_CODE (in) == MEM)
+ if (MEM_P (in))
/* This is supposed to happen only for paradoxical subregs made by
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
{
enum reg_class in_class = class;
- if (GET_CODE (SUBREG_REG (in)) == REG)
+ if (REG_P (SUBREG_REG (in)))
in_class
= find_valid_class (inmode,
subreg_regno_offset (REGNO (SUBREG_REG (in)),
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
- || (((GET_CODE (SUBREG_REG (out)) == REG
+ || (((REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
- || GET_CODE (SUBREG_REG (out)) == MEM)
+ || MEM_P (SUBREG_REG (out)))
&& ((GET_MODE_SIZE (outmode)
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
#ifdef WORD_REGISTER_OPERATIONS
/ UNITS_PER_WORD)))
#endif
))
- || (GET_CODE (SUBREG_REG (out)) == REG
+ || (REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
> UNITS_PER_WORD)
&& ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
/ UNITS_PER_WORD)
- != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
- GET_MODE (SUBREG_REG (out)))))
+ != (int) hard_regno_nregs[REGNO (SUBREG_REG (out))]
+ [GET_MODE (SUBREG_REG (out))]))
|| ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
|| (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
== NO_REGS))
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
- || (GET_CODE (SUBREG_REG (out)) == REG
+ || (REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
GET_MODE (SUBREG_REG (out)),
outloc = &SUBREG_REG (out);
out = *outloc;
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
- if (GET_CODE (out) == MEM
+ if (MEM_P (out)
&& GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
abort ();
#endif
}
/* If IN appears in OUT, we can't share any input-only reload for IN. */
- if (in != 0 && out != 0 && GET_CODE (out) == MEM
- && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
+ if (in != 0 && out != 0 && MEM_P (out)
+ && (REG_P (in) || MEM_P (in))
&& reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
dont_share = 1;
/* If IN is a SUBREG of a hard register, make a new REG. This
simplifies some of the cases below. */
- if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
+ if (in != 0 && GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
&& ! dont_remove_subreg)
in = gen_rtx_REG (GET_MODE (in), subreg_regno (in));
/* Similarly for OUT. */
if (out != 0 && GET_CODE (out) == SUBREG
- && GET_CODE (SUBREG_REG (out)) == REG
+ && REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ! dont_remove_subreg)
out = gen_rtx_REG (GET_MODE (out), subreg_regno (out));
if (HARD_REGNO_MODE_OK (i, mode)
&& TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
{
- int nregs = HARD_REGNO_NREGS (i, mode);
+ int nregs = hard_regno_nregs[i][mode];
int j;
for (j = 1; j < nregs; j++)
#ifdef SECONDARY_MEMORY_NEEDED
/* If a memory location is needed for the copy, make one. */
- if (in != 0 && (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
+ if (in != 0 && (REG_P (in) || GET_CODE (in) == SUBREG)
&& reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
&& SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
class, inmode))
n_reloads++;
#ifdef SECONDARY_MEMORY_NEEDED
- if (out != 0 && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
+ if (out != 0 && (REG_P (out) || GET_CODE (out) == SUBREG)
&& reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
&& SECONDARY_MEMORY_NEEDED (class,
REGNO_REG_CLASS (reg_or_subregno (out)),
The easiest way to tell the caller that is to give a phony
value for the incoming operand (same as outgoing one). */
if (rld[i].reg_rtx == out
- && (GET_CODE (in) == REG || CONSTANT_P (in))
+ && (REG_P (in) || CONSTANT_P (in))
&& 0 != find_equiv_reg (in, this_insn, 0, REGNO (out),
static_reload_reg_p, i, inmode))
rld[i].in = out;
for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_DEAD
- && GET_CODE (XEXP (note, 0)) == REG
+ && REG_P (XEXP (note, 0))
&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (XEXP (note, 0), in)
&& ! refers_to_regno_for_reload_p (regno,
(regno
- + HARD_REGNO_NREGS (regno,
- rel_mode)),
+ + hard_regno_nregs[regno]
+ [rel_mode]),
PATTERN (this_insn), inloc)
/* If this is also an output reload, IN cannot be used as
the reload register if it is set in this insn unless IN
&& (out == 0 || in == out
|| ! hard_reg_set_here_p (regno,
(regno
- + HARD_REGNO_NREGS (regno,
- rel_mode)),
+ + hard_regno_nregs[regno]
+ [rel_mode]),
PATTERN (this_insn)))
/* ??? Why is this code so different from the previous?
Is there any simple coherent way to describe the two together?
&& HARD_REGNO_MODE_OK (regno, outmode))
{
unsigned int offs;
- unsigned int nregs = MAX (HARD_REGNO_NREGS (regno, inmode),
- HARD_REGNO_NREGS (regno, outmode));
+ unsigned int nregs = MAX (hard_regno_nregs[regno][inmode],
+ hard_regno_nregs[regno][outmode]);
for (offs = 0; offs < nregs; offs++)
if (fixed_regs[regno + offs]
if (offs == nregs
&& (! (refers_to_regno_for_reload_p
- (regno, (regno + HARD_REGNO_NREGS (regno, inmode)),
+ (regno, (regno + hard_regno_nregs[regno][inmode]),
in, (rtx *)0))
|| can_reload_into (in, regno, inmode)))
{
If the same reload reg is used for both reg 69 and the
result to be stored in memory, then that result
will clobber the address of the memory ref. */
- && ! (GET_CODE (rld[i].in) == REG
+ && ! (REG_P (rld[i].in)
&& reg_overlap_mentioned_for_reload_p (rld[i].in,
rld[output_reload].out))))
&& ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
up can fully hold our output reload. */
for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_DEAD
- && GET_CODE (XEXP (note, 0)) == REG
+ && REG_P (XEXP (note, 0))
&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
rld[output_reload].out)
&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
REGNO (XEXP (note, 0)))
- && (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
- <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
+ && (hard_regno_nregs[REGNO (XEXP (note, 0))][rld[output_reload].outmode]
+ <= hard_regno_nregs[REGNO (XEXP (note, 0))][GET_MODE (XEXP (note, 0))])
/* Ensure that a secondary or tertiary reload for this output
won't want this register. */
&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
/* Find the inside of any subregs. */
while (GET_CODE (out) == SUBREG)
{
- if (GET_CODE (SUBREG_REG (out)) == REG
+ if (REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
out_offset += subreg_regno_offset (REGNO (SUBREG_REG (out)),
GET_MODE (SUBREG_REG (out)),
}
while (GET_CODE (in) == SUBREG)
{
- if (GET_CODE (SUBREG_REG (in)) == REG
+ if (REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
in_offset += subreg_regno_offset (REGNO (SUBREG_REG (in)),
GET_MODE (SUBREG_REG (in)),
class = PREFERRED_RELOAD_CLASS (in, class);
/* See if OUT will do. */
- if (GET_CODE (out) == REG
+ if (REG_P (out)
&& REGNO (out) < FIRST_PSEUDO_REGISTER)
{
unsigned int regno = REGNO (out) + out_offset;
- unsigned int nwords = HARD_REGNO_NREGS (regno, outmode);
+ unsigned int nwords = hard_regno_nregs[regno][outmode];
rtx saved_rtx;
/* When we consider whether the insn uses OUT,
if (i == nwords)
{
- if (GET_CODE (real_out) == REG)
+ if (REG_P (real_out))
value = real_out;
else
value = gen_rtx_REG (outmode, regno);
Also, the result can't go in IN if IN is used within OUT,
or if OUT is an earlyclobber and IN appears elsewhere in the insn. */
if (hard_regs_live_known
- && GET_CODE (in) == REG
+ && REG_P (in)
&& REGNO (in) < FIRST_PSEUDO_REGISTER
&& (value == 0
|| find_reg_note (this_insn, REG_UNUSED, real_out))
? GET_MODE (out) : outmode)))
{
unsigned int regno = REGNO (in) + in_offset;
- unsigned int nwords = HARD_REGNO_NREGS (regno, inmode);
+ unsigned int nwords = hard_regno_nregs[regno][inmode];
if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, (rtx*) 0)
&& ! hard_reg_set_here_p (regno, regno + nwords,
dies here. So don't bother copying value to it. */
if (for_real >= 0 && value == real_out)
rld[for_real].out = 0;
- if (GET_CODE (real_in) == REG)
+ if (REG_P (real_in))
value = real_in;
else
value = gen_rtx_REG (inmode, regno);
while (GET_CODE (op0) == SUBREG)
op0 = SUBREG_REG (op0);
- if (GET_CODE (op0) == REG)
+ if (REG_P (op0))
{
unsigned int r = REGNO (op0);
/* See if this reg overlaps range under consideration. */
if (r < end_regno
- && r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
+ && r + hard_regno_nregs[r][GET_MODE (op0)] > beg_regno)
return 1;
}
}
if (x == y)
return 1;
- if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
- && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
- && GET_CODE (SUBREG_REG (y)) == REG)))
+ if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
+ && (REG_P (y) || (GET_CODE (y) == SUBREG
+ && REG_P (SUBREG_REG (y)))))
{
int j;
(reg:SI 1) will be considered the same register. */
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
&& i < FIRST_PSEUDO_REGISTER)
- i += HARD_REGNO_NREGS (i, GET_MODE (x)) - 1;
+ i += hard_regno_nregs[i][GET_MODE (x)] - 1;
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
&& j < FIRST_PSEUDO_REGISTER)
- j += HARD_REGNO_NREGS (j, GET_MODE (y)) - 1;
+ j += hard_regno_nregs[j][GET_MODE (y)] - 1;
return i == j;
}
struct decomposition val;
int all_const = 0;
- val.reg_flag = 0;
- val.safe = 0;
- val.base = 0;
- if (GET_CODE (x) == MEM)
+ memset (&val, 0, sizeof (val));
+
+ if (MEM_P (x))
{
rtx base = NULL_RTX, offset = 0;
rtx addr = XEXP (x, 0);
val.base = base;
return val;
}
- else if (GET_CODE (x) == REG)
+ else if (REG_P (x))
{
val.reg_flag = 1;
val.start = true_regnum (x);
}
else
/* A hard reg. */
- val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
+ val.end = val.start + hard_regno_nregs[val.start][GET_MODE (x)];
}
else if (GET_CODE (x) == SUBREG)
{
- if (GET_CODE (SUBREG_REG (x)) != REG)
+ if (!REG_P (SUBREG_REG (x)))
/* This could be more precise, but it's good enough. */
return decompose (SUBREG_REG (x));
val.reg_flag = 1;
return decompose (SUBREG_REG (x));
else
/* A hard reg. */
- val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
+ val.end = val.start + hard_regno_nregs[val.start][GET_MODE (x)];
}
else if (CONSTANT_P (x)
/* This hasn't been assigned yet, so it can't conflict yet. */
if (ydata.safe)
return 1;
- if (GET_CODE (y) != MEM)
+ if (!MEM_P (y))
abort ();
/* If Y is memory and X is not, Y can't affect X. */
- if (GET_CODE (x) != MEM)
+ if (!MEM_P (x))
return 1;
xdata = decompose (x);
/* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
neither are insns that SET cc0. Insns that use CC0 are not allowed
to have any input reloads. */
- if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
+ if (JUMP_P (insn) || CALL_P (insn))
no_output_reloads = 1;
#ifdef HAVE_cc0
/* The eliminated forms of any secondary memory locations are per-insn, so
clear them out here. */
- memset (secondary_memlocs_elim, 0, sizeof secondary_memlocs_elim);
+ if (secondary_memlocs_elim_used)
+ {
+ memset (secondary_memlocs_elim, 0,
+ sizeof (secondary_memlocs_elim[0]) * secondary_memlocs_elim_used);
+ secondary_memlocs_elim_used = 0;
+ }
#endif
/* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
is cheap to move between them. If it is not, there may not be an insn
to do the copy, so we may need a reload. */
if (GET_CODE (body) == SET
- && GET_CODE (SET_DEST (body)) == REG
+ && REG_P (SET_DEST (body))
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
- && GET_CODE (SET_SRC (body)) == REG
+ && REG_P (SET_SRC (body))
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
&& REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
REGNO_REG_CLASS (REGNO (SET_SRC (body))),
while ((c = *p))
{
p += CONSTRAINT_LEN (c, p);
- if (c == '=')
- modified[i] = RELOAD_WRITE;
- else if (c == '+')
- modified[i] = RELOAD_READ_WRITE;
- else if (c == '%')
+ switch (c)
{
- /* The last operand should not be marked commutative. */
- if (i == noperands - 1)
- abort ();
+ case '=':
+ modified[i] = RELOAD_WRITE;
+ break;
+ case '+':
+ modified[i] = RELOAD_READ_WRITE;
+ break;
+ case '%':
+ {
+ /* The last operand should not be marked commutative. */
+ if (i == noperands - 1)
+ abort ();
- commutative = i;
- }
- else if (ISDIGIT (c))
- {
- c = strtoul (p - 1, &p, 10);
+ /* We currently only support one commutative pair of
+ operands. Some existing asm code currently uses more
+ than one pair. Previously, that would usually work,
+ but sometimes it would crash the compiler. We
+ continue supporting that case as well as we can by
+ silently ignoring all but the first pair. In the
+ future we may handle it correctly. */
+ if (commutative < 0)
+ commutative = i;
+ else if (!this_insn_is_asm)
+ abort ();
+ }
+ break;
+ /* Use of ISDIGIT is tempting here, but it may get expensive because
+ of locale support we don't want. */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ c = strtoul (p - 1, &p, 10);
- operands_match[c][i]
- = operands_match_p (recog_data.operand[c],
- recog_data.operand[i]);
+ operands_match[c][i]
+ = operands_match_p (recog_data.operand[c],
+ recog_data.operand[i]);
- /* An operand may not match itself. */
- if (c == i)
- abort ();
+ /* An operand may not match itself. */
+ if (c == i)
+ abort ();
- /* If C can be commuted with C+1, and C might need to match I,
- then C+1 might also need to match I. */
- if (commutative >= 0)
- {
- if (c == commutative || c == commutative + 1)
- {
- int other = c + (c == commutative ? 1 : -1);
- operands_match[other][i]
- = operands_match_p (recog_data.operand[other],
- recog_data.operand[i]);
- }
- if (i == commutative || i == commutative + 1)
- {
- int other = i + (i == commutative ? 1 : -1);
- operands_match[c][other]
- = operands_match_p (recog_data.operand[c],
- recog_data.operand[other]);
- }
- /* Note that C is supposed to be less than I.
- No need to consider altering both C and I because in
- that case we would alter one into the other. */
- }
+ /* If C can be commuted with C+1, and C might need to match I,
+ then C+1 might also need to match I. */
+ if (commutative >= 0)
+ {
+ if (c == commutative || c == commutative + 1)
+ {
+ int other = c + (c == commutative ? 1 : -1);
+ operands_match[other][i]
+ = operands_match_p (recog_data.operand[other],
+ recog_data.operand[i]);
+ }
+ if (i == commutative || i == commutative + 1)
+ {
+ int other = i + (i == commutative ? 1 : -1);
+ operands_match[c][other]
+ = operands_match_p (recog_data.operand[c],
+ recog_data.operand[other]);
+ }
+ /* Note that C is supposed to be less than I.
+ No need to consider altering both C and I because in
+ that case we would alter one into the other. */
+ }
+ }
}
}
}
/* If we now have a simple operand where we used to have a
PLUS or MULT, re-recognize and try again. */
- if ((GET_RTX_CLASS (GET_CODE (*recog_data.operand_loc[i])) == 'o'
+ if ((OBJECT_P (*recog_data.operand_loc[i])
|| GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
&& (GET_CODE (recog_data.operand[i]) == MULT
|| GET_CODE (recog_data.operand[i]) == PLUS))
wider reload. */
if (replace
- && GET_CODE (op) == MEM
- && GET_CODE (reg) == REG
+ && MEM_P (op)
+ && REG_P (reg)
&& (GET_MODE_SIZE (GET_MODE (reg))
>= GET_MODE_SIZE (GET_MODE (op))))
set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
substed_operand[i] = recog_data.operand[i] = op;
}
- else if (code == PLUS || GET_RTX_CLASS (code) == '1')
+ else if (code == PLUS || GET_RTX_CLASS (code) == RTX_UNARY)
/* We can get a PLUS as an "operand" as a result of register
elimination. See eliminate_regs and gen_reload. We handle
a unary operator by reloading the operand. */
/* If the predicate accepts a unary operator, it means that
we need to reload the operand, but do not do this for
match_operator and friends. */
- if (GET_RTX_CLASS (GET_CODE (operand)) == '1' && *p != 0)
+ if (UNARY_P (operand) && *p != 0)
operand = XEXP (operand, 0);
/* If the operand is a SUBREG, extract
it is a hard reg. This is because it is passed
to reg_fits_class_p if it is a REG and all pseudos
return 0 from that function. */
- if (GET_CODE (SUBREG_REG (operand)) == REG
+ if (REG_P (SUBREG_REG (operand))
&& REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
{
if (!subreg_offset_representable_p
??? When is it right at this stage to have a subreg
of a mem that is _not_ to be handled specially? IMO
those should have been reduced to just a mem. */
- || ((GET_CODE (operand) == MEM
- || (GET_CODE (operand)== REG
+ || ((MEM_P (operand)
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
#ifndef WORD_REGISTER_OPERATIONS
&& (((GET_MODE_BITSIZE (GET_MODE (operand))
< BIGGEST_ALIGNMENT)
&& (GET_MODE_SIZE (operand_mode[i])
> GET_MODE_SIZE (GET_MODE (operand))))
- || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
+ || BYTES_BIG_ENDIAN
#ifdef LOAD_EXTEND_OP
|| (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (operand))
break;
case '%':
- /* The last operand should not be marked commutative. */
- if (i != noperands - 1)
- commutative = i;
+ /* We only support one commutative marker, the first
+ one. We already set commutative above. */
break;
case '?':
offsettable address was expected, then we must reject
this combination, because we can't reload it. */
if (this_alternative_offmemok[m]
- && GET_CODE (recog_data.operand[m]) == MEM
+ && MEM_P (recog_data.operand[m])
&& this_alternative[m] == (int) NO_REGS
&& ! this_alternative_win[m])
bad = 1;
case 'm':
if (force_reload)
break;
- if (GET_CODE (operand) == MEM
- || (GET_CODE (operand) == REG
+ if (MEM_P (operand)
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0))
win = 1;
- if (CONSTANT_P (operand)
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (operand) != HIGH)
+ if (CONST_POOL_OK_P (operand))
badop = 0;
constmemok = 1;
break;
case '<':
- if (GET_CODE (operand) == MEM
+ if (MEM_P (operand)
&& ! address_reloaded[i]
&& (GET_CODE (XEXP (operand, 0)) == PRE_DEC
|| GET_CODE (XEXP (operand, 0)) == POST_DEC))
break;
case '>':
- if (GET_CODE (operand) == MEM
+ if (MEM_P (operand)
&& ! address_reloaded[i]
&& (GET_CODE (XEXP (operand, 0)) == PRE_INC
|| GET_CODE (XEXP (operand, 0)) == POST_INC))
case 'V':
if (force_reload)
break;
- if (GET_CODE (operand) == MEM
+ if (MEM_P (operand)
&& ! (ind_levels ? offsettable_memref_p (operand)
: offsettable_nonstrict_memref_p (operand))
/* Certain mem addresses will become offsettable
after they themselves are reloaded. This is important;
we don't want our own handling of unoffsettables
to override the handling of reg_equiv_address. */
- && !(GET_CODE (XEXP (operand, 0)) == REG
+ && !(REG_P (XEXP (operand, 0))
&& (ind_levels == 0
|| reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
win = 1;
case 'o':
if (force_reload)
break;
- if ((GET_CODE (operand) == MEM
+ if ((MEM_P (operand)
/* If IND_LEVELS, find_reloads_address won't reload a
pseudo that didn't get a hard reg, so we have to
reject that case. */
/* A reloaded address is offsettable because it is now
just a simple register indirect. */
|| address_reloaded[i]))
- || (GET_CODE (operand) == REG
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
/* If reg_equiv_address is nonzero, we will be
&& offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
|| (reg_equiv_address[REGNO (operand)] != 0))))
win = 1;
- /* force_const_mem does not accept HIGH. */
- if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
- || GET_CODE (operand) == MEM)
+ if (CONST_POOL_OK_P (operand)
+ || MEM_P (operand))
badop = 0;
constmemok = 1;
offmemok = 1;
break;
case 'i':
if (CONSTANT_P (operand)
-#ifdef LEGITIMATE_PIC_OPERAND_P
- && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))
-#endif
- )
+ && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand)))
win = 1;
break;
&& GET_CODE (operand) != PLUS
/* A SCRATCH is not a valid operand. */
&& GET_CODE (operand) != SCRATCH
-#ifdef LEGITIMATE_PIC_OPERAND_P
&& (! CONSTANT_P (operand)
|| ! flag_pic
|| LEGITIMATE_PIC_OPERAND_P (operand))
-#endif
&& (GENERAL_REGS == ALL_REGS
- || GET_CODE (operand) != REG
+ || !REG_P (operand)
|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0)))
win = 1;
win = 1;
/* If the address was already reloaded,
we win as well. */
- else if (GET_CODE (operand) == MEM
+ else if (MEM_P (operand)
&& address_reloaded[i])
win = 1;
/* Likewise if the address will be reloaded because
reg_equiv_address is nonzero. For reg_equiv_mem
we have to check. */
- else if (GET_CODE (operand) == REG
+ else if (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
&& ((reg_equiv_mem[REGNO (operand)] != 0
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
- if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
- || GET_CODE (operand) == MEM)
+ if (CONST_POOL_OK_P (operand)
+ || MEM_P (operand))
badop = 0;
constmemok = 1;
offmemok = 1;
if (GET_MODE (operand) == BLKmode)
break;
winreg = 1;
- if (GET_CODE (operand) == REG
+ if (REG_P (operand)
&& reg_fits_class_p (operand, this_alternative[i],
offset, GET_MODE (recog_data.operand[i])))
win = 1;
if (badop)
bad = 1;
/* Alternative loses if it has no regs for a reg operand. */
- if (GET_CODE (operand) == REG
+ if (REG_P (operand)
&& this_alternative[i] == (int) NO_REGS
&& this_alternative_matches[i] < 0)
bad = 1;
an early reload pass. Note that the test here is
precisely the same as in the code below that calls
force_const_mem. */
- if (CONSTANT_P (operand)
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (operand) != HIGH
+ if (CONST_POOL_OK_P (operand)
&& ((PREFERRED_RELOAD_CLASS (operand,
(enum reg_class) this_alternative[i])
== NO_REGS)
const_to_mem = 1;
if (this_alternative[i] != (int) NO_REGS)
losers++;
-
- /* If constant pool symbols are not valid addresses,
- count an extra reload for the address. */
- if (!targetm.direct_pool_load_p (operand_mode[i]))
- losers++;
}
/* If we can't reload this value at all, reject this
&& ! const_to_mem)
bad = 1;
-#ifdef SECONDARY_MEMORY_NEEDED
- /* If this alternative would use memory to move a value
- between registers, it would need two reloads, one for
- the load and one for the store. Account for the extra
- reload here. */
- if (GET_CODE (operand) == REG
- && REGNO (operand) < FIRST_PSEUDO_REGISTER
- && (enum reg_class) this_alternative[i] != NO_REGS
- && (SECONDARY_MEMORY_NEEDED
- ((enum reg_class) this_alternative[i],
- REGNO_REG_CLASS (REGNO (operand)),
- GET_MODE (operand))))
- losers++;
-#endif
-
/* We prefer to reload pseudos over reloading other things,
since such reloads may be able to be eliminated later.
If we are reloading a SCRATCH, we won't be generating any
case where we are forcing a constant into memory and
it will then win since we don't want to have a different
alternative match then. */
- if (! (GET_CODE (operand) == REG
+ if (! (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER)
&& GET_CODE (operand) != SCRATCH
&& ! (const_to_mem && constmemok))
for (j = 0; j < noperands; j++)
/* Is this an input operand or a memory ref? */
- if ((GET_CODE (recog_data.operand[j]) == MEM
+ if ((MEM_P (recog_data.operand[j])
|| modified[j] != RELOAD_WRITE)
&& j != i
/* Ignore things like match_operator operands. */
/* If the output is in a single-reg class,
it's costly to reload it, so reload the input instead. */
if (reg_class_size[this_alternative[i]] == 1
- && (GET_CODE (recog_data.operand[j]) == REG
+ && (REG_P (recog_data.operand[j])
|| GET_CODE (recog_data.operand[j]) == SUBREG))
{
losers++;
into registers are here changed into memory references. */
for (i = 0; i < noperands; i++)
if (! goal_alternative_win[i]
- && CONSTANT_P (recog_data.operand[i])
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (recog_data.operand[i]) != HIGH
+ && CONST_POOL_OK_P (recog_data.operand[i])
&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
(enum reg_class) goal_alternative[i])
== NO_REGS)
so we don't bother with it. It may not be worth doing. */
else if (goal_alternative_matched[i] == -1
&& goal_alternative_offmemok[i]
- && GET_CODE (recog_data.operand[i]) == MEM)
+ && MEM_P (recog_data.operand[i]))
{
operand_reloadnum[i]
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
while (GET_CODE (operand) == SUBREG)
operand = SUBREG_REG (operand);
- if ((GET_CODE (operand) == MEM
- || (GET_CODE (operand) == REG
+ if ((MEM_P (operand)
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
/* If this is only for an output, the optional reload would not
actually cause us to use a register now, just note that
we then need to emit a USE and/or a CLOBBER so that reload
inheritance will do the right thing. */
else if (replace
- && (GET_CODE (operand) == MEM
- || (GET_CODE (operand) == REG
+ && (MEM_P (operand)
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber [REGNO (operand)] < 0)))
{
while (GET_CODE (operand) == SUBREG)
operand = SUBREG_REG (operand);
- if (GET_CODE (operand) == REG)
+ if (REG_P (operand))
{
if (modified[i] != RELOAD_WRITE)
/* We mark the USE with QImode so that we recognize
while (GET_CODE (operand) == SUBREG)
operand = SUBREG_REG (operand);
- if ((GET_CODE (operand) == MEM
- || (GET_CODE (operand) == REG
+ if ((MEM_P (operand)
+ || (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
&& ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
!= NO_REGS))
/* If we're replacing an operand with a LABEL_REF, we need
to make sure that there's a REG_LABEL note attached to
this instruction. */
- if (GET_CODE (insn) != JUMP_INSN
+ if (!JUMP_P (insn)
&& GET_CODE (substitution) == LABEL_REF
&& !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
for (i = 0; i < n_reloads; i++)
if (rld[i].reg_rtx == 0
&& rld[i].in != 0
- && GET_CODE (rld[i].in) == REG
+ && REG_P (rld[i].in)
&& rld[i].out == 0)
{
rld[i].reg_rtx
for (i = 0; i < n_reloads; i++)
if (rld[i].when_needed == RELOAD_FOR_INPUT
&& GET_CODE (PATTERN (insn)) == SET
- && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ && REG_P (SET_DEST (PATTERN (insn)))
&& SET_SRC (PATTERN (insn)) == rld[i].in)
{
rtx dest = SET_DEST (PATTERN (insn));
&& TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
&& HARD_REGNO_MODE_OK (regno, rld[i].mode))
{
- int nr = HARD_REGNO_NREGS (regno, rld[i].mode);
+ int nr = hard_regno_nregs[regno][rld[i].mode];
int ok = 1, nri;
for (nri = 1; nri < nr; nri ++)
return tem;
}
- if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
+ if (code == SUBREG && REG_P (SUBREG_REG (x)))
{
/* Check for SUBREG containing a REG that's equivalent to a constant.
If the constant has a known value, truncate it right now.
reload if not. We first handle the cases where we need not reload
or where we must reload in a non-standard way. */
- if (GET_CODE (ad) == REG)
+ if (REG_P (ad))
{
regno = REGNO (ad);
if (ind_levels > 0
&& strict_memory_address_p (mode, tem)
- && (GET_CODE (XEXP (tem, 0)) == REG
+ && (REG_P (XEXP (tem, 0))
|| (GET_CODE (XEXP (tem, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
+ && REG_P (XEXP (XEXP (tem, 0), 0))
&& CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
{
/* TEM is not the same as what we'll be replacing the
/* But first quickly dispose of a common case. */
if (GET_CODE (ad) == PLUS
&& GET_CODE (XEXP (ad, 1)) == CONST_INT
- && GET_CODE (XEXP (ad, 0)) == REG
+ && REG_P (XEXP (ad, 0))
&& reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
return 0;
frame and stack pointers is not its initial value. In that case the
pseudo will have been replaced by a MEM referring to the
stack pointer. */
- if (GET_CODE (ad) == MEM)
+ if (MEM_P (ad))
{
/* First ensure that the address in this MEM is valid. Then, unless
indirect addresses are valid, reload the MEM into a register. */
if (ind_levels == 0
|| (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
- || GET_CODE (XEXP (tem, 0)) == MEM
- || ! (GET_CODE (XEXP (tem, 0)) == REG
+ || MEM_P (XEXP (tem, 0))
+ || ! (REG_P (XEXP (tem, 0))
|| (GET_CODE (XEXP (tem, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
+ && REG_P (XEXP (XEXP (tem, 0), 0))
&& GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)))
{
/* Must use TEM here, not AD, since it is the one that will
targets (namely SH) we can also get too large displacements from
big-endian corrections. */
else if (GET_CODE (ad) == PLUS
- && GET_CODE (XEXP (ad, 0)) == REG
+ && REG_P (XEXP (ad, 0))
&& REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
&& REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
&& GET_CODE (XEXP (ad, 1)) == CONST_INT)
else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
&& GET_CODE (XEXP (ad, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ad, 0), 0)) == REG
+ && 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
else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
&& GET_CODE (XEXP (ad, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ad, 0), 1)) == REG
+ && 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
{
/* Try to find a register to replace. */
op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 0;
- if (GET_CODE (op0) == REG
+ if (REG_P (op0)
&& (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0)
op0 = reg_equiv_constant[regno];
- else if (GET_CODE (op1) == REG
+ else if (REG_P (op1)
&& (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0)
case POST_DEC:
case PRE_INC:
case PRE_DEC:
- if (GET_CODE (XEXP (x, 0)) == REG)
+ if (REG_P (XEXP (x, 0)))
{
int regno = REGNO (XEXP (x, 0));
int value = 0;
memory location, since this will make it harder to
reuse address reloads, and increases register pressure.
Also don't do this if we can probably update x directly. */
- rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
+ rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
- if (insn && GET_CODE (insn) == INSN && equiv
+ if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
&& ! sets_cc0_p (PATTERN (insn))
return value;
}
- else if (GET_CODE (XEXP (x, 0)) == MEM)
+ else if (MEM_P (XEXP (x, 0)))
{
/* This is probably the result of a substitution, by eliminate_regs,
of an equivalent address for a pseudo that was not allocated to a
return 0;
case SUBREG:
- if (GET_CODE (SUBREG_REG (x)) == REG)
+ if (REG_P (SUBREG_REG (x)))
{
/* If this is a SUBREG of a hard register and the resulting register
is of the wrong class, reload the whole SUBREG. This avoids
return x;
base = XEXP (base, 0);
}
- if (GET_CODE (base) != REG
+ if (!REG_P (base)
|| (REGNO_POINTER_ALIGN (REGNO (base))
< outer_size * BITS_PER_UNIT))
return x;
REG_LABEL note to indicate to flow which label this
register refers to. */
if (GET_CODE (*r->where) == LABEL_REF
- && GET_CODE (insn) == JUMP_INSN)
+ && JUMP_P (insn))
REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
XEXP (*r->where, 0),
REG_NOTES (insn));
??? Is it actually still ever a SUBREG? If so, why? */
- if (GET_CODE (reloadreg) == REG)
+ if (REG_P (reloadreg))
return gen_rtx_REG (GET_MODE (*loc),
(REGNO (reloadreg) +
subreg_regno_offset (REGNO (SUBREG_REG (*loc)),
return (endregno > r
&& regno < r + (r < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (r, GET_MODE (x))
+ ? hard_regno_nregs[r][GET_MODE (x)]
: 1));
case SUBREG:
/* If this is a SUBREG of a hard reg, we can see exactly which
registers are being modified. Otherwise, handle normally. */
- if (GET_CODE (SUBREG_REG (x)) == REG
+ if (REG_P (SUBREG_REG (x))
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
{
unsigned int inner_regno = subreg_regno (x);
unsigned int inner_endregno
= inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ ? hard_regno_nregs[inner_regno][GET_MODE (x)] : 1);
return endregno > inner_regno && regno < inner_endregno;
}
treat each word individually. */
&& ((GET_CODE (SET_DEST (x)) == SUBREG
&& loc != &SUBREG_REG (SET_DEST (x))
- && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
+ && REG_P (SUBREG_REG (SET_DEST (x)))
&& REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
&& refers_to_regno_for_reload_p (regno, endregno,
SUBREG_REG (SET_DEST (x)),
loc))
/* If the output is an earlyclobber operand, this is
a conflict. */
- || ((GET_CODE (SET_DEST (x)) != REG
+ || ((!REG_P (SET_DEST (x))
|| earlyclobber_operand_p (SET_DEST (x)))
&& refers_to_regno_for_reload_p (regno, endregno,
SET_DEST (x), loc))))
/* Overly conservative. */
if (GET_CODE (x) == STRICT_LOW_PART
- || GET_RTX_CLASS (GET_CODE (x)) == 'a')
+ || GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
x = XEXP (x, 0);
/* If either argument is a constant, then modifying X can not affect IN. */
SUBREG_BYTE (x),
GET_MODE (x));
}
- else if (GET_CODE (x) == REG)
+ else if (REG_P (x))
{
regno = REGNO (x);
abort ();
}
}
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
return refers_to_mem_for_reload_p (in);
else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
else if (GET_CODE (x) == PLUS)
- return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
- || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ {
+ /* We actually want to know if X is mentioned somewhere inside IN.
+ We must not say that (plus (sp) (const_int 124)) is in
+ (plus (sp) (const_int 64)), since that can lead to incorrect reload
+ allocation when spuriously changing a RELOAD_FOR_OUTPUT_ADDRESS
+ into a RELOAD_OTHER on behalf of another RELOAD_OTHER. */
+ while (MEM_P (in))
+ in = XEXP (in, 0);
+ if (REG_P (in))
+ return 0;
+ else if (GET_CODE (in) == PLUS)
+ return (reg_overlap_mentioned_for_reload_p (x, XEXP (in, 0))
+ || reg_overlap_mentioned_for_reload_p (x, XEXP (in, 1)));
+ else return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
+ || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ }
else
abort ();
endregno = regno + (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ ? hard_regno_nregs[regno][GET_MODE (x)] : 1);
return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
}
const char *fmt;
int i;
- if (GET_CODE (x) == MEM)
+ if (MEM_P (x))
return 1;
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
return (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& reg_equiv_memory_loc[REGNO (x)]);
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
if (fmt[i] == 'e'
- && (GET_CODE (XEXP (x, i)) == MEM
+ && (MEM_P (XEXP (x, i))
|| refers_to_mem_for_reload_p (XEXP (x, i))))
return 1;
int need_stable_sp = 0;
int nregs;
int valuenregs;
+ int num = 0;
if (goal == 0)
regno = goalreg;
- else if (GET_CODE (goal) == REG)
+ else if (REG_P (goal))
regno = REGNO (goal);
- else if (GET_CODE (goal) == MEM)
+ else if (MEM_P (goal))
{
enum rtx_code code = GET_CODE (XEXP (goal, 0));
if (MEM_VOLATILE_P (goal))
else
return 0;
+ num = 0;
/* Scan insns back from INSN, looking for one that copies
a value into or out of GOAL.
Stop and give up if we reach a label. */
while (1)
{
p = PREV_INSN (p);
- if (p == 0 || GET_CODE (p) == CODE_LABEL)
+ num++;
+ if (p == 0 || LABEL_P (p)
+ || num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS))
return 0;
- if (GET_CODE (p) == INSN
+ if (NONJUMP_INSN_P (p)
/* If we don't want spill regs ... */
&& (! (reload_reg_p != 0
&& reload_reg_p != (short *) (HOST_WIDE_INT) 1)
&& ((rtx_equal_p (XEXP (tem, 0), goal)
&& (valueno
= true_regnum (valtry = SET_DEST (pat))) >= 0)
- || (GET_CODE (SET_DEST (pat)) == REG
+ || (REG_P (SET_DEST (pat))
&& GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
&& (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
== MODE_FLOAT)
&& (valueno = true_regnum (valtry)) >= 0)))
|| (goal_const && (tem = find_reg_note (p, REG_EQUIV,
NULL_RTX))
- && GET_CODE (SET_DEST (pat)) == REG
+ && REG_P (SET_DEST (pat))
&& GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
&& (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
== MODE_FLOAT)
{
int i;
- for (i = HARD_REGNO_NREGS (valueno, mode) - 1; i >= 0; i--)
+ for (i = hard_regno_nregs[valueno][mode] - 1; i >= 0; i--)
if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
valueno + i))
break;
if (goal_mem && value == SET_DEST (single_set (where))
&& refers_to_regno_for_reload_p (valueno,
(valueno
- + HARD_REGNO_NREGS (valueno, mode)),
+ + hard_regno_nregs[valueno][mode]),
goal, (rtx*) 0))
return 0;
/* Reject registers that overlap GOAL. */
+ if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
+ nregs = hard_regno_nregs[regno][mode];
+ else
+ nregs = 1;
+ valuenregs = hard_regno_nregs[valueno][mode];
+
if (!goal_mem && !goal_const
- && regno + (int) HARD_REGNO_NREGS (regno, mode) > valueno
- && regno < valueno + (int) HARD_REGNO_NREGS (valueno, mode))
+ && regno + nregs > valueno && regno < valueno + valuenregs)
return 0;
- nregs = HARD_REGNO_NREGS (regno, mode);
- valuenregs = HARD_REGNO_NREGS (valueno, mode);
-
/* Reject VALUE if it is one of the regs reserved for reloads.
Reload1 knows how to reuse them anyway, and it would get
confused if we allocated one without its knowledge.
if (rld[i].reg_rtx != 0 && rld[i].in)
{
int regno1 = REGNO (rld[i].reg_rtx);
- int nregs1 = HARD_REGNO_NREGS (regno1,
- GET_MODE (rld[i].reg_rtx));
+ int nregs1 = hard_regno_nregs[regno1]
+ [GET_MODE (rld[i].reg_rtx)];
if (regno1 < valueno + valuenregs
&& regno1 + nregs1 > valueno)
return 0;
/* Don't trust the conversion past a function call
if either of the two is in a call-clobbered register, or memory. */
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
{
int i;
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
int xregno = REGNO (dest);
int xnregs;
if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
- xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
+ xnregs = hard_regno_nregs[xregno][GET_MODE (dest)];
else
xnregs = 1;
if (xregno < regno + nregs && xregno + xnregs > regno)
if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
return 0;
}
- else if (goal_mem && GET_CODE (dest) == MEM
+ else if (goal_mem && MEM_P (dest)
&& ! push_operand (dest, GET_MODE (dest)))
return 0;
- else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
+ else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
&& reg_equiv_memory_loc[regno] != 0)
return 0;
else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
int xregno = REGNO (dest);
int xnregs;
if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
- xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
+ xnregs = hard_regno_nregs[xregno][GET_MODE (dest)];
else
xnregs = 1;
if (xregno < regno + nregs
if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
return 0;
}
- else if (goal_mem && GET_CODE (dest) == MEM
+ else if (goal_mem && MEM_P (dest)
&& ! push_operand (dest, GET_MODE (dest)))
return 0;
- else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
+ else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
&& reg_equiv_memory_loc[regno] != 0)
return 0;
else if (need_stable_sp
}
}
- if (GET_CODE (p) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (p))
+ if (CALL_P (p) && CALL_INSN_FUNCTION_USAGE (p))
{
rtx link;
{
rtx dest = SET_DEST (pat);
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
int xregno = REGNO (dest);
int xnregs
- = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
+ = hard_regno_nregs[xregno][GET_MODE (dest)];
if (xregno < regno + nregs
&& xregno + xnregs > regno)
return 0;
}
- else if (goal_mem && GET_CODE (dest) == MEM
+ else if (goal_mem && MEM_P (dest)
&& ! push_operand (dest, GET_MODE (dest)))
return 0;
else if (need_stable_sp
for (link = REG_NOTES (p); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC
- && GET_CODE (XEXP (link, 0)) == REG)
+ && REG_P (XEXP (link, 0)))
{
int incno = REGNO (XEXP (link, 0));
if (incno < regno + nregs && incno >= regno)
regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
int sets)
{
- unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
+ unsigned int nregs = hard_regno_nregs[regno][mode];
unsigned int endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET))
- && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
+ && REG_P (XEXP (PATTERN (insn), 0)))
{
unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET))
- && GET_CODE (XEXP (elt, 0)) == REG)
+ && REG_P (XEXP (elt, 0)))
{
unsigned int test = REGNO (XEXP (elt, 0));
regno = REGNO (reloadreg);
if (WORDS_BIG_ENDIAN)
- regno += HARD_REGNO_NREGS (regno, GET_MODE (reloadreg))
- - HARD_REGNO_NREGS (regno, mode);
+ regno += (int) hard_regno_nregs[regno][GET_MODE (reloadreg)]
+ - (int) hard_regno_nregs[regno][mode];
return gen_rtx_REG (mode, regno);
}