const char * mnem;
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)
{
case ROTATE:
- gcc_assert (*amountp != -1);
- *amountp = 32 - *amountp;
- code = ROTATERT;
+ if (!CONST_INT_P (XEXP (op, 1)))
+ {
+ output_operand_lossage ("invalid shift operand");
+ return NULL;
+ }
- /* Fall through. */
+ code = ROTATERT;
+ *amountp = 32 - INTVAL (XEXP (op, 1));
+ mnem = "ror";
+ break;
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
case ROTATERT:
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;
case MULT:
/* 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. */
- 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);
return ARM_LSL_NAME;
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
- 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))
- {
- if (code == ASHIFT)
- mnem = "lsr";
- *amountp = 32;
- }
-
- /* Shifts of 0 are no-ops. */
- if (*amountp == 0)
- return NULL;
+ if (code == ASHIFT)
+ mnem = "lsr";
+ *amountp = 32;
}
+ /* Shifts of 0 are no-ops. */
+ if (*amountp == 0)
+ return NULL;
+
return mnem;
}
HOST_WIDE_INT val;
const char *shift;
- if (!shift_operator (x, SImode))
- {
- output_operand_lossage ("invalid shift operand");
- break;
- }
-
shift = shift_op (x, &val);
if (shift)