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]

RE: [PING^1] [AArch64] Implement Bitwise AND and Set Flags


Hi,

Thanks for reviewing the patch and testcase.

There were some doubts regarding the addressing modes supported by 
these instructions.
The only source that could be referred was the AARCH64 assembler.
Hence, these modifications are implemented as per the assembler.
Please let me know if there should be any modifications.

>> the second "set" in each pattern should have the "=r,rk" constraint
>> rather than just "=r,r".
If the destination operand is stack register, assembler generates error
as follows:-
Error: operand 1 should be an integer register -- `ands sp,x0,x1' 
The ands instruction does not support sp in any of the operand as per
the assembler. 

adds and subs instruction can use SP as the first operand.
adds    x2, sp, 1                  -> No Assembler error
subs    x3, sp, #1                -> No Assembler error
adds    x2, sp, x1                -> No Assembler error
subs    x3, sp, x1                -> No Assembler error
adds    x3, sp, x1, lsl 3        -> No Assembler error
subs    x3, sp, x1, lsl 3        -> No Assembler error
Hence, their implementations are modified to support stack pointer as
the first operand.

>> I've attached a patch that provides more thorough test cases,
>> including execute ones. 
Thanks for the testcase. They were added in the testsuite and run to
check the implementation. However, the testcase had shift operations in
them. Hence, the pattern for shift are added in the patch.
Testcase have been added for adds and subs instructions similar to
the ands testcase submitted by Ian.

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). 

Thanks,
Naveen

gcc/

2013-03-26   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* config/aarch64/aarch64.md (*add<mode>3_compare0): Use stack
	register in constraint of 1st operand along with general registers.
	(*addsi3_compare0_uxtw): Likewise.
	(*sub<mode>3_compare0): Likewise.
	(*subsi3_compare0_uxtw): Likewise.
	(*adds_<shift>_<mode>, *adds_<shift>_si_uxtw): New pattern.
	(*adds_mul_imm_<mode>, *adds_mul_imm_si_uxtw): New pattern.
	(*subs_<shift>_<mode>, *subs_<shift>_si_uxtw): New pattern.
	(*subs_mul_imm_<mode>, *subs_mul_imm_si_uxtw): New pattern.
	(*and<mode>3_compare0, *andsi3_compare0_si_uxtw): New pattern.
	(*ands_<shift>_<mode>, *ands_<shift>_si_uxtw): New pattern.

gcc/testsuite/

2013-03-26   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* gcc.target/aarch64/ands.c: New.
	* gcc.target/aarch64/adds1.c: New.
	* gcc.target/aarch64/adds2.c: New.
	* gcc.target/aarch64/subs1.c: New.
	* gcc.target/aarch64/subs2.c: New.
--- gcc/config/aarch64/aarch64.md	2013-03-26 12:51:12.180448029 +0530
+++ gcc/config/aarch64/aarch64.md	2013-03-26 13:38:48.792544909 +0530
@@ -1256,7 +1256,7 @@
 (define_insn "*add<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
+	 (plus:GPI (match_operand:GPI 1 "register_operand" "%rk,rk")
 		   (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
 	 (const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r,r")
@@ -1273,7 +1273,7 @@
 (define_insn "*addsi3_compare0_uxtw"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
+	 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk")
 		  (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r,r")
@@ -1286,6 +1286,146 @@
    (set_attr "mode" "SI")]
 )
 
+(define_insn "*adds_<shift>_<mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI (ASHIFT:GPI
+		    (match_operand:GPI 1 "register_operand" "r")
+		    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
+		   (match_operand:GPI 3 "register_operand" "r"))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
+		  (match_dup 3)))]
+  ""
+  "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*adds_<shift>_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:SI (ASHIFT:SI
+		   (match_operand:SI 1 "register_operand" "r")
+		   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
+		  (match_operand:SI 3 "register_operand" "r"))
+	 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (plus:SI (ASHIFT:SI (match_dup 1) (match_dup 2))
+				 (match_dup 3))))]
+  ""
+  "adds\\t%w0, %w3, %w1, <shift> %2"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*adds_mul_imm_<mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI (mult:GPI
+		    (match_operand:GPI 1 "register_operand" "r")
+		    (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
+		   (match_operand:GPI 3 "register_operand" "rk"))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
+		  (match_dup 3)))]
+  ""
+  "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*adds_mul_imm_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:SI (mult:SI
+		   (match_operand:SI 1 "register_operand" "r")
+		   (match_operand:QI 2 "aarch64_pwr_2_si" "n"))
+		  (match_operand:SI 3 "register_operand" "rk"))
+	 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (plus:SI (mult:SI (match_dup 1) (match_dup 2))
+				 (match_dup 3))))]
+  ""
+  "adds\\t%w0, %w3, %w1, lsl %p2"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*subs_<shift>_<mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+		    (ASHIFT:GPI
+		     (match_operand:GPI 2 "register_operand" "r")
+		     (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(minus:GPI (match_dup 1)
+		   (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
+  ""
+  "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*subs_<shift>_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:SI (match_operand:SI 1 "register_operand" "r")
+		   (ASHIFT:SI
+		    (match_operand:SI 2 "register_operand" "r")
+		    (match_operand:QI 3 "aarch64_shift_imm_si" "n")))
+	(const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (minus:SI (match_dup 1)
+				  (ASHIFT:SI (match_dup 2) (match_dup 3)))))]
+  ""
+  "subs\\t%w0, %w1, %w2, <shift> %3"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*subs_mul_imm_<mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
+		    (mult:GPI
+		     (match_operand:GPI 2 "register_operand" "r")
+		     (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(minus:GPI (match_dup 1)
+		   (mult:GPI (match_dup 2) (match_dup 3))))]
+  ""
+  "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*subs_mul_imm_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:SI (match_operand:SI 1 "register_operand" "rk")
+		   (mult:SI
+		    (match_operand:SI 2 "register_operand" "r")
+		    (match_operand:QI 3 "aarch64_pwr_2_si" "n")))
+	 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (minus:SI (match_dup 1)
+				  (mult:SI (match_dup 2) (match_dup 3)))))]
+  ""
+  "subs\\t%w0, %w1, %w2, lsl %p3"
+  [(set_attr "v8type" "alu_shift")
+   (set_attr "mode" "SI")]
+)
+
 (define_insn "*add<mode>3nr_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
@@ -1633,7 +1773,7 @@
 
 (define_insn "*sub<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
-	(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+	(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
 				  (match_operand:GPI 2 "register_operand" "r"))
 		       (const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r")
@@ -1647,7 +1787,7 @@
 ;; zero_extend version of above
 (define_insn "*subsi3_compare0_uxtw"
   [(set (reg:CC_NZ CC_REGNUM)
-	(compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
+	(compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "rk")
 				 (match_operand:SI 2 "register_operand" "r"))
 		       (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
@@ -2433,6 +2573,70 @@
   [(set_attr "v8type" "logic,logic_imm")
    (set_attr "mode" "SI")])
 
+(define_insn "*and<mode>3_compare0"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
+		  (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r,r")
+	(and:GPI (match_dup 1) (match_dup 2)))]
+  ""
+  "ands\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "v8type" "logic,logic_imm")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*andsi3_compare0_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
+		 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
+	 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r,r")
+	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
+  ""
+  "ands\\t%w0, %w1, %w2"
+  [(set_attr "v8type" "logic,logic_imm")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*ands_<shift>_<mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (and:GPI (ASHIFT:GPI
+		   (match_operand:GPI 1 "register_operand" "r")
+		   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
+		  (match_operand:GPI 3 "register_operand" "r"))
+	 (const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(and:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
+		 (match_dup 3)))]
+  ""
+  "ands\\t%<w>0, %<w>3, %<w>1, <shift> %2"
+  [(set_attr "v8type" "logics_shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of above
+(define_insn "*ands_<shift>_si_uxtw"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (and:SI (ASHIFT:SI
+		  (match_operand:SI 1 "register_operand" "r")
+		  (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
+		 (match_operand:SI 3 "register_operand" "r"))
+	 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (and:SI (ASHIFT:SI (match_dup 1) (match_dup 2))
+				(match_dup 3))))]
+  ""
+  "ands\\t%w0, %w3, %w1, <shift> %2"
+  [(set_attr "v8type" "logics_shift")
+   (set_attr "mode" "SI")]
+)
+
 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(LOGICAL:GPI (SHIFT:GPI
--- gcc/testsuite/gcc.target/aarch64/adds1.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/adds1.c	2013-03-26 13:38:48.792544909 +0530
@@ -0,0 +1,149 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+adds_si_test1 (int a, int b, int c)
+{
+  int d = a + b;
+
+  /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+adds_si_test2 (int a, int b, int c)
+{
+  int d = a + 0xff;
+
+  /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, 255" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+adds_si_test3 (int a, int b, int c)
+{
+  int d = a + (b << 3);
+
+  /* { dg-final { scan-assembler "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+typedef long long s64;
+
+s64
+adds_di_test1 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + b;
+
+  /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+adds_di_test2 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + 0xff;
+
+  /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, 255" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+adds_di_test3 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + (b << 3);
+
+  /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = adds_si_test1 (29, 4, 5);
+  if (x != 42)
+    abort ();
+
+  x = adds_si_test1 (5, 2, 20);
+  if (x != 29)
+    abort ();
+
+  x = adds_si_test2 (29, 4, 5);
+  if (x != 293)
+    abort ();
+
+  x = adds_si_test2 (1024, 2, 20);
+  if (x != 1301)
+    abort ();
+
+  x = adds_si_test3 (35, 4, 5);
+  if (x != 76)
+    abort ();
+
+  x = adds_si_test3 (5, 2, 20);
+  if (x != 43)
+    abort ();
+
+  y = adds_di_test1 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+
+  if (y != 0xc75050536)
+    abort ();
+
+  y = adds_di_test1 (0x5000500050005ll,
+		     0x2111211121112ll,
+		     0x0000000002020ll);
+  if (y != 0x9222922294249)
+    abort ();
+
+  y = adds_di_test2 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x955050631)
+    abort ();
+
+  y = adds_di_test2 (0x130002900ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x955052f08)
+    abort ();
+
+  y = adds_di_test3 (0x130000029ll,
+		     0x064000008ll,
+		     0x505050505ll);
+  if (y != 0x9b9050576)
+    abort ();
+
+  y = adds_di_test3 (0x130002900ll,
+		     0x088000008ll,
+		     0x505050505ll);
+  if (y != 0xafd052e4d)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
--- gcc/testsuite/gcc.target/aarch64/adds2.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/adds2.c	2013-03-26 13:38:48.792544909 +0530
@@ -0,0 +1,155 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+adds_si_test1 (int a, int b, int c)
+{
+  int d = a + b;
+
+  /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+adds_si_test2 (int a, int b, int c)
+{
+  int d = a + 0xfff;
+
+  /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, 4095" } } */
+  /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, 4095" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+adds_si_test3 (int a, int b, int c)
+{
+  int d = a + (b << 3);
+
+  /* { dg-final { scan-assembler-not "adds\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  /* { dg-final { scan-assembler "add\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+typedef long long s64;
+
+s64
+adds_di_test1 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + b;
+
+  /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+adds_di_test2 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + 0x1000ll;
+
+  /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, 4096" } } */
+  /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, 4096" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+adds_di_test3 (s64 a, s64 b, s64 c)
+{
+  s64 d = a + (b << 3);
+
+  /* { dg-final { scan-assembler-not "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  /* { dg-final { scan-assembler "add\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = adds_si_test1 (29, 4, 5);
+  if (x != 42)
+    abort ();
+
+  x = adds_si_test1 (5, 2, 20);
+  if (x != 29)
+    abort ();
+
+  x = adds_si_test2 (29, 4, 5);
+  if (x != 4133)
+    abort ();
+
+  x = adds_si_test2 (1024, 2, 20);
+  if (x != 5141)
+    abort ();
+
+  x = adds_si_test3 (35, 4, 5);
+  if (x != 76)
+    abort ();
+
+  x = adds_si_test3 (5, 2, 20);
+  if (x != 43)
+    abort ();
+
+  y = adds_di_test1 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+
+  if (y != 0xc75050536)
+    abort ();
+
+  y = adds_di_test1 (0x5000500050005ll,
+		     0x2111211121112ll,
+		     0x0000000002020ll);
+  if (y != 0x9222922294249)
+    abort ();
+
+  y = adds_di_test2 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x955051532)
+    abort ();
+
+  y = adds_di_test2 (0x540004100ll,
+		     0x320000004ll,
+		     0x805050205ll);
+  if (y != 0x1065055309)
+    abort ();
+
+  y = adds_di_test3 (0x130000029ll,
+		     0x064000008ll,
+		     0x505050505ll);
+  if (y != 0x9b9050576)
+    abort ();
+
+  y = adds_di_test3 (0x130002900ll,
+		     0x088000008ll,
+		     0x505050505ll);
+  if (y != 0xafd052e4d)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
--- gcc/testsuite/gcc.target/aarch64/ands.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/ands.c	2013-03-26 13:43:10.868553797 +0530
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int z;
+int
+foo (int x, int y)
+{
+  int l = x & y;
+  if (l == 0)
+    return 5;
+
+  /* { dg-final { scan-assembler "ands\tw\[0-9\]" } } */
+  z = l ;
+  return 25;
+}
+
+typedef long long s64;
+
+s64 zz;
+s64
+foo2 (s64 x, s64 y)
+{
+  s64 l = x & y;
+  if (l < 0)
+    return 5;
+
+  /* { dg-final { scan-assembler "ands\tx\[0-9\]" } } */
+  zz = l ;
+  return 25;
+}
--- gcc/testsuite/gcc.target/aarch64/subs1.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/subs1.c	2013-03-26 13:38:48.792544909 +0530
@@ -0,0 +1,149 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+subs_si_test1 (int a, int b, int c)
+{
+  int d = a - c;
+
+  /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+subs_si_test2 (int a, int b, int c)
+{
+  int d = a - 0xff;
+
+  /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, #255" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+subs_si_test3 (int a, int b, int c)
+{
+  int d = a - (b << 3);
+
+  /* { dg-final { scan-assembler "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+typedef long long s64;
+
+s64
+subs_di_test1 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - c;
+
+  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+subs_di_test2 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - 0xff;
+
+  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, #255" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+subs_di_test3 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - (b << 3);
+
+  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = subs_si_test1 (29, 4, 5);
+  if (x != 33)
+    abort ();
+
+  x = subs_si_test1 (5, 2, 20);
+  if (x != 7)
+    abort ();
+
+  x = subs_si_test2 (29, 4, 5);
+  if (x != -217)
+    abort ();
+
+  x = subs_si_test2 (1024, 2, 20);
+  if (x != 791)
+    abort ();
+
+  x = subs_si_test3 (35, 4, 5);
+  if (x != 12)
+    abort ();
+
+  x = subs_si_test3 (5, 2, 20);
+  if (x != 11)
+    abort ();
+
+  y = subs_di_test1 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+
+  if (y != 0x45000002d)
+    abort ();
+
+  y = subs_di_test1 (0x5000500050005ll,
+		     0x2111211121112ll,
+		     0x0000000002020ll);
+  if (y != 0x7111711171117)
+    abort ();
+
+  y = subs_di_test2 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x955050433)
+    abort ();
+
+  y = subs_di_test2 (0x130002900ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x955052d0a)
+    abort ();
+
+  y = subs_di_test3 (0x130000029ll,
+		     0x064000008ll,
+		     0x505050505ll);
+  if (y != 0x3790504f6)
+    abort ();
+
+  y = subs_di_test3 (0x130002900ll,
+		     0x088000008ll,
+		     0x505050505ll);
+  if (y != 0x27d052dcd)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
--- gcc/testsuite/gcc.target/aarch64/subs2.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/subs2.c	2013-03-26 13:38:48.792544909 +0530
@@ -0,0 +1,155 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+int
+subs_si_test1 (int a, int b, int c)
+{
+  int d = a - b;
+
+  /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+subs_si_test2 (int a, int b, int c)
+{
+  int d = a - 0xfff;
+
+  /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, #4095" } } */
+  /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, #4095" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+subs_si_test3 (int a, int b, int c)
+{
+  int d = a - (b << 3);
+
+  /* { dg-final { scan-assembler-not "subs\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  /* { dg-final { scan-assembler "sub\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+typedef long long s64;
+
+s64
+subs_di_test1 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - b;
+
+  /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+subs_di_test2 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - 0x1000ll;
+
+  /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, #4096" } } */
+  /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, #4096" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+s64
+subs_di_test3 (s64 a, s64 b, s64 c)
+{
+  s64 d = a - (b << 3);
+
+  /* { dg-final { scan-assembler-not "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  /* { dg-final { scan-assembler "sub\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */
+  if (d <= 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = subs_si_test1 (29, 4, 5);
+  if (x != 34)
+    abort ();
+
+  x = subs_si_test1 (5, 2, 20);
+  if (x != 25)
+    abort ();
+
+  x = subs_si_test2 (29, 4, 5);
+  if (x != 34)
+    abort ();
+
+  x = subs_si_test2 (1024, 2, 20);
+  if (x != 1044)
+    abort ();
+
+  x = subs_si_test3 (35, 4, 5);
+  if (x != 12)
+    abort ();
+
+  x = subs_si_test3 (5, 2, 20);
+  if (x != 25)
+    abort ();
+
+  y = subs_di_test1 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+
+  if (y != 0x63505052e)
+    abort ();
+
+  y = subs_di_test1 (0x5000500050005ll,
+		     0x2111211121112ll,
+		     0x0000000002020ll);
+  if (y != 0x5000500052025)
+    abort ();
+
+  y = subs_di_test2 (0x130000029ll,
+		     0x320000004ll,
+		     0x505050505ll);
+  if (y != 0x95504f532)
+    abort ();
+
+  y = subs_di_test2 (0x540004100ll,
+		     0x320000004ll,
+		     0x805050205ll);
+  if (y != 0x1065053309)
+    abort ();
+
+  y = subs_di_test3 (0x130000029ll,
+		     0x064000008ll,
+		     0x505050505ll);
+  if (y != 0x63505052e)
+    abort ();
+
+  y = subs_di_test3 (0x130002900ll,
+		     0x088000008ll,
+		     0x505050505ll);
+  if (y != 0x635052e05)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */

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