2009-10-28 Paolo Bonzini <bonzini@gnu.org>
+ PR rtl-optimization/40741
+ * config/arm/arm.c (thumb1_rtx_costs): IOR or XOR with
+ a small constant is cheap.
+ * config/arm/arm.md (andsi3, iorsi3): Try to place the result of
+ force_reg on the LHS.
+ (xorsi3): Likewise, and split the XOR if the constant is complex
+ and not in Thumb mode.
+
+2009-10-28 Paolo Bonzini <bonzini@gnu.org>
+
* expmed.c (emit_store_flag): Check costs before
transforming to the opposite representation.
else if ((outer == PLUS || outer == COMPARE)
&& INTVAL (x) < 256 && INTVAL (x) > -256)
return 0;
- else if (outer == AND
+ else if ((outer == IOR || outer == XOR || outer == AND)
&& INTVAL (x) < 256 && INTVAL (x) >= -256)
return COSTS_N_INSNS (1);
else if (outer == ASHIFT || outer == ASHIFTRT
else /* TARGET_THUMB1 */
{
if (GET_CODE (operands[2]) != CONST_INT)
- operands[2] = force_reg (SImode, operands[2]);
+ {
+ rtx tmp = force_reg (SImode, operands[2]);
+ if (rtx_equal_p (operands[0], operands[1]))
+ operands[2] = tmp;
+ else
+ {
+ operands[2] = operands[1];
+ operands[1] = tmp;
+ }
+ }
else
{
int i;
DONE;
}
else /* TARGET_THUMB1 */
- operands [2] = force_reg (SImode, operands [2]);
+ {
+ rtx tmp = force_reg (SImode, operands[2]);
+ if (rtx_equal_p (operands[0], operands[1]))
+ operands[2] = tmp;
+ else
+ {
+ operands[2] = operands[1];
+ operands[1] = tmp;
+ }
+ }
}
"
)
(define_expand "xorsi3"
[(set (match_operand:SI 0 "s_register_operand" "")
(xor:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "arm_rhs_operand" "")))]
+ (match_operand:SI 2 "reg_or_int_operand" "")))]
"TARGET_EITHER"
- "if (TARGET_THUMB1)
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = force_reg (SImode, operands[2]);
- "
+ "if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if (TARGET_32BIT)
+ {
+ arm_split_constant (XOR, SImode, NULL_RTX,
+ INTVAL (operands[2]), operands[0], operands[1],
+ optimize && can_create_pseudo_p ());
+ DONE;
+ }
+ else /* TARGET_THUMB1 */
+ {
+ rtx tmp = force_reg (SImode, operands[2]);
+ if (rtx_equal_p (operands[0], operands[1]))
+ operands[2] = tmp;
+ else
+ {
+ operands[2] = operands[1];
+ operands[1] = tmp;
+ }
+ }
+ }"
)
(define_insn "*arm_xorsi3"