aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-07-29 09:43:27 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-07-29 09:43:27 -0400
commit922db4bb4e54b4d3b2b65fb7e6242bbb86080275 (patch)
tree52481ae8d769b7f585abb0a7dd0b41824071f230
parent1e63b23a042a8a3776db7662c8c9342d396fc8ab (diff)
downloadgcc-922db4bb4e54b4d3b2b65fb7e6242bbb86080275.zip
gcc-922db4bb4e54b4d3b2b65fb7e6242bbb86080275.tar.gz
gcc-922db4bb4e54b4d3b2b65fb7e6242bbb86080275.tar.bz2
(find_reloads_address_1, case PLUS): When handle SUBREG, add SUBREG_WORD offset to SUBREG_REG register number.
(find_reloads_address_1, case PLUS): When handle SUBREG, add SUBREG_WORD offset to SUBREG_REG register number. (find_reloads_address_1, case SUBREG): If a pseudo register inside a SUBREG is larger than the class, then reload the entire SUBREG. From-SVN: r10197
-rw-r--r--gcc/reload.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 94c9f22..b33eb4b 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4561,12 +4561,18 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
{
op0 = SUBREG_REG (op0);
code0 = GET_CODE (op0);
+ if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
+ op0 = gen_rtx (REG, word_mode,
+ REGNO (op0) + SUBREG_WORD (orig_op0));
}
if (GET_CODE (op1) == SUBREG)
{
op1 = SUBREG_REG (op1);
code1 = GET_CODE (op1);
+ if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
+ op1 = gen_rtx (REG, GET_MODE (op1),
+ REGNO (op1) + SUBREG_WORD (orig_op1));
}
if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
@@ -4828,21 +4834,37 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
return 0;
case SUBREG:
- /* If this is a SUBREG of a hard register and the resulting register is
- of the wrong class, reload the whole SUBREG. This avoids needless
- copies if SUBREG_REG is multi-word. */
- if (GET_CODE (SUBREG_REG (x)) == REG
- && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
+ if (GET_CODE (SUBREG_REG (x)) == REG)
{
- int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
+ /* If this is a SUBREG of a hard register and the resulting register
+ is of the wrong class, reload the whole SUBREG. This avoids
+ needless copies if SUBREG_REG is multi-word. */
+ if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
+ {
+ int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
- : REGNO_OK_FOR_BASE_P (regno)))
+ if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
+ : REGNO_OK_FOR_BASE_P (regno)))
+ {
+ push_reload (x, NULL_RTX, loc, NULL_PTR,
+ context ? INDEX_REG_CLASS : BASE_REG_CLASS,
+ GET_MODE (x), VOIDmode, 0, 0, opnum, type);
+ return 1;
+ }
+ }
+ /* If this is a SUBREG of a pseudo-register, and the psuedo-register
+ is larger than the class size, then reload the whole SUBREG. */
+ else
{
- push_reload (x, NULL_RTX, loc, NULL_PTR,
- context ? INDEX_REG_CLASS : BASE_REG_CLASS,
- GET_MODE (x), VOIDmode, 0, 0, opnum, type);
- return 1;
+ enum reg_class class = (context
+ ? INDEX_REG_CLASS : BASE_REG_CLASS);
+ if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
+ > reg_class_size[class])
+ {
+ push_reload (x, NULL_RTX, loc, NULL_PTR, class,
+ GET_MODE (x), VOIDmode, 0, 0, opnum, type);
+ return 1;
+ }
}
}
break;