diff mbox

[AArch64] Support ROR in backend

Message ID 000401ce20ca$8ab84da0$a028e8e0$@bolton@arm.com
State New
Headers show

Commit Message

Ian Bolton March 14, 2013, 3:42 p.m. UTC
We couldn't generate ROR (preferred alias of EXTR when both source
registers are the same) for AArch64, when rotating by an immediate,
... until now!

This patch includes the pattern 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 (*ror<mode>3_insn): New pattern.
	(*rorsi3_insn_uxtw): Likewise.

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

Comments

Marcus Shawcroft March 15, 2013, 2:30 p.m. UTC | #1
On 14/03/13 15:42, Ian Bolton wrote:
> We couldn't generate ROR (preferred alias of EXTR when both source
> registers are the same) for AArch64, when rotating by an immediate,
> ... until now!
>
> This patch includes the pattern 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 (*ror<mode>3_insn): New pattern.
> 	(*rorsi3_insn_uxtw): Likewise.
>
> testsuite/
> 	* gcc.target/aarch64/ror.c: New test.
>

OK for stage-1

/Marcus
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index ef1c0f3..367c0e3 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2731,6 +2731,34 @@ 
    (set_attr "mode" "SI")]
 )
 
+(define_insn "*ror<mode>3_insn"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+	(rotate:GPI (match_operand:GPI 1 "register_operand" "r")
+		    (match_operand 2 "const_int_operand" "n")))]
+  "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+{
+  operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
+  return "ror\\t%<w>0, %<w>1, %3";
+}
+  [(set_attr "v8type" "shift")
+   (set_attr "mode" "<MODE>")]
+)
+
+;; zero_extend version of the above
+(define_insn "*rorsi3_insn_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI
+	 (rotate:SI (match_operand:SI 1 "register_operand" "r")
+		    (match_operand 2 "const_int_operand" "n"))))]
+  "UINTVAL (operands[2]) < 32"
+{
+  operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
+  return "ror\\t%w0, %w1, %3";
+}
+  [(set_attr "v8type" "shift")
+   (set_attr "mode" "SI")]
+)
+
 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(ANY_EXTEND:GPI
diff --git a/gcc/testsuite/gcc.target/aarch64/ror.c b/gcc/testsuite/gcc.target/aarch64/ror.c
new file mode 100644
index 0000000..4d266f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ror.c
@@ -0,0 +1,34 @@ 
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+test_si (int a)
+{
+  /* { dg-final { scan-assembler "ror\tw\[0-9\]+, w\[0-9\]+, 27\n" } } */
+  return (a << 5) | ((unsigned int) a >> 27);
+}
+
+long long
+test_di (long long a)
+{
+  /* { dg-final { scan-assembler "ror\tx\[0-9\]+, x\[0-9\]+, 45\n" } } */
+  return (a << 19) | ((unsigned long long) a >> 45);
+}
+
+int
+main ()
+{
+  int v;
+  long long w;
+  v = test_si (0x0203050);
+  if (v != 0x4060a00)
+    abort();
+  w = test_di (0x0000020506010304ll);
+  if (w != 0x1028300818200000ll)
+    abort();
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */