mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 12:00:03 -05:00
reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that boiled down to && ! 0.
* reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
boiled down to && ! 0.
* reload.c (find_reloads): Always force (subreg (mem)) to be
reloaded if WORD_REGISTER_OPERATIONS.
* reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
SUBREGs of CONST_INTs.
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
SUBREG_REG if the word count is unchanged, also in the input reload
case. Disable non-applicable sanity checks.
* reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
to require the SUBREG mode to be smaller than the SUBREG_REG mode.
* reload1.c (eliminate_regs): Likewise.
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
SUBREG_REG if the word count is unchanged.
* reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
subregs of identical word size for push_reload.
Various alpha fixes from the mainline sources.
Co-Authored-By: J"orn Rennecke <amylaar@cygnus.co.uk>
Co-Authored-By: Jim Wilson <wilson@cygnus.com>
From-SVN: r19336
This commit is contained in:
committed by
Jeff Law
parent
620a5a20ec
commit
495bf6087a
@@ -1,3 +1,29 @@
|
||||
Mon Apr 20 02:17:37 1998 Richard Henderson <rth@cygnus.com>
|
||||
Jim Wilson <wilson@cygnus.com>
|
||||
J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
|
||||
boiled down to && ! 0.
|
||||
|
||||
* reload.c (find_reloads): Always force (subreg (mem)) to be
|
||||
reloaded if WORD_REGISTER_OPERATIONS.
|
||||
|
||||
* reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
|
||||
SUBREGs of CONST_INTs.
|
||||
|
||||
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
|
||||
SUBREG_REG if the word count is unchanged, also in the input reload
|
||||
case. Disable non-applicable sanity checks.
|
||||
|
||||
* reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
|
||||
to require the SUBREG mode to be smaller than the SUBREG_REG mode.
|
||||
* reload1.c (eliminate_regs): Likewise.
|
||||
|
||||
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
|
||||
SUBREG_REG if the word count is unchanged.
|
||||
* reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
|
||||
subregs of identical word size for push_reload.
|
||||
|
||||
Mon Apr 20 00:58:48 1998 H.J. Lu (hjl@gnu.org)
|
||||
|
||||
* reg-stack.c (subst_asm_stack_regs): Change to return the last
|
||||
|
||||
60
gcc/reload.c
60
gcc/reload.c
@@ -889,6 +889,13 @@ push_reload (in, out, inloc, outloc, class,
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
|
||||
&& INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
|
||||
&& LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
|
||||
#endif
|
||||
#ifdef WORD_REGISTER_OPERATIONS
|
||||
|| ((GET_MODE_SIZE (inmode)
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
|
||||
&& ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
|
||||
((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
|
||||
/ UNITS_PER_WORD)))
|
||||
#endif
|
||||
))
|
||||
|| (GET_CODE (SUBREG_REG (in)) == REG
|
||||
@@ -927,7 +934,7 @@ push_reload (in, out, inloc, outloc, class,
|
||||
in_subreg_loc = inloc;
|
||||
inloc = &SUBREG_REG (in);
|
||||
in = *inloc;
|
||||
#ifndef LOAD_EXTEND_OP
|
||||
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
|
||||
if (GET_CODE (in) == MEM)
|
||||
/* This is supposed to happen only for paradoxical subregs made by
|
||||
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
|
||||
@@ -989,7 +996,15 @@ push_reload (in, out, inloc, outloc, class,
|
||||
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|
||||
|| GET_CODE (SUBREG_REG (out)) == MEM)
|
||||
&& ((GET_MODE_SIZE (outmode)
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
|
||||
#ifdef WORD_REGISTER_OPERATIONS
|
||||
|| ((GET_MODE_SIZE (outmode)
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
|
||||
&& ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
|
||||
((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
|
||||
/ UNITS_PER_WORD)))
|
||||
#endif
|
||||
))
|
||||
|| (GET_CODE (SUBREG_REG (out)) == REG
|
||||
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
|
||||
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
|
||||
@@ -1023,7 +1038,7 @@ push_reload (in, out, inloc, outloc, class,
|
||||
out_subreg_loc = outloc;
|
||||
outloc = &SUBREG_REG (out);
|
||||
out = *outloc;
|
||||
#ifndef LOAD_EXTEND_OP
|
||||
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
|
||||
if (GET_CODE (out) == MEM
|
||||
&& GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
|
||||
abort ();
|
||||
@@ -2757,10 +2772,20 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
register access. If the data is, in fact, in memory we
|
||||
must always load using the size assumed to be in the
|
||||
register and let the insn do the different-sized
|
||||
accesses. */
|
||||
accesses.
|
||||
|
||||
This is doubly true if WORD_REGISTER_OPERATIONS. In
|
||||
this case eliminate_regs has left non-paradoxical
|
||||
subregs for push_reloads to see. Make sure it does
|
||||
by forcing the reload.
|
||||
|
||||
??? When is it right at this stage to have a subreg
|
||||
of a mem that is _not_ to be handled specialy? IMO
|
||||
those should have been reduced to just a mem. */
|
||||
|| ((GET_CODE (operand) == MEM
|
||||
|| (GET_CODE (operand)== REG
|
||||
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
|
||||
#ifndef WORD_REGISTER_OPERATIONS
|
||||
&& (((GET_MODE_BITSIZE (GET_MODE (operand))
|
||||
< BIGGEST_ALIGNMENT)
|
||||
&& (GET_MODE_SIZE (operand_mode[i])
|
||||
@@ -2775,7 +2800,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
&& INTEGRAL_MODE_P (GET_MODE (operand))
|
||||
&& LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
|
||||
#endif
|
||||
))
|
||||
)
|
||||
#endif
|
||||
)
|
||||
/* Subreg of a hard reg which can't handle the subreg's mode
|
||||
or which would handle that mode in the wrong number of
|
||||
registers for subregging to work. */
|
||||
@@ -4162,6 +4189,29 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
|
||||
GET_MODE (SUBREG_REG (x)))) != 0)
|
||||
return tem;
|
||||
|
||||
/* If the SUBREG is wider than a word, the above test will fail.
|
||||
For example, we might have a SImode SUBREG of a DImode SUBREG_REG
|
||||
for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
|
||||
a 32 bit target. We still can - and have to - handle this
|
||||
for non-paradoxical subregs of CONST_INTs. */
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
|
||||
&& reg_equiv_constant[regno] != 0
|
||||
&& GET_CODE (reg_equiv_constant[regno]) == CONST_INT
|
||||
&& (GET_MODE_SIZE (GET_MODE (x))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
|
||||
{
|
||||
int shift = SUBREG_WORD (x) * BITS_PER_WORD;
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
|
||||
- GET_MODE_BITSIZE (GET_MODE (x))
|
||||
- shift);
|
||||
/* Here we use the knowledge that CONST_INTs have a
|
||||
HOST_WIDE_INT field. */
|
||||
if (shift >= HOST_BITS_PER_WIDE_INT)
|
||||
shift = HOST_BITS_PER_WIDE_INT - 1;
|
||||
return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
|
||||
}
|
||||
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
|
||||
&& reg_equiv_constant[regno] != 0
|
||||
&& GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
|
||||
|
||||
@@ -3108,30 +3108,21 @@ eliminate_regs (x, mem_mode, insn, storing)
|
||||
int x_size = GET_MODE_SIZE (GET_MODE (x));
|
||||
int new_size = GET_MODE_SIZE (GET_MODE (new));
|
||||
|
||||
/* When asked to spill a partial word subreg, we need to go
|
||||
ahead and spill the whole thing against the possibility
|
||||
that we reload the whole reg and find garbage at the top. */
|
||||
if (storing
|
||||
&& GET_CODE (new) == MEM
|
||||
&& x_size < new_size
|
||||
&& ((x_size + UNITS_PER_WORD-1) / UNITS_PER_WORD
|
||||
== (new_size + UNITS_PER_WORD-1) / UNITS_PER_WORD))
|
||||
return new;
|
||||
else if (GET_CODE (new) == MEM
|
||||
&& x_size <= new_size
|
||||
#ifdef LOAD_EXTEND_OP
|
||||
/* On these machines we will be reloading what is
|
||||
inside the SUBREG if it originally was a pseudo and
|
||||
the inner and outer modes are both a word or
|
||||
smaller. So leave the SUBREG then. */
|
||||
&& ! (GET_CODE (SUBREG_REG (x)) == REG
|
||||
&& x_size <= UNITS_PER_WORD
|
||||
&& new_size <= UNITS_PER_WORD
|
||||
&& x_size > new_size
|
||||
&& INTEGRAL_MODE_P (GET_MODE (new))
|
||||
&& LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
|
||||
if (GET_CODE (new) == MEM
|
||||
&& ((x_size < new_size
|
||||
#ifdef WORD_REGISTER_OPERATIONS
|
||||
/* On these machines, combine can create rtl of the form
|
||||
(set (subreg:m1 (reg:m2 R) 0) ...)
|
||||
where m1 < m2, and expects something interesting to
|
||||
happen to the entire word. Moreover, it will use the
|
||||
(reg:m2 R) later, expecting all bits to be preserved.
|
||||
So if the number of words is the same, preserve the
|
||||
subreg so that push_reloads can see it. */
|
||||
&& ! ((x_size-1)/UNITS_PER_WORD == (new_size-1)/UNITS_PER_WORD)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
|| (x_size == new_size))
|
||||
)
|
||||
{
|
||||
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
@@ -3271,12 +3262,6 @@ eliminate_regs (x, mem_mode, insn, storing)
|
||||
&& GET_CODE (insn) != INSN_LIST)
|
||||
emit_insn_after (gen_rtx (CLOBBER, VOIDmode, SET_DEST (x)), insn);
|
||||
|
||||
/* If SET_DEST was a partial-word subreg, NEW0 may have been widened
|
||||
to spill the entire register (see SUBREG case above). If the
|
||||
widths of SET_DEST and NEW0 no longer match, adjust NEW1. */
|
||||
if (GET_MODE (SET_DEST (x)) != GET_MODE (new0))
|
||||
new1 = gen_rtx (SUBREG, GET_MODE (new0), new1, 0);
|
||||
|
||||
if (new0 != SET_DEST (x) || new1 != SET_SRC (x))
|
||||
return gen_rtx (SET, VOIDmode, new0, new1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user