From 86c31b2d150ede7efba5e394716e341396a8b450 Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Mon, 24 May 1993 07:51:12 +0000 Subject: [PATCH] (push_reload): Fix NULL arg in last change. (push_reload): When IN is a subreg of a multiword reg that uses a funny number of registers, and SUBREG_WORD is nonzero, and IN must match an output, reload both the reg and the subreg. From-SVN: r4556 --- gcc/reload.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/gcc/reload.c b/gcc/reload.c index c2555b0..08a21c6 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -616,9 +616,12 @@ push_reload (in, out, inloc, outloc, class, really reload just the inside expression in its own mode. If we have (SUBREG:M1 (REG:M2 ...) ...) with M1 wider than M2 and the register is a pseudo, this will become the same as the above case. - Do the same for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where + 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, if OUT is nonzero, we need to reload the reg *and* + the subreg, so do nothing here, and let following statement handle it.) + Note that the case of (SUBREG (CONST_INT...)...) is handled elsewhere; we can't handle it here because CONST_INT does not indicate a mode. @@ -635,8 +638,10 @@ push_reload (in, out, inloc, outloc, class, && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER && (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))) - || (GET_CODE (SUBREG_REG (in)) == REG - && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER + || (REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER + /* The case where out is nonzero + is handled differently in the following statement. */ + && (out == 0 || SUBREG_WORD (in) == 0) && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)), inmode) || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) @@ -667,6 +672,30 @@ push_reload (in, out, inloc, outloc, class, inmode = GET_MODE (in); } + /* 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. */ + + if (in != 0 && GET_CODE (in) == SUBREG + && GET_CODE (SUBREG_REG (in)) == REG + && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER + && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)), inmode) + || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) + > UNITS_PER_WORD) + && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) + / UNITS_PER_WORD) + != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)), + GET_MODE (SUBREG_REG (in))))))) + { + push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR, + GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type); + } + + /* Similarly for paradoxical and problematical SUBREGs on the output. Note that there is no reason we need worry about the previous value of SUBREG_REG (out); even if wider than out, -- 2.7.4