#include "tm_p.h"
#include "obstack.h"
#include "insn-config.h"
-#include "insn-flags.h"
-#include "insn-codes.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
#ifdef AUTO_INC_DEC
static void add_auto_inc_notes PARAMS ((rtx, rtx));
#endif
+static void copy_eh_notes PARAMS ((rtx, rtx));
static HOST_WIDE_INT sext_for_mode PARAMS ((enum machine_mode,
HOST_WIDE_INT));
static void failed_reload PARAMS ((rtx, int));
/* The two pointers used to track the true location of the memory used
for label offsets. */
- char *real_known_ptr = NULL_PTR;
+ char *real_known_ptr = NULL;
int (*real_at_ptr)[NUM_ELIMINABLE_REGS];
/* Make sure even insns with volatile mem refs are recognizable. */
/* Make sure that the last insn in the chain
is not something that needs reloading. */
- emit_note (NULL_PTR, NOTE_INSN_DELETED);
+ emit_note (NULL, NOTE_INSN_DELETED);
/* Enable find_equiv_reg to distinguish insns made by reload. */
reload_first_uid = get_max_uid ();
return x;
case SUBREG:
- /* Similar to above processing, but preserve SUBREG_WORD.
+ /* Similar to above processing, but preserve SUBREG_BYTE.
Convert (subreg (mem)) to (mem) if not paradoxical.
Also, if we have a non-paradoxical (subreg (pseudo)) and the
pseudo didn't get a hard reg, we must replace this with the
else
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
- if (new != XEXP (x, 0))
+ if (new != SUBREG_REG (x))
{
int x_size = GET_MODE_SIZE (GET_MODE (x));
int new_size = GET_MODE_SIZE (GET_MODE (new));
|| (x_size == new_size))
)
{
- int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
+ int offset = SUBREG_BYTE (x);
enum machine_mode mode = GET_MODE (x);
- if (BYTES_BIG_ENDIAN)
- offset += (MIN (UNITS_PER_WORD,
- GET_MODE_SIZE (GET_MODE (new)))
- - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
-
PUT_MODE (new, mode);
XEXP (new, 0) = plus_constant (XEXP (new, 0), offset);
return new;
}
else
- return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_WORD (x));
+ return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_BYTE (x));
}
return x;
return x;
case USE:
+ /* Handle insn_list USE that a call to a pure function may generate. */
+ new = eliminate_regs (XEXP (x, 0), 0, insn);
+ if (new != XEXP (x, 0))
+ return gen_rtx_USE (GET_MODE (x), new);
+ return x;
+
case CLOBBER:
case ASM_OPERANDS:
case SET:
unsigned int nr;
int offset = 0;
- /* note_stores does give us subregs of hard regs. */
+ /* note_stores does give us subregs of hard regs,
+ subreg_regno_offset will abort if it is not a hard reg. */
while (GET_CODE (x) == SUBREG)
{
- offset += SUBREG_WORD (x);
+ offset += subreg_regno_offset (REGNO (SUBREG_REG (x)),
+ GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x),
+ GET_MODE (x));
x = SUBREG_REG (x);
}
if (inheritance)
{
- int word = 0;
+ int byte = 0;
register int regno = -1;
enum machine_mode mode = VOIDmode;
else if (GET_CODE (rld[r].in_reg) == SUBREG
&& GET_CODE (SUBREG_REG (rld[r].in_reg)) == REG)
{
- word = SUBREG_WORD (rld[r].in_reg);
+ byte = SUBREG_BYTE (rld[r].in_reg);
regno = REGNO (SUBREG_REG (rld[r].in_reg));
if (regno < FIRST_PSEUDO_REGISTER)
- regno += word;
+ regno = subreg_regno (rld[r].in_reg);
mode = GET_MODE (rld[r].in_reg);
}
#ifdef AUTO_INC_DEC
that can invalidate an inherited reload of part of a pseudoreg. */
else if (GET_CODE (rld[r].in) == SUBREG
&& GET_CODE (SUBREG_REG (rld[r].in)) == REG)
- regno = REGNO (SUBREG_REG (rld[r].in)) + SUBREG_WORD (rld[r].in);
+ regno = subreg_regno (rld[r].in);
#endif
if (regno >= 0 && reg_last_reload_reg[regno] != 0)
rtx last_reg = reg_last_reload_reg[regno];
enum machine_mode need_mode;
- i = REGNO (last_reg) + word;
+ i = REGNO (last_reg);
+ i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
last_class = REGNO_REG_CLASS (i);
- if (word == 0)
+ if (byte == 0)
need_mode = mode;
else
need_mode
- = smallest_mode_for_size (GET_MODE_SIZE (mode)
- + word * UNITS_PER_WORD,
+ = smallest_mode_for_size (GET_MODE_SIZE (mode) + byte,
GET_MODE_CLASS (mode));
if (
{
register rtx equiv
= find_equiv_reg (search_equiv, insn, rld[r].class,
- -1, NULL_PTR, 0, rld[r].mode);
+ -1, NULL, 0, rld[r].mode);
int regno = 0;
if (equiv != 0)
Make a new REG since this might be used in an
address and not all machines support SUBREGs
there. */
- regno = REGNO (SUBREG_REG (equiv)) + SUBREG_WORD (equiv);
+ regno = subreg_regno (equiv);
equiv = gen_rtx_REG (rld[r].mode, regno);
}
else
oldequiv
= find_equiv_reg (old, insn,
rld[rl->secondary_in_reload].class,
- -1, NULL_PTR, 0, mode);
+ -1, NULL, 0, mode);
#endif
/* If reloading from memory, see if there is a register
|| (GET_CODE (old) == REG
&& REGNO (old) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (old)] < 0)))
- oldequiv = find_equiv_reg (old, insn, ALL_REGS,
- -1, NULL_PTR, 0, mode);
+ oldequiv = find_equiv_reg (old, insn, ALL_REGS, -1, NULL, 0, mode);
if (oldequiv)
{
oldequiv = SUBREG_REG (oldequiv);
if (GET_MODE (oldequiv) != VOIDmode
&& mode != GET_MODE (oldequiv))
- oldequiv = gen_rtx_SUBREG (mode, oldequiv, 0);
+ oldequiv = gen_lowpart_SUBREG (mode, oldequiv);
/* Switch to the right place to emit the reload insns. */
switch (rl->when_needed)
rl->when_needed);
}
+ if (flag_non_call_exceptions)
+ copy_eh_notes (insn, get_insns ());
+
/* End this sequence. */
*where = get_insns ();
end_sequence ();
-
+
/* Update reload_override_in so that delete_address_reloads_1
can see the actual register usage. */
if (oldequiv_reg)
else
output_reload_insns[rl->opnum] = get_insns ();
+ if (flag_non_call_exceptions)
+ copy_eh_notes (insn, get_insns ());
+
end_sequence ();
}
&& GET_CODE (SET_SRC (set)) != REG))
{
#ifdef LOAD_EXTEND_OP
- rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
- ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
- validate_change (insn, &SET_DEST (set), wide_dest, 1);
+ if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD
+ && extend_op != NIL)
+ {
+ rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
+ ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
+ validate_change (insn, &SET_DEST (set), wide_dest, 1);
+ }
#endif
validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1);
if (GET_CODE (dst) == SUBREG)
{
- regno = SUBREG_WORD (dst);
+ regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
+ GET_MODE (SUBREG_REG (dst)),
+ SUBREG_BYTE (dst),
+ GET_MODE (dst));
dst = SUBREG_REG (dst);
}
if (GET_CODE (dst) != REG)
if (GET_CODE (dst) == SUBREG)
{
- regno = SUBREG_WORD (dst);
+ regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
+ GET_MODE (SUBREG_REG (dst)),
+ SUBREG_BYTE (dst),
+ GET_MODE (dst));
dst = SUBREG_REG (dst);
}
}
}
#endif
+
+/* Copy EH notes from an insn to its reloads. */
+static void
+copy_eh_notes (insn, x)
+ rtx insn;
+ rtx x;
+{
+ rtx eh_note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (eh_note)
+ {
+ for (; x != 0; x = NEXT_INSN (x))
+ {
+ if (may_trap_p (PATTERN (x)))
+ REG_NOTES (x)
+ = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (eh_note, 0),
+ REG_NOTES (x));
+ }
+ }
+}
+