Patchwork [ARM] NEON DImode neg

login
register
mail settings
Submitter Andrew Stubbs
Date Feb. 29, 2012, 2:14 p.m.
Message ID <4F4E32CF.1040405@codesourcery.com>
Download mbox | patch
Permalink /patch/143734/
State New
Headers show

Comments

Andrew Stubbs - Feb. 29, 2012, 2:14 p.m.
On 28/02/12 17:45, Andrew Stubbs wrote:
> This patch adds a DImode negate pattern for NEON.

Oops, that patch completely failed to allow for the fallback to 
instructions that work in core registers. It also forgot to mention that 
the CC register was clobbered.

This patch is the same except that it addresses those deficiencies. The 
outputs are the same.

Ok for 4.8?

Andrew

Patch

2012-02-29  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.

---
 gcc/config/arm/arm.md  |    8 +++++++-
 gcc/config/arm/neon.md |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletions(-)

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 d7caa37..b040ab1 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -922,6 +922,43 @@ 
                     (const_string "neon_int_3")))]
 )
 
+(define_insn "negdi2_neon"
+  [(set (match_operand:DI 0 "s_register_operand"	 "=w,?r,?&r,?w")
+	(neg:DI (match_operand:DI 1 "s_register_operand" " w, 0,  r, w")))
+   (clobber (match_scratch:DI 2				 "=w, X,  X, w"))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_NEON"
+  "#"
+  [(set_attr "length" "8")
+   (set_attr "arch" "nota8,*,*,onlya8")]
+)
+
+; 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))])]
+  ""
+)
+
+; 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")