This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, AArch64] Negate and set flags in shift mode


Hi,

Please find attached the patch that implements negs instruction
with shift for aarch64 target.
Testcase have been added for negs instruction.

Please review the same and let me know if there should be any 
modifications in the patch.
 
Build and tested on aarch64-thunder-elf (using Cavium's internal
simulator). No new regressions.

Thanks,
Naveen

gcc/

2013-04-10   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* config/aarch64/aarch64.c (aarch64_select_cc_mode): Allow NEG
	code in CC_NZ mode.
	* config/aarch64/aarch64.md (*neg_<shift><mode>3_compare0): New
	pattern.

gcc/testsuite/

2013-04-10   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* gcc.target/aarch64/negs.c: New.
--- gcc/config/aarch64/aarch64.c	2013-04-09 11:58:48.650789435 +0530
+++ gcc/config/aarch64/aarch64.c	2013-04-10 15:42:42.493294822 +0530
@@ -3087,7 +3087,8 @@ aarch64_select_cc_mode (RTX_CODE code, r
   if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
       && y == const0_rtx
       && (code == EQ || code == NE || code == LT || code == GE)
-      && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND))
+      && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS || GET_CODE (x) == AND
+	  || GET_CODE (x) == NEG))
     return CC_NZmode;
 
   /* A compare with a shifted operand.  Because of canonicalization,
--- gcc/config/aarch64/aarch64.md	2013-04-09 11:58:48.646789435 +0530
+++ gcc/config/aarch64/aarch64.md	2013-04-10 15:43:31.213294725 +0530
@@ -1901,6 +1901,21 @@
    (set_attr "mode" "SI")]
 )
 
+(define_insn "*neg_<shift><mode>3_compare0"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (neg:GPI (ASHIFT:GPI
+		   (match_operand:GPI 1 "register_operand" "r")
+		   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
+  ""
+  "negs\\t%<w>0, %<w>1, <shift> %2"
+  [(set_attr "v8type" "alus_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
 (define_insn "*neg_<shift>_<mode>2"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(neg:GPI (ASHIFT:GPI
--- gcc/testsuite/gcc.target/aarch64/negs.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/negs.c	2013-04-10 15:44:28.981294610 +0530
@@ -0,0 +1,108 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+int z;
+
+int
+negs_si_test1 (int a, int b, int c)
+{
+  int d = -b;
+
+  /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+" } } */
+  if (d < 0)
+    return a + c;
+
+  z = d;
+    return b + c + d;
+}
+
+int
+negs_si_test3 (int a, int b, int c)
+{
+  int d = -(b) << 3;
+
+  /* { dg-final { scan-assembler "negs\tw\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+
+  z = d;
+    return b + c + d;
+}
+
+typedef long long s64;
+s64 zz;
+
+s64
+negs_di_test1 (s64 a, s64 b, s64 c)
+{
+  s64 d = -b;
+
+  /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+" } } */
+  if (d < 0)
+    return a + c;
+
+  zz = d;
+    return b + c + d;
+}
+
+s64
+negs_di_test3 (s64 a, s64 b, s64 c)
+{
+  s64 d = -(b) << 3;
+
+  /* { dg-final { scan-assembler "negs\tx\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+
+  zz = d;
+    return b + c + d;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = negs_si_test1 (2, 12, 5);
+  if (x != 7)
+    abort ();
+
+  x = negs_si_test1 (1, 2, 32);
+  if (x != 33)
+    abort ();
+
+  x = negs_si_test3 (13, 14, 5);
+  if (x != -93)
+    abort ();
+
+  x = negs_si_test3 (15, 21, 2);
+  if (x != -145)
+    abort ();
+
+  y = negs_di_test1 (0x20202020ll,
+		     0x65161611ll,
+		     0x42434243ll);
+  if (y != 0x62636263ll)
+    abort ();
+
+  y = negs_di_test1 (0x1010101010101ll,
+		     0x123456789abcdll,
+		     0x5555555555555ll);
+  if (y != 0x6565656565656ll)
+    abort ();
+
+  y = negs_di_test3 (0x62523781ll,
+		     0x64234978ll,
+		     0x12345123ll);
+  if (y != 0xfffffffd553d4edbll)
+    abort ();
+
+  y = negs_di_test3 (0x763526268ll,
+		     0x101010101ll,
+		     0x222222222ll);
+  if (y != 0xfffffffb1b1b1b1bll)
+    abort ();
+
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]