Commit a7c99304 by Richard Kenner

*** empty log message ***

From-SVN: r689
parent 8b3686ed
...@@ -3521,6 +3521,13 @@ subst (x, from, to, in_dest, unique_copy) ...@@ -3521,6 +3521,13 @@ subst (x, from, to, in_dest, unique_copy)
} }
break; break;
case FFS:
/* (ffs (*_extend <X>)) = (ffs <X>) */
if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
|| GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
break;
case FLOAT: case FLOAT:
/* (float (sign_extend <X>)) = (float <X>). */ /* (float (sign_extend <X>)) = (float <X>). */
if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND) if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
...@@ -4145,7 +4152,20 @@ make_compound_operation (x, in_code) ...@@ -4145,7 +4152,20 @@ make_compound_operation (x, in_code)
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE); 0, in_code == COMPARE);
/* One machines without logical shifts, if the operand of the AND is
/* If we are have (and (rotate X C) M) and C is larger than the number
of bits in M, this is an extraction. */
else if (GET_CODE (XEXP (x, 0)) == ROTATE
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
&& i <= INTVAL (XEXP (XEXP (x, 0), 1)))
new = make_extraction (mode, XEXP (XEXP (x, 0), 0),
(GET_MODE_BITSIZE (mode)
- INTVAL (XEXP (XEXP (x, 0), 1))),
0, i, 1, 0, in_code == COMPARE);
/* On machines without logical shifts, if the operand of the AND is
a logical shift and our mask turns off all the propagated sign a logical shift and our mask turns off all the propagated sign
bits, we can replace the logical shift with an arithmetic shift. */ bits, we can replace the logical shift with an arithmetic shift. */
else if ( else if (
...@@ -6191,7 +6211,7 @@ gen_lowpart_for_combine (mode, x) ...@@ -6191,7 +6211,7 @@ gen_lowpart_for_combine (mode, x)
/* If we couldn't simplify X any other way, just enclose it in a /* If we couldn't simplify X any other way, just enclose it in a
SUBREG. Normally, this SUBREG won't match, but some patterns may SUBREG. Normally, this SUBREG won't match, but some patterns may
include and explicit SUBREG or we may simplify it further in combine. */ include an explicit SUBREG or we may simplify it further in combine. */
else else
{ {
int word = 0; int word = 0;
...@@ -7609,15 +7629,31 @@ move_deaths (x, from_cuid, to_insn, pnotes) ...@@ -7609,15 +7629,31 @@ move_deaths (x, from_cuid, to_insn, pnotes)
move_deaths (SET_SRC (x), from_cuid, to_insn, pnotes); move_deaths (SET_SRC (x), from_cuid, to_insn, pnotes);
if (GET_CODE (dest) == ZERO_EXTRACT) /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
that accesses one word of a multi-word item, some
piece of everything register in the expression is used by
this insn, so remove any old death. */
if (GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART
|| (GET_CODE (dest) == SUBREG
&& (((GET_MODE_SIZE (GET_MODE (dest))
+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)
== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
+ UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
{ {
move_deaths (XEXP (dest, 1), from_cuid, to_insn, pnotes); move_deaths (dest, from_cuid, to_insn, pnotes);
move_deaths (XEXP (dest, 2), from_cuid, to_insn, pnotes); return;
} }
while (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG /* If this is some other SUBREG, we know it replaces the entire
|| GET_CODE (dest) == STRICT_LOW_PART) value, so use that as the destination. */
dest = XEXP (dest, 0); if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
/* If this is a MEM, adjust deaths of anything used in the address.
For a REG (the only other possibility), the entire value is
being replaced so the old value is not used in this insn. */
if (GET_CODE (dest) == MEM) if (GET_CODE (dest) == MEM)
move_deaths (XEXP (dest, 0), from_cuid, to_insn, pnotes); move_deaths (XEXP (dest, 0), from_cuid, to_insn, pnotes);
...@@ -7643,25 +7679,48 @@ move_deaths (x, from_cuid, to_insn, pnotes) ...@@ -7643,25 +7679,48 @@ move_deaths (x, from_cuid, to_insn, pnotes)
} }
} }
/* Return 1 if REG is the target of a bit-field assignment in BODY, the /* Return 1 if X is the target of a bit-field assignment in BODY, the
pattern of an insn. */ pattern of an insn. X must be a REG. */
static int static int
reg_bitfield_target_p (reg, body) reg_bitfield_target_p (x, body)
rtx reg; rtx x;
rtx body; rtx body;
{ {
int i; int i;
if (GET_CODE (body) == SET) if (GET_CODE (body) == SET)
return ((GET_CODE (SET_DEST (body)) == ZERO_EXTRACT {
&& rtx_equal_p (reg, XEXP (SET_DEST (body), 0))) rtx dest = SET_DEST (body);
|| (GET_CODE (SET_DEST (body)) == STRICT_LOW_PART rtx target;
&& rtx_equal_p (reg, SUBREG_REG (XEXP (SET_DEST (body), 0))))); int regno, tregno, endregno, endtregno;
if (GET_CODE (dest) == ZERO_EXTRACT)
target = XEXP (dest, 0);
else if (GET_CODE (dest) == STRICT_LOW_PART)
target = SUBREG_REG (XEXP (dest, 0));
else
return 0;
if (GET_CODE (target) == SUBREG)
target = SUBREG_REG (target);
if (GET_CODE (target) != REG)
return 0;
tregno = REGNO (target), regno = REGNO (x);
if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
return target == x;
endtregno = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (target));
endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
return endregno > tregno && regno < endtregno;
}
else if (GET_CODE (body) == PARALLEL) else if (GET_CODE (body) == PARALLEL)
for (i = XVECLEN (body, 0) - 1; i >= 0; i--) for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
if (reg_bitfield_target_p (reg, XVECEXP (body, 0, i))) if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
return 1; return 1;
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment