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

login
register
mail settings
Submitter Hurugalawadi, Naveen
Date April 12, 2013, 11:38 a.m.
Message ID <dc27d0b988e74f338fa2b5244d8eb9fa@SN2PR07MB029.namprd07.prod.outlook.com>
Download mbox | patch
Permalink /patch/236055/
State New
Headers show

Comments

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

--- 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;
+}