(push_reload): Add case for output reload of a SUBREG of a hard reg when output mode is invalid for that mode.

(push_reload): Add case for output reload of a SUBREG
of a hard reg when output mode is invalid for that mode.
In both that case and existing case for in, don't remove SUBREG.

From-SVN: r10294
This commit is contained in:
Richard Kenner 1995-08-31 08:30:38 -04:00
parent 1604422ce4
commit 74347d76f0
1 changed files with 35 additions and 2 deletions

View File

@ -734,6 +734,7 @@ push_reload (in, out, inloc, outloc, class,
{
register int i;
int dont_share = 0;
int dont_remove_subreg = 0;
rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
int secondary_in_reload = -1, secondary_out_reload = -1;
enum insn_code secondary_in_icode = CODE_FOR_nothing;
@ -902,6 +903,7 @@ push_reload (in, out, inloc, outloc, class,
{
push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type);
dont_remove_subreg = 1;
}
@ -963,6 +965,35 @@ push_reload (in, out, inloc, outloc, class,
outmode = GET_MODE (out);
}
/* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
either M1 is not valid for R or M2 is wider than a word but we only
need one word to store an M2-sized quantity in R.
However, we must reload the inner reg *as well as* the subreg in
that case. In this case, the inner reg is an in-out reload. */
if (out != 0 && GET_CODE (out) == SUBREG
&& GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode)
|| (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)
!= HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
GET_MODE (SUBREG_REG (out)))))))
{
if (type == RELOAD_OTHER)
abort ();
dont_remove_subreg = 1;
push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
&SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0,
opnum, RELOAD_OTHER);
}
/* 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)
@ -973,14 +1004,16 @@ push_reload (in, out, inloc, outloc, class,
simplifies some of the cases below. */
if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
&& ! dont_remove_subreg)
in = gen_rtx (REG, GET_MODE (in),
REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
/* Similarly for OUT. */
if (out != 0 && GET_CODE (out) == SUBREG
&& GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ! dont_remove_subreg)
out = gen_rtx (REG, GET_MODE (out),
REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));