Commit 280f58ba by Richard Kenner

(make_compound_operation): Call recursively in the cases where we find a simplification.

(make_compound_operation): Call recursively in the cases where we find a
simplification.
(make_compound_operation, case SUBREG): If the recursive call changes the rtx
code and this is an appropriate SUBREG, use force_to_mode.

From-SVN: r3800
parent 28d10cea
...@@ -4951,6 +4951,7 @@ make_compound_operation (x, in_code) ...@@ -4951,6 +4951,7 @@ make_compound_operation (x, in_code)
enum rtx_code next_code; enum rtx_code next_code;
int i, count; int i, count;
rtx new = 0; rtx new = 0;
rtx tem;
char *fmt; char *fmt;
/* Select the code to be used in recursive calls. Once we are inside an /* Select the code to be used in recursive calls. Once we are inside an
...@@ -4974,9 +4975,12 @@ make_compound_operation (x, in_code) ...@@ -4974,9 +4975,12 @@ make_compound_operation (x, in_code)
if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) >= 0) && INTVAL (XEXP (x, 1)) >= 0)
new = gen_rtx_combine (MULT, mode, XEXP (x, 0), {
GEN_INT ((HOST_WIDE_INT) 1 new = make_compound_operation (XEXP (x, 0), next_code);
<< INTVAL (XEXP (x, 1)))); new = gen_rtx_combine (MULT, mode, new,
GEN_INT ((HOST_WIDE_INT) 1
<< INTVAL (XEXP (x, 1))));
}
break; break;
case AND: case AND:
...@@ -4989,20 +4993,24 @@ make_compound_operation (x, in_code) ...@@ -4989,20 +4993,24 @@ make_compound_operation (x, in_code)
is a logical right shift, make an extraction. */ is a logical right shift, make an extraction. */
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (mode, XEXP (XEXP (x, 0), 0), 0, {
XEXP (XEXP (x, 0), 1), i, 1, new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
0, in_code == COMPARE); new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
0, in_code == COMPARE);
}
/* Same as previous, but for (subreg (lshiftrt ...)) in first op. */ /* Same as previous, but for (subreg (lshiftrt ...)) in first op. */
else if (GET_CODE (XEXP (x, 0)) == SUBREG else if (GET_CODE (XEXP (x, 0)) == SUBREG
&& subreg_lowpart_p (XEXP (x, 0)) && subreg_lowpart_p (XEXP (x, 0))
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), {
XEXP (SUBREG_REG (XEXP (x, 0)), 0), 0, new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, next_code);
0, in_code == COMPARE); new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE);
}
/* If we are have (and (rotate X C) M) and C is larger than the number /* If we are have (and (rotate X C) M) and C is larger than the number
of bits in M, this is an extraction. */ of bits in M, this is an extraction. */
...@@ -5011,10 +5019,13 @@ make_compound_operation (x, in_code) ...@@ -5011,10 +5019,13 @@ make_compound_operation (x, in_code)
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0 && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
&& i <= INTVAL (XEXP (XEXP (x, 0), 1))) && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
new = make_extraction (mode, XEXP (XEXP (x, 0), 0), {
(GET_MODE_BITSIZE (mode) new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
- INTVAL (XEXP (XEXP (x, 0), 1))), new = make_extraction (mode, new,
NULL_RTX, i, 1, 0, in_code == COMPARE); (GET_MODE_BITSIZE (mode)
- INTVAL (XEXP (XEXP (x, 0), 1))),
NULL_RTX, i, 1, 0, in_code == COMPARE);
}
/* On machines without logical shifts, if the operand of the AND is /* 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
...@@ -5033,7 +5044,9 @@ make_compound_operation (x, in_code) ...@@ -5033,7 +5044,9 @@ make_compound_operation (x, in_code)
mask >>= INTVAL (XEXP (XEXP (x, 0), 1)); mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
if ((INTVAL (XEXP (x, 1)) & ~mask) == 0) if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
SUBST (XEXP (x, 0), SUBST (XEXP (x, 0),
gen_rtx_combine (ASHIFTRT, mode, XEXP (XEXP (x, 0), 0), gen_rtx_combine (ASHIFTRT, mode,
make_compound_operation (XEXP (XEXP (x, 0), 0),
next_code),
XEXP (XEXP (x, 0), 1))); XEXP (XEXP (x, 0), 1)));
} }
...@@ -5042,14 +5055,19 @@ make_compound_operation (x, in_code) ...@@ -5042,14 +5055,19 @@ make_compound_operation (x, in_code)
If it doesn't end up being a ZERO_EXTEND, we will ignore it unless If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
we are in a COMPARE. */ we are in a COMPARE. */
else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (mode, XEXP (x, 0), 0, NULL_RTX, i, 1, new = make_extraction (mode,
0, in_code == COMPARE); make_compound_operation (XEXP (x, 0),
next_code),
0, NULL_RTX, i, 1, 0, in_code == COMPARE);
/* If we are in a comparison and this is an AND with a power of two, /* If we are in a comparison and this is an AND with a power of two,
convert this into the appropriate bit extract. */ convert this into the appropriate bit extract. */
else if (in_code == COMPARE else if (in_code == COMPARE
&& (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
new = make_extraction (mode, XEXP (x, 0), i, NULL_RTX, 1, 1, 0, 1); new = make_extraction (mode,
make_compound_operation (XEXP (x, 0),
next_code),
i, NULL_RTX, 1, 1, 0, 1);
break; break;
...@@ -5061,7 +5079,10 @@ make_compound_operation (x, in_code) ...@@ -5061,7 +5079,10 @@ make_compound_operation (x, in_code)
&& mode_width <= HOST_BITS_PER_WIDE_INT && mode_width <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0) && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
{ {
new = gen_rtx_combine (ASHIFTRT, mode, XEXP (x, 0), XEXP (x, 1)); new = gen_rtx_combine (ASHIFTRT, mode,
make_compound_operation (XEXP (x, 0),
next_code),
XEXP (x, 1));
break; break;
} }
...@@ -5074,11 +5095,14 @@ make_compound_operation (x, in_code) ...@@ -5074,11 +5095,14 @@ make_compound_operation (x, in_code)
&& GET_CODE (XEXP (x, 0)) == ASHIFT && GET_CODE (XEXP (x, 0)) == ASHIFT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (x, 0), 1))) && INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (x, 0), 1)))
new = make_extraction (mode, XEXP (XEXP (x, 0), 0), {
(INTVAL (XEXP (x, 1)) new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
- INTVAL (XEXP (XEXP (x, 0), 1))), new = make_extraction (mode, new,
NULL_RTX, mode_width - INTVAL (XEXP (x, 1)), (INTVAL (XEXP (x, 1))
code == LSHIFTRT, 0, in_code == COMPARE); - INTVAL (XEXP (XEXP (x, 0), 1))),
NULL_RTX, mode_width - INTVAL (XEXP (x, 1)),
code == LSHIFTRT, 0, in_code == COMPARE);
}
/* Similarly if we have (ashifrt (OP (ashift foo C1) C3) C2). In these /* Similarly if we have (ashifrt (OP (ashift foo C1) C3) C2). In these
cases, we are better off returning a SIGN_EXTEND of the operation. */ cases, we are better off returning a SIGN_EXTEND of the operation. */
...@@ -5100,9 +5124,10 @@ make_compound_operation (x, in_code) ...@@ -5100,9 +5124,10 @@ make_compound_operation (x, in_code)
= (INTVAL (XEXP (XEXP (x, 0), 1)) = (INTVAL (XEXP (XEXP (x, 0), 1))
>> INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))); >> INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)));
new = make_compound_operation (XEXP (XEXP (XEXP (x, 0), 0), 0),
next_code);
new = make_extraction (mode, new = make_extraction (mode,
gen_binary (GET_CODE (XEXP (x, 0)), mode, gen_binary (GET_CODE (XEXP (x, 0)), mode, new,
XEXP (XEXP (XEXP (x, 0), 0), 0),
GEN_INT (newop1)), GEN_INT (newop1)),
(INTVAL (XEXP (x, 1)) (INTVAL (XEXP (x, 1))
- INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))), - INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))),
...@@ -5116,14 +5141,29 @@ make_compound_operation (x, in_code) ...@@ -5116,14 +5141,29 @@ make_compound_operation (x, in_code)
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == ASHIFT && GET_CODE (XEXP (XEXP (x, 0), 0)) == ASHIFT
&& GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))) && INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
new = make_extraction (mode, {
gen_unary (GET_CODE (XEXP (x, 0)), mode, new = make_compound_operation (XEXP (XEXP (XEXP (x, 0), 0), 0),
XEXP (XEXP (XEXP (x, 0), 0), 0)), next_code);
(INTVAL (XEXP (x, 1)) new = make_extraction (mode,
- INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))), gen_unary (GET_CODE (XEXP (x, 0)), mode,
NULL_RTX, mode_width - INTVAL (XEXP (x, 1)), new, 0),
code == LSHIFTRT, 0, in_code == COMPARE); (INTVAL (XEXP (x, 1))
- INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))),
NULL_RTX, mode_width - INTVAL (XEXP (x, 1)),
code == LSHIFTRT, 0, in_code == COMPARE);
}
break; break;
case SUBREG:
/* Call ourselves recursively on the inner expression. If we are
narrowing the object and it has a different RTL code from
what it originally did, do this SUBREG as a force_to_mode. */
tem = make_compound_operation (SUBREG_REG (x), next_code);
if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
&& subreg_lowpart_p (x))
return force_to_mode (tem, mode, GET_MODE_BITSIZE (mode), NULL_RTX);
} }
if (new) if (new)
......
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