diff mbox

[ARM] NEON DImode neg

Message ID 4F897794.7010402@codesourcery.com
State New
Headers show

Commit Message

Andrew Stubbs April 14, 2012, 1:11 p.m. UTC
And now with the patch. :(

On 14/04/12 13:48, Andrew Stubbs wrote:
> On 12/04/12 16:48, Richard Earnshaw wrote:
>> If negation in Neon needs a scratch register, it seems to me to be
>> somewhat odd that we're disparaging the ARM version.
>>
>> Also, wouldn't it be sensible to support a variant that was
>> early-clobber on operand 0, but loaded immediate zero into that value
>> first:
>>
>> vmov Dd, #0
>> vsub Dd, Dd, Dm
>>
>> That way you'll never need more than two registers, whereas today you
>> want three.
>
> This patch implements the changes you suggested.
>
> I've done a full bootstrap and test and found no regressions.
>
> OK?
>
> Andrew
>
> P.S. This patch can't actually be committed until my "NEON DImode
> immediate constants" patch is approved and committed. (Without that the
> load #0 needs a constant pool, and loading constants this late has a bug
> at -O0.)

Comments

Richard Earnshaw April 16, 2012, 12:41 p.m. UTC | #1
On 14/04/12 14:11, Andrew Stubbs wrote:
> And now with the patch. :(
> 
> On 14/04/12 13:48, Andrew Stubbs wrote:
>> On 12/04/12 16:48, Richard Earnshaw wrote:
>>> If negation in Neon needs a scratch register, it seems to me to be
>>> somewhat odd that we're disparaging the ARM version.
>>>
>>> Also, wouldn't it be sensible to support a variant that was
>>> early-clobber on operand 0, but loaded immediate zero into that value
>>> first:
>>>
>>> vmov Dd, #0
>>> vsub Dd, Dd, Dm
>>>
>>> That way you'll never need more than two registers, whereas today you
>>> want three.
>>
>> This patch implements the changes you suggested.
>>
>> I've done a full bootstrap and test and found no regressions.
>>
>> OK?
>>
>> Andrew
>>
>> P.S. This patch can't actually be committed until my "NEON DImode
>> immediate constants" patch is approved and committed. (Without that the
>> load #0 needs a constant pool, and loading constants this late has a bug
>> at -O0.)
>>
>> neon-neg64.patch
>>
>>
>> 2012-04-12  Andrew Stubbs  <ams@codesourcery.com>
>>
>> 	gcc/
>> 	* config/arm/arm.md (negdi2): Use gen_negdi2_neon.
>> 	* config/arm/neon.md (negdi2_neon): New insn.
>> 	Also add splitters for core and NEON registers.
>>

OK

R.
Andrew Stubbs April 30, 2012, 2:12 p.m. UTC | #2
On 16/04/12 13:41, Richard Earnshaw wrote:
>>> P.S. This patch can't actually be committed until my "NEON DImode
>>> immediate constants" patch is approved and committed. (Without that the
>>> load #0 needs a constant pool, and loading constants this late has a bug
>>> at -O0.)
>>>
>>> neon-neg64.patch
>>>
>>>
>>> 2012-04-12  Andrew Stubbs<ams@codesourcery.com>
>>>
>>> 	gcc/
>>> 	* config/arm/arm.md (negdi2): Use gen_negdi2_neon.
>>> 	* config/arm/neon.md (negdi2_neon): New insn.
>>> 	Also add splitters for core and NEON registers.
>>>
>
> OK

Thanks, now that the other patch is committed, I've committed this one also.

Andrew
diff mbox

Patch

2012-04-12  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	* config/arm/arm.md (negdi2): Use gen_negdi2_neon.
	* config/arm/neon.md (negdi2_neon): New insn.
	Also add splitters for core and NEON registers.

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 751997f..f1dbbf7 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4048,7 +4048,13 @@ 
 	 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
     (clobber (reg:CC CC_REGNUM))])]
   "TARGET_EITHER"
-  ""
+  {
+    if (TARGET_NEON)
+      {
+        emit_insn (gen_negdi2_neon (operands[0], operands[1]));
+	DONE;
+      }
+  }
 )
 
 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 3c88568..8c8b02d 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -922,6 +922,45 @@ 
                     (const_string "neon_int_3")))]
 )
 
+(define_insn "negdi2_neon"
+  [(set (match_operand:DI 0 "s_register_operand"	 "=&w, w,r,&r")
+	(neg:DI (match_operand:DI 1 "s_register_operand" "  w, w,0, r")))
+   (clobber (match_scratch:DI 2				 "= X,&w,X, X"))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_NEON"
+  "#"
+  [(set_attr "length" "8")]
+)
+
+; Split negdi2_neon for vfp registers
+(define_split
+  [(set (match_operand:DI 0 "s_register_operand" "")
+	(neg:DI (match_operand:DI 1 "s_register_operand" "")))
+   (clobber (match_scratch:DI 2 ""))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
+  [(set (match_dup 2) (const_int 0))
+   (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1)))
+	      (clobber (reg:CC CC_REGNUM))])]
+  {
+    if (!REG_P (operands[2]))
+      operands[2] = operands[0];
+  }
+)
+
+; Split negdi2_neon for core registers
+(define_split
+  [(set (match_operand:DI 0 "s_register_operand" "")
+	(neg:DI (match_operand:DI 1 "s_register_operand" "")))
+   (clobber (match_scratch:DI 2 ""))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT && reload_completed
+   && arm_general_register_operand (operands[0], DImode)"
+  [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
+	      (clobber (reg:CC CC_REGNUM))])]
+  ""
+)
+
 (define_insn "*umin<mode>3_neon"
   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
 	(umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")