This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, AArch64] Compare Negative instruction in shift and extend mode
- From: "Hurugalawadi, Naveen" <Naveen dot Hurugalawadi at caviumnetworks dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 10 Apr 2013 10:35:06 +0000
- Subject: [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;
+}