[AArch64] Add/Sub and set flags instructions in extend and shift_extend mode

Submitted by Hurugalawadi, Naveen on April 12, 2013, 11:38 a.m.

Details

Message ID dc27d0b988e74f338fa2b5244d8eb9fa@SN2PR07MB029.namprd07.prod.outlook.com
State New
Headers show

Commit Message

Hurugalawadi, Naveen April 12, 2013, 11:38 a.m.
Hi,

Please find attached the patch that implements addition and Subtraction
by setting flags instructions in extend and shift_extend mode for 
aarch64 target.

The patch for Add/Sub instructions by setting flags in shift mode is 
already posted.

Testcase have been added for these instructions.

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-12   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* config/aarch64/aarch64.md (*adds_<optab><mode>_multp2):
	New pattern.
	(*subs_<optab><mode>_multp2): New pattern.
	(*adds_<optab><ALLX:mode>_<GPI:mode>): New pattern.
	(*subs_<optab><ALLX:mode>_<GPI:mode>): New pattern.

gcc/testsuite/

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

	* gcc.target/aarch64/adds3.c: New.
	* gcc.target/aarch64/subs3.c: New.

Comments

Richard Earnshaw April 12, 2013, 1:10 p.m.
On 12/04/13 12:38, Hurugalawadi, Naveen wrote:
> Hi,
>
> Please find attached the patch that implements addition and Subtraction
> by setting flags instructions in extend and shift_extend mode for
> aarch64 target.
>
> The patch for Add/Sub instructions by setting flags in shift mode is
> already posted.
>
> Testcase have been added for these instructions.
>
> 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

> @@ -0,0 +1,61 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps" } */
> +
> +extern void abort (void);
> +typedef long long s64;
> +
> +int
> +subs_ext (s64 a, int b, int c)
> +{
> + s64 d = a - b;
> +
> +  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" } } */
> +  if (d == 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +
> +int
> +subs_shift_ext (s64 a, int b, int c)
> +{
> + s64 d = (a - ((s64)b << 3));
> +
> +  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw 3" } } */
> +  if (d == 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +

This won't test what you think it does.  The first regexp will also 
match on the same patterns that the second one does, since it's a 
sub-expression of the latter.

If you're going to do it in one file you'll need to use 
scan-assembler-times.

R.

--
Marcus Shawcroft April 16, 2013, 1:28 p.m.
On 12/04/13 12:38, Hurugalawadi, Naveen wrote:
> --- gcc/testsuite/gcc.target/aarch64/adds3.c	1970-01-01 05:30:00.000000000 +0530
> +++ gcc/testsuite/gcc.target/aarch64/adds3.c	2013-04-12 16:18:29.472945730 +0530
> @@ -0,0 +1,61 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps" } */
> +

Same comment as previous patch:

dg-options will need to include -fno-inline, otherwise main gets
optimized down to { return 0; } and the execution aspect of these test
cases has no value.

With that change, OK.

Thankyou
/Marcus

Patch hide | download patch | download mbox

--- gcc/config/aarch64/aarch64.md	2013-04-12 10:03:11.924990662 +0530
+++ gcc/config/aarch64/aarch64.md	2013-04-12 14:31:58.368958483 +0530
@@ -1291,6 +1291,78 @@ 
    (set_attr "mode" "SI")]
 )
 
+(define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI
+	  (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
+	  (match_operand:GPI 2 "register_operand" "r"))
+	(const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
+  ""
+  "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
+  [(set_attr "v8type" "alus_ext")
+   (set_attr "mode" "<GPI:MODE>")]
+)
+
+(define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+		    (ANY_EXTEND:GPI
+		     (match_operand:ALLX 2 "register_operand" "r")))
+	(const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
+  ""
+  "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
+  [(set_attr "v8type" "alus_ext")
+   (set_attr "mode" "<GPI:MODE>")]
+)
+
+(define_insn "*adds_<optab><mode>_multp2"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI (ANY_EXTRACT:GPI
+		    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
+			      (match_operand 2 "aarch64_pwr_imm3" "Up3"))
+		    (match_operand 3 "const_int_operand" "n")
+		    (const_int 0))
+		   (match_operand:GPI 4 "register_operand" "r"))
+	(const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
+				   (match_dup 3)
+				   (const_int 0))
+		  (match_dup 4)))]
+  "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
+  "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
+  [(set_attr "v8type" "alus_ext")
+   (set_attr "mode" "<MODE>")]
+)
+
+(define_insn "*subs_<optab><mode>_multp2"
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
+		    (ANY_EXTRACT:GPI
+		     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
+			       (match_operand 2 "aarch64_pwr_imm3" "Up3"))
+		     (match_operand 3 "const_int_operand" "n")
+		     (const_int 0)))
+	(const_int 0)))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+	(minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
+				  (mult:GPI (match_dup 1) (match_dup 2))
+				  (match_dup 3)
+				  (const_int 0))))]
+  "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
+  "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
+  [(set_attr "v8type" "alus_ext")
+   (set_attr "mode" "<MODE>")]
+)
+
 (define_insn "*add<mode>3nr_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
--- gcc/testsuite/gcc.target/aarch64/adds3.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/adds3.c	2013-04-12 16:18:29.472945730 +0530
@@ -0,0 +1,61 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+typedef long long s64;
+
+int
+adds_ext (s64 a, int b, int c)
+{
+ s64 d = a + b;
+
+  /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+adds_shift_ext (s64 a, int b, int c)
+{
+ s64 d = (a + ((s64)b << 3));
+
+  /* { dg-final { scan-assembler "adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = adds_ext (0x13000002ll, 41, 15);
+  if (x != 318767203)
+    abort ();
+
+  x = adds_ext (0x50505050ll, 29, 4);
+  if (x != 1347440782)
+    abort ();
+
+  x = adds_ext (0x12121212121ll, 2, 14);
+  if (x != 555819315)
+    abort ();
+
+  x = adds_shift_ext (0x123456789ll, 4, 12);
+  if (x != 591751097)
+    abort ();
+
+  x = adds_shift_ext (0x02020202ll, 9, 8);
+  if (x != 33686107)
+    abort ();
+
+  x = adds_shift_ext (0x987987987987ll, 23, 41);
+  if (x != -2020050305)
+    abort ();
+
+  return 0;
+}
--- gcc/testsuite/gcc.target/aarch64/subs3.c	1970-01-01 05:30:00.000000000 +0530
+++ gcc/testsuite/gcc.target/aarch64/subs3.c	2013-04-12 16:18:40.404945709 +0530
@@ -0,0 +1,61 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+typedef long long s64;
+
+int
+subs_ext (s64 a, int b, int c)
+{
+ s64 d = a - b;
+
+  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+subs_shift_ext (s64 a, int b, int c)
+{
+ s64 d = (a - ((s64)b << 3));
+
+  /* { dg-final { scan-assembler "subs\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw 3" } } */
+  if (d == 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = subs_ext (0x13000002ll, 41, 15);
+  if (x != 318767121)
+    abort ();
+
+  x = subs_ext (0x50505050ll, 29, 4);
+  if (x != 1347440724)
+    abort ();
+
+  x = subs_ext (0x12121212121ll, 2, 14);
+  if (x != 555819311)
+    abort ();
+
+  x = subs_shift_ext (0x123456789ll, 4, 12);
+  if (x != 591751033)
+    abort ();
+
+  x = subs_shift_ext (0x02020202ll, 9, 8);
+  if (x != 33685963)
+    abort ();
+
+  x = subs_shift_ext (0x987987987987ll, 23, 41);
+  if (x != -2020050673)
+    abort ();
+
+  return 0;
+}