[AArch64] Support SBC in the backend

Submitted by Ian Bolton on March 14, 2013, 3:52 p.m.

Details

Message ID 000801ce20cb$fcf249b0$f6d6dd10$@bolton@arm.com
State New
Headers show

Commit Message

Ian Bolton March 14, 2013, 3:52 p.m.
We couldn't generate SBC for AArch64 ... until now!

This really patch includes the main pattern, a zero_extend form
of it and a test.

Full regression testing for Linux and bare-metal passed.

OK for trunk stage-1?

Thanks,
Ian


2013-03-14  Ian Bolton  <ian.bolton@arm.com>

gcc/
	* config/aarch64/aarch64.md (*sub<mode>3_carryin): New pattern.
	(*subsi3_carryin_uxtw): Likewise.

testsuite/
	* gcc.target/aarch64/sbc.c: New test.

Comments

Marcus Shawcroft March 15, 2013, 2:29 p.m.
On 14/03/13 15:52, Ian Bolton wrote:
> We couldn't generate SBC for AArch64 ... until now!
>
> This really patch includes the main pattern, a zero_extend form
> of it and a test.
>
> Full regression testing for Linux and bare-metal passed.
>
> OK for trunk stage-1?
>
> Thanks,
> Ian
>
>
> 2013-03-14  Ian Bolton  <ian.bolton@arm.com>
>
> gcc/
> 	* config/aarch64/aarch64.md (*sub<mode>3_carryin): New pattern.
> 	(*subsi3_carryin_uxtw): Likewise.
>
> testsuite/
> 	* gcc.target/aarch64/sbc.c: New test.
>


OK for stage-1.

/Marcus
Gerald Pfeifer March 15, 2013, 4:37 p.m.
On Fri, 15 Mar 2013, Marcus Shawcroft wrote:
> OK for stage-1.

This may be a naive question, but with AArch64 being a new port
and these changes being port-specific, with no impact on anything
else, have you considered asking the release managers to be more 
aggressive in applying things?

Of course, if you, too, are stabilizing the port and it's good
enough to be used as is and those changes are just the topping
on the ice cream, just ignore my note. :-)

Gerald
Richard Earnshaw March 15, 2013, 5:10 p.m.
On 15/03/13 16:37, Gerald Pfeifer wrote:
> On Fri, 15 Mar 2013, Marcus Shawcroft wrote:
>> OK for stage-1.
>
> This may be a naive question, but with AArch64 being a new port
> and these changes being port-specific, with no impact on anything
> else, have you considered asking the release managers to be more
> aggressive in applying things?
>
> Of course, if you, too, are stabilizing the port and it's good
> enough to be used as is and those changes are just the topping
> on the ice cream, just ignore my note. :-)
>
> Gerald
>

Yes, it is a new port, but it's important that 4.8.0 works and we can't 
afford a mess-up at the last minute causing problems.

I think it would be better to seek leniency for selected back-ports 
early in the 4.8.1 cycle.

R.

Patch hide | download patch | download mbox

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4358b44..c99e188 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1790,6 +1790,34 @@ 
    (set_attr "mode" "SI")]
 )
 
+(define_insn "*sub<mode>3_carryin"
+  [(set
+    (match_operand:GPI 0 "register_operand" "=r")
+    (minus:GPI (minus:GPI
+		(match_operand:GPI 1 "register_operand" "r")
+		(ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
+	       (match_operand:GPI 2 "register_operand" "r")))]
+   ""
+   "sbc\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "v8type" "adc")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of the above
+(define_insn "*subsi3_carryin_uxtw"
+  [(set
+    (match_operand:DI 0 "register_operand" "=r")
+    (zero_extend:DI
+     (minus:SI (minus:SI
+		(match_operand:SI 1 "register_operand" "r")
+		(ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
+	       (match_operand:SI 2 "register_operand" "r"))))]
+   ""
+   "sbc\\t%w0, %w1, %w2"
+  [(set_attr "v8type" "adc")
+   (set_attr "mode" "SI")]
+)
+
 (define_insn "*sub_uxt<mode>_multp2"
   [(set (match_operand:GPI 0 "register_operand" "=rk")
 	(minus:GPI (match_operand:GPI 4 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/aarch64/sbc.c b/gcc/testsuite/gcc.target/aarch64/sbc.c
new file mode 100644
index 0000000..e479910
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sbc.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+typedef unsigned int u32int;
+typedef unsigned long long u64int;
+
+u32int
+test_si (u32int w1, u32int w2, u32int w3, u32int w4)
+{
+  u32int w0;
+  /* { dg-final { scan-assembler "sbc\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+\n" } } */
+  w0 = w1 - w2 - (w3 < w4);
+  return w0;
+}
+
+u64int
+test_di (u64int x1, u64int x2, u64int x3, u64int x4)
+{
+  u64int x0;
+  /* { dg-final { scan-assembler "sbc\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+\n" } } */
+  x0 = x1 - x2 - (x3 < x4);
+  return x0;
+}
+
+int
+main ()
+{
+  u32int x;
+  u64int y;
+  x = test_si (7, 8, 12, 15);
+  if (x != -2)
+    abort();
+  y = test_di (0x987654321ll, 0x123456789ll, 0x345345345ll, 0x123123123ll);
+  if (y != 0x8641fdb98ll)
+    abort();
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */