xcoffout.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h \
dbxout.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H)
recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \
- $(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h $(INSN_ATTR_H) \
- real.h toplev.h output.h reload.h $(TM_P_H)
+ $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \
+ $(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \
$(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
varray.h function.h $(TM_P_H)
MEM alone, but need to return the canonicalized MEM with
all the flags with their original values. */
else if (GET_CODE (x) == MEM)
- {
- rtx addr = canon_rtx (XEXP (x, 0));
-
- if (addr != XEXP (x, 0))
- {
- rtx new = gen_rtx_MEM (GET_MODE (x), addr);
+ x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0)));
- MEM_COPY_ATTRIBUTES (new, x);
- x = new;
- }
- }
return x;
}
/* This should not depend on WORDS_BIG_ENDIAN.
The order of words in regs is the same as in memory. */
regno_save_mem[i + k][1]
- = adjust_address (regno_save_mem[i][j], regno_save_mode[i + k][1],
- k * UNITS_PER_WORD);
+ = adjust_address_nv (regno_save_mem[i][j],
+ regno_save_mode[i + k][1],
+ k * UNITS_PER_WORD);
}
/* Now loop again and set the alias set of any save areas we made to
if (GET_CODE (inner) == MEM)
{
- int offset;
+ HOST_WIDE_INT offset;
+
/* POS counts from lsb, but make OFFSET count in memory order. */
if (BYTES_BIG_ENDIAN)
offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
else
offset = pos / BITS_PER_UNIT;
- new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset));
- MEM_COPY_ATTRIBUTES (new, inner);
+ new = adjust_address_nv (inner, tmode, offset);
}
else if (GET_CODE (inner) == REG)
{
a SUBREG and it would sometimes return a new hard register. */
if (tmode != inner_mode)
{
- int final_word = pos / BITS_PER_WORD;
+ HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
if (WORDS_BIG_ENDIAN
&& GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
- GET_MODE_SIZE (wanted_inner_mode) - offset);
if (offset != 0 || inner_mode != wanted_inner_mode)
- {
- rtx newmem = gen_rtx_MEM (wanted_inner_mode,
- plus_constant (XEXP (inner, 0), offset));
-
- MEM_COPY_ATTRIBUTES (newmem, inner);
- inner = newmem;
- }
+ inner = adjust_address_nv (inner, wanted_inner_mode, offset);
}
/* If INNER is not memory, we can always get it into the proper mode. If we
&& (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
MODE_INT, 1)) != BLKmode)
{
- if (BYTES_BIG_ENDIAN)
- new = gen_rtx_MEM (tmode, XEXP (varop, 0));
- else
- new = gen_rtx_MEM (tmode,
- plus_constant (XEXP (varop, 0),
- count / BITS_PER_UNIT));
+ new = adjust_address_nv (varop, tmode,
+ BYTES_BIG_ENDIAN ? 0
+ : count / BITS_PER_UNIT);
- MEM_COPY_ATTRIBUTES (new, varop);
varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
: ZERO_EXTEND, mode, new);
count = 0;
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
}
- new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
- MEM_COPY_ATTRIBUTES (new, x);
- return new;
+
+ return adjust_address_nv (x, mode, offset);
}
/* If X is a comparison operator, rewrite it in a new mode. This
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
if (BYTES_BIG_ENDIAN)
- {
- /* Adjust the address so that the address-after-the-data is
- unchanged. */
- offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
- }
- new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
+ /* Adjust the address so that the address-after-the-data is
+ unchanged. */
+ offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
+ - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
+
+ new = adjust_address_nv (x, mode, offset);
if (! memory_address_p (mode, XEXP (new, 0)))
return 0;
- MEM_COPY_ATTRIBUTES (new, x);
+
return new;
}
else
cselib_val *addr_elt, *mem_elt;
rtx x;
{
- rtx new;
struct elt_loc_list *l;
/* Avoid duplicates. */
&& CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt)
return;
- new = gen_rtx_MEM (GET_MODE (x), addr_elt->u.val_rtx);
- MEM_COPY_ATTRIBUTES (new, x);
-
addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt);
- mem_elt->locs = new_elt_loc_list (mem_elt->locs, new);
+ mem_elt->locs
+ = new_elt_loc_list (mem_elt->locs,
+ replace_equiv_address_nv (x, addr_elt->u.val_rtx));
}
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
/* Form a new MEM at the requested address. */
if (GET_CODE (op) == MEM)
{
- rtx addr = plus_constant (XEXP (op, 0), (offset * UNITS_PER_WORD));
- rtx new;
+ rtx new = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
- if (validate_address)
+ if (! validate_address)
+ return new;
+
+ else if (reload_completed)
{
- if (reload_completed)
- {
- if (! strict_memory_address_p (word_mode, addr))
- return 0;
- }
- else
- addr = memory_address (word_mode, addr);
+ if (! strict_memory_address_p (word_mode, XEXP (new, 0)))
+ return 0;
}
-
- new = gen_rtx_MEM (word_mode, addr);
- MEM_COPY_ATTRIBUTES (new, op);
- return new;
+ else
+ return replace_equiv_address (new, XEXP (new, 0));
}
/* Rest can be handled by simplify_subreg. */
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR.
(VOIDmode means don't change the mode.
- NULL for ADDR means don't change the address.) */
+ NULL for ADDR means don't change the address.)
+ VALIDATE is nonzero if the returned memory location is required to be
+ valid. */
rtx
-change_address (memref, mode, addr)
+change_address_1 (memref, mode, addr, validate)
rtx memref;
enum machine_mode mode;
rtx addr;
+ int validate;
{
rtx new;
if (addr == 0)
addr = XEXP (memref, 0);
- /* If reload is in progress, don't check for validity of the address since we
- assume the caller knows what they are doing. If reload has completed, the
- address must be valid. Otherwise, we call memory_address to make it
- valid. */
- if (reload_in_progress)
- ;
- else if (reload_completed)
+ if (validate)
{
- if (! memory_address_p (mode, addr))
- abort ();
+ if (reload_in_progress || reload_completed)
+ {
+ if (! memory_address_p (mode, addr))
+ abort ();
+ }
+ else
+ addr = memory_address (mode, addr);
}
- else
- addr = memory_address (mode, addr);
if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
return memref;
change_address (memref, mode, plus_constant (XEXP (memref, 0), offset));
}
+/* Likewise, but the reference is not required to be valid. */
+
+rtx
+adjust_address_nv (memref, mode, offset)
+ rtx memref;
+ enum machine_mode mode;
+ HOST_WIDE_INT offset;
+{
+ /* For now, this is just a wrapper for change_address, but eventually
+ will do memref tracking. */
+ return change_address_1 (memref, mode,
+ plus_constant (XEXP (memref, 0), offset), 0);
+}
+
/* Return a memory reference like MEMREF, but with its address changed to
ADDR. The caller is asserting that the actual piece of memory pointed
to is the same, just the form of the address is being changed, such as
will do memref tracking. */
return change_address (memref, VOIDmode, addr);
}
+/* Likewise, but the reference is not required to be valid. */
+
+rtx
+replace_equiv_address_nv (memref, addr)
+ rtx memref;
+ rtx addr;
+{
+ /* For now, this is just a wrapper for change_address, but eventually
+ will do memref tracking. */
+ return change_address_1 (memref, VOIDmode, addr, 0);
+}
\f
/* Return a newly created CODE_LABEL rtx with a unique label number. */
stabilize (x)
rtx x;
{
- register rtx addr;
- if (GET_CODE (x) != MEM)
+ if (GET_CODE (x) != MEM
+ || ! rtx_unstable_p (XEXP (x, 0)))
return x;
- addr = XEXP (x, 0);
- if (rtx_unstable_p (addr))
- {
- rtx temp = force_reg (Pmode, copy_all_regs (addr));
- rtx mem = gen_rtx_MEM (GET_MODE (x), temp);
-
- MEM_COPY_ATTRIBUTES (mem, x);
- return mem;
- }
- return x;
+ return
+ replace_equiv_address (x, force_reg (Pmode, copy_all_regs (XEXP (x, 0))));
}
\f
/* Copy the value or contents of X to a new temp reg and return that reg. */
if (code == MEM && GET_MODE (x) != BLKmode
&& GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
{
- register rtx y = XEXP (x, 0);
- register rtx new = gen_rtx_MEM (GET_MODE (x), QUEUED_VAR (y));
-
- MEM_COPY_ATTRIBUTES (new, x);
+ rtx y = XEXP (x, 0);
+ rtx new = replace_equiv_address_nv (x, QUEUED_VAR (y));
if (QUEUED_INSN (y))
{
- register rtx temp = gen_reg_rtx (GET_MODE (new));
+ rtx temp = gen_reg_rtx (GET_MODE (x));
+
emit_insn_before (gen_move_insn (temp, new),
QUEUED_INSN (y));
return temp;
}
+
/* Copy the address into a pseudo, so that the returned value
remains correct across calls to emit_queue. */
- XEXP (new, 0) = copy_to_reg (XEXP (new, 0));
- return new;
+ return replace_equiv_address (new, copy_to_reg (XEXP (new, 0)));
}
+
/* Otherwise, recursively protect the subexpressions of all
the kinds of rtx's that can contain a QUEUED. */
if (code == MEM)
{
if (data->autinc_to)
{
- to1 = gen_rtx_MEM (mode, data->to_addr);
- MEM_COPY_ATTRIBUTES (to1, data->to);
+ to1 = replace_equiv_address (data->to, data->to_addr);
+ to1 = adjust_address (to1, mode, 0);
}
else
to1 = adjust_address (data->to, mode, data->offset);
if (data->autinc_from)
{
- from1 = gen_rtx_MEM (mode, data->from_addr);
- MEM_COPY_ATTRIBUTES (from1, data->from);
+ from1 = replace_equiv_address (data->from, data->from_addr);
+ from1 = adjust_address (from1, mode, 0);
}
else
from1 = adjust_address (data->from, mode, data->offset);
if (data->autinc_to)
{
- to1 = gen_rtx_MEM (mode, data->to_addr);
- MEM_COPY_ATTRIBUTES (to1, data->to);
+ to1 = replace_equiv_address (data->to, data->to_addr);
+ to1 = adjust_address (to1, mode, 0);
}
else
to1 = adjust_address (data->to, mode, data->offset);
is scheduled for replacement. */
if (reload_in_progress && GET_CODE (x) == MEM
&& (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
- {
- rtx new = gen_rtx_MEM (GET_MODE (x), inner);
-
- MEM_COPY_ATTRIBUTES (new, x);
- x = new;
- }
+ x = replace_equiv_address_nv (x, inner);
if (reload_in_progress && GET_CODE (y) == MEM
&& (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
- {
- rtx new = gen_rtx_MEM (GET_MODE (y), inner);
-
- MEM_COPY_ATTRIBUTES (new, y);
- y = new;
- }
+ y = replace_equiv_address_nv (y, inner);
start_sequence ();
/* Get a reference to just this component. */
if (modifier == EXPAND_CONST_ADDRESS
|| modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
- {
- rtx new = gen_rtx_MEM (mode1,
- plus_constant (XEXP (op0, 0),
- (bitpos / BITS_PER_UNIT)));
-
- MEM_COPY_ATTRIBUTES (new, op0);
- op0 = new;
- }
+ op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT);
else
op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR.
(VOIDmode means don't change the mode.
- NULL for ADDR means don't change the address.) */
-extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
+ NULL for ADDR means don't change the address.)
+ VALIDATE is nonzero if the returned memory location is required to be
+ valid. */
+extern rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx, int));
+
+#define change_address(MEMREF, MODE, ADDR) \
+ change_address_1 (MEMREF, MODE, ADDR, 1)
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address offset by OFFSET bytes. */
extern rtx adjust_address PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
+/* Likewise, but the reference is not required to be valid. */
+extern rtx adjust_address_nv PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
+
/* Return a memory reference like MEMREF, but with its address changed to
ADDR. The caller is asserting that the actual piece of memory pointed
to is the same, just the form of the address is being changed, such as
by putting something into a register. */
extern rtx replace_equiv_address PARAMS ((rtx, rtx));
+/* Likewise, but the reference is not required to be valid. */
+extern rtx replace_equiv_address_nv PARAMS ((rtx, rtx));
+
/* Return a memory reference like MEMREF, but which is known to have a
valid address. */
extern rtx validize_mem PARAMS ((rtx));
}
else if (GET_CODE (y) == MEM)
{
- register int offset = SUBREG_BYTE (x);
+ HOST_WIDE_INT offset = SUBREG_BYTE (x);
/* Catch these instead of generating incorrect code. */
if ((offset % GET_MODE_SIZE (GET_MODE (x))) != 0)
pos %= GET_MODE_BITSIZE (wanted_mode);
- newmem = gen_rtx_MEM (wanted_mode,
- plus_constant (XEXP (tem, 0), offset));
- MEM_COPY_ATTRIBUTES (newmem, tem);
+ newmem = adjust_address_nv (tem, wanted_mode, offset);
/* Make the change and see if the insn remains valid. */
INSN_CODE (insn) = -1;
pos %= GET_MODE_BITSIZE (wanted_mode);
- newmem = gen_rtx_MEM (wanted_mode,
- plus_constant (XEXP (tem, 0),
- offset));
- MEM_COPY_ATTRIBUTES (newmem, tem);
+ newmem = adjust_address_nv (tem, wanted_mode, offset);
/* Make the change and see if the insn remains valid. */
INSN_CODE (insn) = -1;
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
{
rtx sub = XEXP (XEXP (x, 0), 0);
- rtx sub2;
if (GET_CODE (sub) == MEM)
- {
- sub2 = gen_rtx_MEM (GET_MODE (x), copy_rtx (XEXP (sub, 0)));
- MEM_COPY_ATTRIBUTES (sub2, sub);
- sub = sub2;
- }
+ sub = adjust_address_nv (sub, GET_MODE (x), 0);
else if (GET_CODE (sub) == REG
&& (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
;
x = gen_lowpart_common (tmode, x1);
if (x == 0 && GET_CODE (x1) == MEM)
{
- x = gen_rtx_MEM (tmode, XEXP (x1, 0));
- MEM_COPY_ATTRIBUTES (x, x1);
+ x = adjust_address_nv (x1, tmode, 0);
copy_replacements (x1, x);
}
y = gen_lowpart_common (tmode, y1);
if (y == 0 && GET_CODE (y1) == MEM)
{
- y = gen_rtx_MEM (tmode, XEXP (y1, 0));
- MEM_COPY_ATTRIBUTES (y, y1);
+ y = adjust_address_nv (y1, tmode, 0);
copy_replacements (y1, y);
}
}
#include "hard-reg-set.h"
#include "recog.h"
#include "regs.h"
+#include "expr.h"
#include "function.h"
#include "flags.h"
#include "real.h"
pos %= GET_MODE_BITSIZE (wanted_mode);
- newmem = gen_rtx_MEM (wanted_mode,
- plus_constant (XEXP (XEXP (x, 0), 0),
- offset));
- MEM_COPY_ATTRIBUTES (newmem, XEXP (x, 0));
+ newmem = adjust_address_nv (XEXP (x, 0), wanted_mode, offset);
validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
validate_change (object, &XEXP (x, 0), newmem, 1);
validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
for (ml = memlist; ml ; ml = ml->next)
- {
- HOST_WIDE_INT c = ml->sp_offset - delta;
- rtx new = gen_rtx_MEM (GET_MODE (*ml->mem),
- plus_constant (stack_pointer_rtx, c));
-
- MEM_COPY_ATTRIBUTES (new, *ml->mem);
- validate_change (ml->insn, ml->mem, new, 1);
- }
+ validate_change
+ (ml->insn, ml->mem,
+ replace_equiv_address_nv (*ml->mem,
+ plus_constant (stack_pointer_rtx,
+ ml->sp_offset - delta)), 1);
if (apply_change_group ())
{
/* 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 (GET_CODE (XEXP (in, 0)) == POST_INC
- || GET_CODE (XEXP (in, 0)) == POST_DEC
- || GET_CODE (XEXP (in, 0)) == POST_MODIFY)
- {
- rtx new = gen_rtx_MEM (GET_MODE (in), XEXP (XEXP (in, 0), 0));
+ switch (GET_CODE (XEXP (in, 0)))
+ {
+ case POST_INC: case POST_DEC: case POST_MODIFY:
+ in = replace_equiv_address_nv (in, XEXP (XEXP (in, 0), 0));
+ break;
- MEM_COPY_ATTRIBUTES (new, in);
- in = new;
- }
- if (GET_CODE (XEXP (in, 0)) == PRE_INC
- || GET_CODE (XEXP (in, 0)) == PRE_DEC
- || GET_CODE (XEXP (in, 0)) == PRE_MODIFY)
- {
- rtx new = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
+ case PRE_INC: case PRE_DEC: case PRE_MODIFY:
+ out = replace_equiv_address_nv (out, XEXP (XEXP (out, 0), 0));
+ break;
- MEM_COPY_ATTRIBUTES (new, out);
- out = new;
- }
+ default:
+ break;
}
/* If we are reloading a (SUBREG constant ...), really reload just the
if (rtx_varies_p (tem, 0))
tem = copy_rtx (tem);
- tem = gen_rtx_MEM (GET_MODE (ad), tem);
- MEM_COPY_ATTRIBUTES (tem, reg_equiv_memory_loc[regno]);
- return tem;
+ tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
+ return adjust_address_nv (tem, GET_MODE (ad), 0);
}
/* Record all reloads needed for handling memory address AD
/* If we have any adjustment to make, or if the stack slot is the
wrong mode, make a new stack slot. */
if (adjust != 0 || GET_MODE (x) != GET_MODE (regno_reg_rtx[i]))
- {
- rtx new = gen_rtx_MEM (GET_MODE (regno_reg_rtx[i]),
- plus_constant (XEXP (x, 0), adjust));
-
- MEM_COPY_ATTRIBUTES (new, x);
- x = new;
- }
+ x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);
/* Save the stack slot for later. */
reg_equiv_memory_loc[i] = x;
/* Our only special processing is to pass the mode of the MEM to our
recursive call and copy the flags. While we are here, handle this
case more efficiently. */
- new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
- if (new != XEXP (x, 0))
- {
- new = gen_rtx_MEM (GET_MODE (x), new);
- MEM_COPY_ATTRIBUTES (new, x);
- return new;
- }
- else
- return x;
+ return
+ replace_equiv_address_nv (x,
+ eliminate_regs (XEXP (x, 0),
+ GET_MODE (x), insn));
case USE:
/* Handle insn_list USE that a call to a pure function may generate. */
default:
if (GET_CODE (x) == MEM)
- {
- /* We can't use change_address here, since it verifies memory address
- for corectness. We don't want such check, since we may handle
- addresses previously incorect (such as ones in push instructions)
- and it is caller's work to verify whether resulting insn match. */
- rtx addr = simplify_replace_rtx (XEXP (x, 0), old, new);
- rtx mem;
- if (XEXP (x, 0) != addr)
- {
- mem = gen_rtx_MEM (GET_MODE (x), addr);
- MEM_COPY_ATTRIBUTES (mem, x);
- }
- else
- mem = x;
- return mem;
- }
+ return
+ replace_equiv_address_nv (x,
+ simplify_replace_rtx (XEXP (x, 0),
+ old, new));
return x;
}
|| (mov_optab->handlers[(int) innermode].insn_code
== CODE_FOR_nothing))
&& GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op)))
- {
- rtx new;
-
- new = gen_rtx_MEM (outermode, plus_constant (XEXP (op, 0), byte));
- MEM_COPY_ATTRIBUTES (new, op);
- return new;
- }
+ return adjust_address_nv (op, outermode, byte);
/* Handle complex values represented as CONCAT
of real and imaginary part. */
if (mode == GET_MODE (x))
SET_DECL_RTL (decl_elt, x);
else
- {
- SET_DECL_RTL (decl_elt,
- gen_rtx_MEM (mode, copy_rtx (XEXP (x, 0))));
- MEM_COPY_ATTRIBUTES (DECL_RTL (decl_elt), x);
- }
+ SET_DECL_RTL (decl_elt, adjust_address_nv (x, mode, 0));
}
else if (GET_CODE (x) == REG)
{