(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
This commit is contained in:
Richard Kenner 1993-03-20 07:11:32 -05:00
parent 28d10ceaf5
commit 280f58bab1

View File

@ -4951,6 +4951,7 @@ make_compound_operation (x, in_code)
enum rtx_code next_code;
int i, count;
rtx new = 0;
rtx tem;
char *fmt;
/* Select the code to be used in recursive calls. Once we are inside an
@ -4974,9 +4975,12 @@ make_compound_operation (x, in_code)
if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) >= 0)
new = gen_rtx_combine (MULT, mode, XEXP (x, 0),
GEN_INT ((HOST_WIDE_INT) 1
<< INTVAL (XEXP (x, 1))));
{
new = make_compound_operation (XEXP (x, 0), next_code);
new = gen_rtx_combine (MULT, mode, new,
GEN_INT ((HOST_WIDE_INT) 1
<< INTVAL (XEXP (x, 1))));
}
break;
case AND:
@ -4989,20 +4993,24 @@ make_compound_operation (x, in_code)
is a logical right shift, make an extraction. */
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& (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,
0, in_code == COMPARE);
{
new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
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. */
else if (GET_CODE (XEXP (x, 0)) == SUBREG
&& subreg_lowpart_p (XEXP (x, 0))
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (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,
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE);
{
new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
next_code);
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
of bits in M, this is an extraction. */
@ -5011,10 +5019,13 @@ make_compound_operation (x, in_code)
&& 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))),
NULL_RTX, i, 1, 0, in_code == COMPARE);
{
new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
new = make_extraction (mode, new,
(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
a logical shift and our mask turns off all the propagated sign
@ -5033,7 +5044,9 @@ make_compound_operation (x, in_code)
mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
if ((INTVAL (XEXP (x, 1)) & ~mask) == 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)));
}
@ -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
we are in a COMPARE. */
else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (mode, XEXP (x, 0), 0, NULL_RTX, i, 1,
0, in_code == COMPARE);
new = make_extraction (mode,
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,
convert this into the appropriate bit extract. */
else if (in_code == COMPARE
&& (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;
@ -5061,7 +5079,10 @@ make_compound_operation (x, in_code)
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& (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;
}
@ -5074,11 +5095,14 @@ make_compound_operation (x, in_code)
&& GET_CODE (XEXP (x, 0)) == ASHIFT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (x, 0), 1)))
new = make_extraction (mode, XEXP (XEXP (x, 0), 0),
(INTVAL (XEXP (x, 1))
- INTVAL (XEXP (XEXP (x, 0), 1))),
NULL_RTX, mode_width - INTVAL (XEXP (x, 1)),
code == LSHIFTRT, 0, in_code == COMPARE);
{
new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
new = make_extraction (mode, new,
(INTVAL (XEXP (x, 1))
- 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
cases, we are better off returning a SIGN_EXTEND of the operation. */
@ -5100,9 +5124,10 @@ make_compound_operation (x, in_code)
= (INTVAL (XEXP (XEXP (x, 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,
gen_binary (GET_CODE (XEXP (x, 0)), mode,
XEXP (XEXP (XEXP (x, 0), 0), 0),
gen_binary (GET_CODE (XEXP (x, 0)), mode, new,
GEN_INT (newop1)),
(INTVAL (XEXP (x, 1))
- INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))),
@ -5116,14 +5141,29 @@ make_compound_operation (x, in_code)
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == ASHIFT
&& GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
new = make_extraction (mode,
gen_unary (GET_CODE (XEXP (x, 0)), mode,
XEXP (XEXP (XEXP (x, 0), 0), 0)),
(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);
{
new = make_compound_operation (XEXP (XEXP (XEXP (x, 0), 0), 0),
next_code);
new = make_extraction (mode,
gen_unary (GET_CODE (XEXP (x, 0)), mode,
new, 0),
(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;
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)