diff mbox

[AArch64] Support BFXIL in the backend

Message ID 000801ce7350$a537f990$efa7ecb0$@bolton@arm.com
State New
Headers show

Commit Message

Ian Bolton June 27, 2013, 4:09 p.m. UTC
Hi,

We don't currently generate BFXIL on AArch64. This patch addresses that,
by adding a pattern in the backend.

It comes with test cases for little and big endian.

Tested on little-endian linux and bare-metal, and big-endian linux.

OK for trunk?

Cheers,
Ian


2013-06-27  Ian Bolton  <ian.bolton@arm.com>

gcc/
	* config/aarch64/aarch64.md (*extr_insv_reg<mode>): New pattern.

testsuite/
	* gcc.target/aarch64/bfxil_1.c: New test.
	* gcc.target/aarch64/bfxil_2.c: Likewise.
diff mbox

Patch

Index: gcc/testsuite/gcc.target/aarch64/bfxil_1.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/bfxil_1.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/bfxil_1.c	(revision 0)
@@ -0,0 +1,40 @@ 
+/* { dg-do run { target aarch64*-*-* } } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target aarch64_little_endian } */
+
+extern void abort (void);
+
+typedef struct bitfield
+{
+  unsigned short eight1: 8;
+  unsigned short four: 4;
+  unsigned short eight2: 8;
+  unsigned short seven: 7;
+  unsigned int sixteen: 16;
+} bitfield;
+
+bitfield
+bfxil (bitfield a)
+{
+  /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 16, 8" } } */
+  a.eight1 = a.eight2;
+  return a;
+}
+
+int
+main (void)
+{
+  static bitfield a;
+  bitfield b;
+
+  a.eight1 = 9;
+  a.eight2 = 57;
+  b = bfxil (a);
+
+  if (b.eight1 != a.eight2)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/bfxil_2.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/bfxil_2.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/bfxil_2.c	(revision 0)
@@ -0,0 +1,42 @@ 
+/* { dg-do run { target aarch64*-*-* } } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target aarch64_big_endian } */
+
+extern void abort (void);
+
+typedef struct bitfield
+{
+  unsigned short eight1: 8;
+  unsigned short four: 4;
+  unsigned short eight2: 8;
+  unsigned short seven: 7;
+  unsigned int sixteen: 16;
+  unsigned short eight3: 8;
+  unsigned short eight4: 8;
+} bitfield;
+
+bitfield
+bfxil (bitfield a)
+{
+  /* { dg-final { scan-assembler "bfxil\tx\[0-9\]+, x\[0-9\]+, 40, 8" } } */
+  a.eight4 = a.eight2;
+  return a;
+}
+
+int
+main (void)
+{
+  static bitfield a;
+  bitfield b;
+
+  a.eight4 = 9;
+  a.eight2 = 57;
+  b = bfxil (a);
+
+  if (b.eight4 != a.eight2)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/config/aarch64/aarch64.md
===================================================================
--- gcc/config/aarch64/aarch64.md	(revision 200470)
+++ gcc/config/aarch64/aarch64.md	(working copy)
@@ -3225,6 +3225,21 @@  (define_insn "*insv_reg<mode>"
    (set_attr "mode" "<MODE>")]
 )
 
+(define_insn "*extr_insv_lower_reg<mode>"
+  [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
+			  (match_operand 1 "const_int_operand" "n")
+			  (const_int 0))
+	(zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
+			  (match_dup 1)
+			  (match_operand 3 "const_int_operand" "n")))]
+  "!(UINTVAL (operands[1]) == 0
+     || (UINTVAL (operands[3]) + UINTVAL (operands[1])
+	 > GET_MODE_BITSIZE (<MODE>mode)))"
+  "bfxil\\t%<w>0, %<w>2, %3, %1"
+  [(set_attr "v8type" "bfm")
+   (set_attr "mode" "<MODE>")]
+)
+
 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 	(ashift:GPI (ANY_EXTEND:GPI