Patchwork [AArch64] Support ROR in backend

login
register
mail settings
Submitter Ian Bolton
Date March 14, 2013, 3:42 p.m.
Message ID <000401ce20ca$8ab84da0$a028e8e0$@bolton@arm.com>
Download mbox | patch
Permalink /patch/227721/
State New
Headers show

Comments

Ian Bolton - March 14, 2013, 3:42 p.m.
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.
Marcus Shawcroft - March 15, 2013, 2:30 p.m.
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

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 } } */