diff mbox

[RFA,ARM] Streamline thumb2 DImode compares

Message ID 4EEBE1A6.6010509@redhat.com
State New
Headers show

Commit Message

Richard Henderson Dec. 17, 2011, 12:26 a.m. UTC
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 <rth@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).

Comments

Richard Earnshaw Dec. 20, 2011, 4:40 p.m. UTC | #1
On 17/12/11 00:26, Richard Henderson wrote:
> 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";
>   }
> 
> ?
> 

It works from binutils-2.17 onwards (ie back to 2006 release).  That's
probably far enough back that you'd encounter other problems if you
tried to mix older binutils with latest GCC.

So on that basis, OK.

R.

> 
> r~
> 
> 
> z1
> 
> 
> commit c1181684567b75719d3599891f0e650cee51d573
> Author: Richard Henderson <rth@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")]
>  )
diff mbox

Patch

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")]
 )