From: Richard Kenner Date: Fri, 17 Jul 1992 09:52:19 +0000 (-0400) Subject: *** empty log message *** X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=df62f951d005dd50be23fd6e28f3ed813b708251;p=gcc.git *** empty log message *** From-SVN: r1611 --- diff --git a/gcc/combine.c b/gcc/combine.c index ba100ad0e81..b3865ed06d2 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3182,49 +3182,6 @@ subst (x, from, to, in_dest, unique_copy) /* Convert this into a field assignment operation, if possible. */ x = make_field_assignment (x); - /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some - operation, and X being a REG or (subreg (reg)), we may be able to - convert this to (set (subreg:m2 x) (op)). - - We can always do this if M1 is narrower than M2 because that - means that we only care about the low bits of the result. - - However, on most machines (those with BYTE_LOADS_ZERO_EXTEND - not defined), we cannot perform a narrower operation that - requested since the high-order bits will be undefined. On - machine where BYTE_LOADS_ZERO_EXTEND are defined, however, this - transformation is safe as long as M1 and M2 have the same number - of words. */ - - if (GET_CODE (SET_SRC (x)) == SUBREG - && subreg_lowpart_p (SET_SRC (x)) - && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) != 'o' - && (((GET_MODE_SIZE (GET_MODE (SET_SRC (x))) + (UNITS_PER_WORD - 1)) - / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) -#ifndef BYTE_LOADS_ZERO_EXTEND - && (GET_MODE_SIZE (GET_MODE (SET_SRC (x))) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) -#endif - && (GET_CODE (SET_DEST (x)) == REG - || (GET_CODE (SET_DEST (x)) == SUBREG - && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))) - { - /* Get the object that will be the SUBREG_REG of the - SUBREG we are making. Note that SUBREG_WORD will always - be zero because this will either be a paradoxical SUBREG - or a SUBREG with the same number of words on the outside and - inside. */ - rtx object = (GET_CODE (SET_DEST (x)) == REG ? SET_DEST (x) - : SUBREG_REG (SET_DEST (x))); - - SUBST (SET_DEST (x), - gen_rtx (SUBREG, GET_MODE (SUBREG_REG (SET_SRC (x))), - object, 0)); - SUBST (SET_SRC (x), SUBREG_REG (SET_SRC (x))); - } - /* If we are setting CC0 or if the source is a COMPARE, look for the use of the comparison result and try to simplify it unless we already have used undobuf.other_insn. */ @@ -3356,6 +3313,49 @@ subst (x, from, to, in_dest, unique_copy) SUBST (SET_SRC (x), temp); } + /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some + operation, and X being a REG or (subreg (reg)), we may be able to + convert this to (set (subreg:m2 x) (op)). + + We can always do this if M1 is narrower than M2 because that + means that we only care about the low bits of the result. + + However, on most machines (those with BYTE_LOADS_ZERO_EXTEND + not defined), we cannot perform a narrower operation that + requested since the high-order bits will be undefined. On + machine where BYTE_LOADS_ZERO_EXTEND are defined, however, this + transformation is safe as long as M1 and M2 have the same number + of words. */ + + if (GET_CODE (SET_SRC (x)) == SUBREG + && subreg_lowpart_p (SET_SRC (x)) + && GET_RTX_CLASS (GET_CODE (SUBREG_REG (SET_SRC (x)))) != 'o' + && (((GET_MODE_SIZE (GET_MODE (SET_SRC (x))) + (UNITS_PER_WORD - 1)) + / UNITS_PER_WORD) + == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))) + + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) +#ifndef BYTE_LOADS_ZERO_EXTEND + && (GET_MODE_SIZE (GET_MODE (SET_SRC (x))) + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) +#endif + && (GET_CODE (SET_DEST (x)) == REG + || (GET_CODE (SET_DEST (x)) == SUBREG + && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))) + { + /* Get the object that will be the SUBREG_REG of the + SUBREG we are making. Note that SUBREG_WORD will always + be zero because this will either be a paradoxical SUBREG + or a SUBREG with the same number of words on the outside and + inside. */ + rtx object = (GET_CODE (SET_DEST (x)) == REG ? SET_DEST (x) + : SUBREG_REG (SET_DEST (x))); + + SUBST (SET_DEST (x), + gen_rtx (SUBREG, GET_MODE (SUBREG_REG (SET_SRC (x))), + object, 0)); + SUBST (SET_SRC (x), SUBREG_REG (SET_SRC (x))); + } + #ifdef BYTE_LOADS_ZERO_EXTEND /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this would require a paradoxical subreg. @@ -4029,10 +4029,11 @@ make_extraction (mode, inner, pos, pos_rtx, len, if (tmode != BLKmode && ! (spans_byte && inner_mode != tmode) - && ((pos == 0 && GET_CODE (inner) == REG + && ((pos == 0 && GET_CODE (inner) != MEM && (! in_dest - || (movstrict_optab->handlers[(int) tmode].insn_code - != CODE_FOR_nothing))) + || (GET_CODE (inner) == REG + && (movstrict_optab->handlers[(int) tmode].insn_code + != CODE_FOR_nothing)))) || (GET_CODE (inner) == MEM && pos >= 0 && (pos % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) @@ -4051,7 +4052,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, adjust the offset. Otherwise, we do if bytes big endian. If INNER is not a MEM, get a piece consisting of the just the field - of interest (in this case INNER must be a REG and POS must be 0). */ + of interest (in this case POS must be 0). */ if (GET_CODE (inner) == MEM) { @@ -4066,7 +4067,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, MEM_VOLATILE_P (new) = MEM_VOLATILE_P (inner); MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (inner); } - else if (GET_MODE (inner) == REG) + else if (GET_CODE (inner) == REG) /* We can't call gen_lowpart_for_combine here since we always want a SUBREG and it would sometimes return a new hard register. */ new = gen_rtx (SUBREG, tmode, inner, @@ -4417,7 +4418,7 @@ make_compound_operation (x, in_code) if (new) { - x = new; + x = gen_lowpart_for_combine (mode, new); code = GET_CODE (x); } diff --git a/gcc/reload.c b/gcc/reload.c index b6bcbb2f693..62f8d673d8f 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -476,7 +476,10 @@ push_reload (in, out, inloc, outloc, class, we can't handle it here because CONST_INT does not indicate a mode. Similarly, we must reload the inside expression if we have a - STRICT_LOW_PART (presumably, in == out in the cas). */ + STRICT_LOW_PART (presumably, in == out in the cas). + + Also reload the inner expression if it does not require a secondary + reload but the SUBREG does. */ if (in != 0 && GET_CODE (in) == SUBREG && (GET_CODE (SUBREG_REG (in)) != REG @@ -494,7 +497,15 @@ push_reload (in, out, inloc, outloc, class, && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) / UNITS_PER_WORD) != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)), - GET_MODE (SUBREG_REG (in))))))))) + GET_MODE (SUBREG_REG (in))))))) +#ifdef SECONDARY_INPUT_RELOAD_CLASS + || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS + && (SECONDARY_INPUT_RELOAD_CLASS (class, + GET_MODE (SUBREG_REG (in)), + SUBREG_REG (in)) + == NO_REGS)) +#endif + )) { in_subreg_loc = inloc; inloc = &SUBREG_REG (in); @@ -529,7 +540,15 @@ push_reload (in, out, inloc, outloc, class, && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) / UNITS_PER_WORD) != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)), - GET_MODE (SUBREG_REG (out))))))))) + GET_MODE (SUBREG_REG (out))))))) +#ifdef SECONDARY_OUTPUT_RELOAD_CLASS + || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS + && (SECONDARY_OUTPUT_RELOAD_CLASS (class, + GET_MODE (SUBREG_REG (out)), + SUBREG_REG (out)) + == NO_REGS)) +#endif + )) { out_subreg_loc = outloc; outloc = &SUBREG_REG (out);