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.hurugalaw...@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.hurugalaw...@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;
+}

Reply via email to