I noticed this while testing my atomic optabs patch with -mthumb. This is identical to what we actually output in the current sync code:
> arm_output_asm_insn (emit, 0, operands, "cmp\t%%0, %%1"); > if (is_di) > { > arm_output_it (emit, "", "eq"); > arm_output_op2 (emit, "cmpeq", old_value_hi, required_value_hi); > } except now it's applicable to all DImode comparisons everywhere. Bootstrapped with -march=armv7-a -mthumb. The only question I have is, can we assume a universal syntax assembler, or should the output pattern be changed to { if (TARGET_THUMB) return "cmp\t%R0, %R1\;it eq\;cmpeq\t%Q0, %Q1"; else return "cmp\t%R0, %R1\;cmpeq\t%Q0, %Q1"; } ? r~
commit c1181684567b75719d3599891f0e650cee51d573 Author: Richard Henderson <r...@redhat.com> Date: Thu Dec 15 12:02:03 2011 -0800 arm: Use arm_cmpdi_unsigned for thumb2 as well This changes code generation from "eors; eors; orrs" (which ranges from 6 to 12 bytes and requires three scratch registers), to "cmp; it; cmp" (which is always 6 bytes for register inputs and requires no scratch registers). diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f829a83..18dabda 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -11606,7 +11606,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) return CC_Zmode; /* We can do an equality test in three Thumb instructions. */ - if (!TARGET_ARM) + if (!TARGET_32BIT) return CC_Zmode; /* FALLTHROUGH */ @@ -11618,7 +11618,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) /* DImode unsigned comparisons can be implemented by cmp + cmpeq without a scratch register. Not worth doing in Thumb-2. */ - if (TARGET_ARM) + if (TARGET_32BIT) return CC_CZmode; /* FALLTHROUGH */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 937a009..4ec300a 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7529,8 +7529,8 @@ [(set (reg:CC_CZ CC_REGNUM) (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r") (match_operand:DI 1 "arm_di_operand" "rDi")))] - "TARGET_ARM" - "cmp%?\\t%R0, %R1\;cmpeq\\t%Q0, %Q1" + "TARGET_32BIT" + "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" [(set_attr "conds" "set") (set_attr "length" "8")] )