diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-07-29 09:43:27 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-07-29 09:43:27 -0400 |
commit | 922db4bb4e54b4d3b2b65fb7e6242bbb86080275 (patch) | |
tree | 52481ae8d769b7f585abb0a7dd0b41824071f230 | |
parent | 1e63b23a042a8a3776db7662c8c9342d396fc8ab (diff) | |
download | gcc-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.c | 46 |
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; |