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] Compare Negative instruction in shift and extend mode


Hi,

Please find attached the patch that implements compare negative
instruction with shift and extend mode for aarch64 target.
Testcase have been added for compare and compare negative 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): Use NEG
	code in CC_SWP mode.
	* config/aarch64/aarch64.md (*cmn_swp_<shift>_reg<mode>): New
	pattern.
	(*cmn_swp_<optab><ALLX:mode>_reg<GPI:mode>): New pattern.

gcc/testsuite/

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

	* gcc.target/aarch64/cmn-1.c: New.
	* gcc.target/aarch64/cmp.c: New.
--- gcc/config/aarch64/aarch64.c	2013-04-09 11:58:48.650789435 +0530
+++ gcc/config/aarch64/aarch64.c	2013-04-10 13:20:12.625311883 +0530
@@ -3094,7 +3094,8 @@ aarch64_select_cc_mode (RTX_CODE code, r
      the comparison will have to be swapped when we emit the assembly
      code.  */
   if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
-      && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
+      && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG
+	  || GET_CODE (y) == NEG)
       && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
 	  || GET_CODE (x) == LSHIFTRT
 	  || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND))
--- gcc/config/aarch64/aarch64.md	2013-04-09 11:58:48.646789435 +0530
+++ gcc/config/aarch64/aarch64.md	2013-04-10 12:31:40.393317692 +0530
@@ -2190,7 +2190,28 @@
    (set_attr "mode" "<GPI:MODE>")]
 )
 
+(define_insn "*cmn_swp_<shift>_reg<mode>"
+  [(set (reg:CC_SWP CC_REGNUM)
+	(compare:CC_SWP (ASHIFT:GPI
+			 (match_operand:GPI 0 "register_operand" "r")
+			 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
+			(neg:GPI (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ"))))]
+  ""
+  "cmn\\t%<w>2, %<w>0, <shift> %1"
+  [(set_attr "v8type" "alus_shift")
+   (set_attr "mode" "<MODE>")]
+)
 
+(define_insn "*cmn_swp_<optab><ALLX:mode>_reg<GPI:mode>"
+  [(set (reg:CC_SWP CC_REGNUM)
+	(compare:CC_SWP (ANY_EXTEND:GPI
+			 (match_operand:ALLX 0 "register_operand" "r"))
+			(neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
+  ""
+  "cmn\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
+  [(set_attr "v8type" "alus_ext")
+   (set_attr "mode" "<GPI:MODE>")]
+)
 ;; -------------------------------------------------------------------
 ;; Store-flag and conditional select insns
 ;; -------------------------------------------------------------------
--- gcc/testsuite/gcc.target/aarch64/cmn-1.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/cmn-1.c	2013-04-10 12:27:17.845318216 +0530
@@ -0,0 +1,134 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+cmn_si_test1 (int a, int b, int c)
+{
+  /* { dg-final { scan-assembler "cmn\tw\[0-9\]+, w\[0-9\]+" } } */
+  if (a + b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int
+cmn_si_test2 (int a, int b, int c)
+{
+  /* { dg-final { scan-assembler "cmn\tw\[0-9\]+, w\[0-9\]+, asr 3" } } */
+  if ((a >> 3) + b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int
+cmn_si_test3 (char a, int b, int c)
+{
+  /* { dg-final { scan-assembler "cmn\tw\[0-9\]+, w\[0-9\]+, uxtb" } } */
+  if (a > -b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+typedef long long s64;
+
+s64
+cmn_di_test1 (s64 a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmn\tx\[0-9\]+, x\[0-9\]+" } } */
+  if (a + b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+s64
+cmn_di_test2 (s64 a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmn\tx\[0-9\]+, x\[0-9\]+, asr 3" } } */
+  if ((a >> 3) + b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+s64
+cmn_di_test3 (int a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmn\tx\[0-9\]+, x\[0-9\]+, sxtw" } } */
+  if (a > -b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = cmn_si_test1 (2, 12, 5);
+  if (x != 7)
+    abort ();
+
+  x = cmn_si_test1 (1, 2, 32);
+  if (x != 33)
+    abort ();
+
+  x = cmn_si_test2 (7, 5, 15);
+  if (x != 22)
+    abort ();
+
+  x = cmn_si_test2 (12, 1, 3);
+  if (x != 15)
+    abort ();
+
+  x = cmn_si_test3 (13, 14, 5);
+  if (x != 18)
+    abort ();
+
+  x = cmn_si_test3 (15, 21, 2);
+  if (x != 17)
+    abort ();
+
+  y = cmn_di_test1 (0x20202020ll,
+		    0x65161611ll,
+		    0x42434243ll);
+  if (y != 0x62636263ll)
+    abort ();
+
+  y = cmn_di_test1 (0x1010101010101ll,
+		    0x123456789abcdll,
+		    0x5555555555555ll);
+  if (y != 0x6565656565656ll)
+    abort ();
+
+  y = cmn_di_test2 (0x31313131ll,
+		    0x35466561ll,
+		    0x42434243ll);
+  if (y != 0x73747374ll)
+    abort ();
+
+  y = cmn_di_test2 (0x101010101ll,
+		    0x123456789ll,
+		    0x555555555ll);
+  if (y != 0x656565656ll)
+    abort ();
+
+  y = cmn_di_test3 (0x62523781ll,
+		    0x64234978ll,
+		    0x12345123ll);
+  if (y != 0x748688a4ll)
+    abort ();
+
+  y = cmn_di_test3 (0x76352626ll,
+		    0x10101010ll,
+		    0x21212121ll);
+  if (y != 0x97564747ll)
+    abort ();
+
+  return 0;
+}
--- gcc/testsuite/gcc.target/aarch64/cmp.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/cmp.c	2013-04-10 12:28:12.897318106 +0530
@@ -0,0 +1,134 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+cmp_si_test1 (int a, int b, int c)
+{
+  /* { dg-final { scan-assembler "cmp\tw\[0-9\]+, w\[0-9\]+" } } */
+  if (a > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int
+cmp_si_test2 (int a, int b, int c)
+{
+  /* { dg-final { scan-assembler "cmp\tw\[0-9\]+, w\[0-9\]+, asr 3" } } */
+  if ((a >> 3) > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int
+cmp_si_test3 (int a, long b, int c)
+{
+  /* { dg-final { scan-assembler "cmp\tx\[0-9\]+, x\[0-9\]+, sxtw" } } */
+  if (a > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+typedef long long s64;
+
+s64
+cmp_di_test1 (s64 a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmp\tx\[0-9\]+, x\[0-9\]+" } } */
+  if (a > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+s64
+cmp_di_test2 (s64 a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmp\tx\[0-9\]+, x\[0-9\]+, asr 3" } } */
+  if ((a >> 3) > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int
+cmp_di_test3 (int a, s64 b, s64 c)
+{
+  /* { dg-final { scan-assembler "cmp\tx\[0-9\]+, x\[0-9\]+, sxtw" } } */
+  if (a > b)
+    return a + c;
+  else
+    return a + b + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = cmp_si_test1 (2, 12, 5);
+  if (x != 19)
+    abort ();
+
+  x = cmp_si_test1 (1, 2, 32);
+  if (x != 35)
+    abort ();
+
+  x = cmp_si_test2 (7, 5, 15);
+  if (x != 27)
+    abort ();
+
+  x = cmp_si_test2 (12, 1, 3);
+  if (x != 16)
+    abort ();
+
+  x = cmp_si_test3 (13, 14, 5);
+  if (x != 32)
+    abort ();
+
+  x = cmp_si_test3 (15, 21, 2);
+  if (x != 38)
+    abort ();
+
+  y = cmp_di_test1 (0x20202020ll,
+		    0x65161611ll,
+		    0x42434243ll);
+  if (y != 0xc7797874ll)
+    abort ();
+
+  y = cmp_di_test1 (0x1010101010101ll,
+		    0x123456789abcdll,
+		    0x5555555555555ll);
+  if (y != 0x7799bbde00223ll)
+    abort ();
+
+  y = cmp_di_test2 (0x31313131ll,
+		    0x35466561ll,
+		    0x42434243ll);
+  if (y != 0xa8bad8d5ll)
+    abort ();
+
+  y = cmp_di_test2 (0x101010101ll,
+		    0x123456789ll,
+		    0x555555555ll);
+  if (y != 0x7799bbddfll)
+    abort ();
+
+  y = cmp_di_test3 (0x62523781ll,
+		    0x64234978ll,
+		    0x12345123ll);
+  if (y != 0xffffffffd8a9d21cll)
+    abort ();
+
+  y = cmp_di_test3 (0x76352626ll,
+		    0x10101010ll,
+		    0x21212121ll);
+  if (y != 0xffffffff97564747ll)
+    abort ();
+
+  return 0;
+}

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