parent
a8ddbf69e5
commit
df62f951d0
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
25
gcc/reload.c
25
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);
|
||||
|
|
Loading…
Reference in New Issue