Commit 3c3279fb by Richard Earnshaw Committed by Richard Earnshaw

re PR target/56470 (ICE output_operand: invalid shift operand)

	PR target/56470
	* arm.c (shift_op): Validate RTL pattern on the fly.
	(arm_print_operand, case 'S'): Don't use shift_operator to validate
	the RTL.

From-SVN: r196595
parent 6be8b5f7
2013-03-11 Richard Earnshaw <rearnsha@arm.com>
PR target/56470
* arm.c (shift_op): Validate RTL pattern on the fly.
(arm_print_operand, case 'S'): Don't use shift_operator to validate
the RTL.
2013-03-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2013-03-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/56347 PR target/56347
......
...@@ -15430,72 +15430,88 @@ shift_op (rtx op, HOST_WIDE_INT *amountp) ...@@ -15430,72 +15430,88 @@ shift_op (rtx op, HOST_WIDE_INT *amountp)
const char * mnem; const char * mnem;
enum rtx_code code = GET_CODE (op); enum rtx_code code = GET_CODE (op);
switch (GET_CODE (XEXP (op, 1)))
{
case REG:
case SUBREG:
*amountp = -1;
break;
case CONST_INT:
*amountp = INTVAL (XEXP (op, 1));
break;
default:
gcc_unreachable ();
}
switch (code) switch (code)
{ {
case ROTATE: case ROTATE:
gcc_assert (*amountp != -1); if (!CONST_INT_P (XEXP (op, 1)))
*amountp = 32 - *amountp; {
code = ROTATERT; output_operand_lossage ("invalid shift operand");
return NULL;
}
/* Fall through. */ code = ROTATERT;
*amountp = 32 - INTVAL (XEXP (op, 1));
mnem = "ror";
break;
case ASHIFT: case ASHIFT:
case ASHIFTRT: case ASHIFTRT:
case LSHIFTRT: case LSHIFTRT:
case ROTATERT: case ROTATERT:
mnem = arm_shift_nmem(code); mnem = arm_shift_nmem(code);
if (CONST_INT_P (XEXP (op, 1)))
{
*amountp = INTVAL (XEXP (op, 1));
}
else if (REG_P (XEXP (op, 1)))
{
*amountp = -1;
return mnem;
}
else
{
output_operand_lossage ("invalid shift operand");
return NULL;
}
break; break;
case MULT: case MULT:
/* We never have to worry about the amount being other than a /* We never have to worry about the amount being other than a
power of 2, since this case can never be reloaded from a reg. */ power of 2, since this case can never be reloaded from a reg. */
gcc_assert (*amountp != -1); if (!CONST_INT_P (XEXP (op, 1)))
{
output_operand_lossage ("invalid shift operand");
return NULL;
}
*amountp = INTVAL (XEXP (op, 1)) & 0xFFFFFFFF;
/* Amount must be a power of two. */
if (*amountp & (*amountp - 1))
{
output_operand_lossage ("invalid shift operand");
return NULL;
}
*amountp = int_log2 (*amountp); *amountp = int_log2 (*amountp);
return ARM_LSL_NAME; return ARM_LSL_NAME;
default: default:
gcc_unreachable (); output_operand_lossage ("invalid shift operand");
return NULL;
} }
if (*amountp != -1) /* This is not 100% correct, but follows from the desire to merge
multiplication by a power of 2 with the recognizer for a
shift. >=32 is not a valid shift for "lsl", so we must try and
output a shift that produces the correct arithmetical result.
Using lsr #32 is identical except for the fact that the carry bit
is not set correctly if we set the flags; but we never use the
carry bit from such an operation, so we can ignore that. */
if (code == ROTATERT)
/* Rotate is just modulo 32. */
*amountp &= 31;
else if (*amountp != (*amountp & 31))
{ {
/* This is not 100% correct, but follows from the desire to merge if (code == ASHIFT)
multiplication by a power of 2 with the recognizer for a mnem = "lsr";
shift. >=32 is not a valid shift for "lsl", so we must try and *amountp = 32;
output a shift that produces the correct arithmetical result.
Using lsr #32 is identical except for the fact that the carry bit
is not set correctly if we set the flags; but we never use the
carry bit from such an operation, so we can ignore that. */
if (code == ROTATERT)
/* Rotate is just modulo 32. */
*amountp &= 31;
else if (*amountp != (*amountp & 31))
{
if (code == ASHIFT)
mnem = "lsr";
*amountp = 32;
}
/* Shifts of 0 are no-ops. */
if (*amountp == 0)
return NULL;
} }
/* Shifts of 0 are no-ops. */
if (*amountp == 0)
return NULL;
return mnem; return mnem;
} }
...@@ -17743,12 +17759,6 @@ arm_print_operand (FILE *stream, rtx x, int code) ...@@ -17743,12 +17759,6 @@ arm_print_operand (FILE *stream, rtx x, int code)
HOST_WIDE_INT val; HOST_WIDE_INT val;
const char *shift; const char *shift;
if (!shift_operator (x, SImode))
{
output_operand_lossage ("invalid shift operand");
break;
}
shift = shift_op (x, &val); shift = shift_op (x, &val);
if (shift) if (shift)
......
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