Commit 65f9e789 by Ian Bolton Committed by Ian Bolton

AArch64 - Support BFI instruction and insv pattern

From-SVN: r199454
parent f1ad09d9
2013-05-30 Ian Bolton <ian.bolton@arm.com>
* config/aarch64/aarch64.md (insv<mode>): New define_expand.
(*insv_reg<mode>): New define_insn.
2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57439
......
......@@ -3163,6 +3163,50 @@
(set_attr "mode" "<MODE>")]
)
;; Bitfield Insert (insv)
(define_expand "insv<mode>"
[(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
(match_operand 1 "const_int_operand")
(match_operand 2 "const_int_operand"))
(match_operand:GPI 3 "general_operand"))]
""
{
unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
rtx value = operands[3];
if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
FAIL;
if (CONST_INT_P (value))
{
unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
/* Prefer AND/OR for inserting all zeros or all ones. */
if ((UINTVAL (value) & mask) == 0
|| (UINTVAL (value) & mask) == mask)
FAIL;
/* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
if (width == 16 && (pos % 16) == 0)
DONE;
}
operands[3] = force_reg (<MODE>mode, value);
})
(define_insn "*insv_reg<mode>"
[(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
(match_operand 1 "const_int_operand" "n")
(match_operand 2 "const_int_operand" "n"))
(match_operand:GPI 3 "register_operand" "r"))]
"!(UINTVAL (operands[1]) == 0
|| (UINTVAL (operands[2]) + UINTVAL (operands[1])
> GET_MODE_BITSIZE (<MODE>mode)))"
"bfi\\t%<w>0, %<w>3, %2, %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
......
2013-05-30 Ian Bolton <ian.bolton@arm.com>
* gcc.target/aarch64/insv_1.c: New test.
2013-05-30 Yufeng Zhang <yufeng.zhang@arm.com>
* g++.dg/cpp0x/alias-decl-debug-0.C: Add aarch64*-*-* to the
......
/* { dg-do run } */
/* { dg-options "-O2 --save-temps -fno-inline" } */
extern void abort (void);
typedef struct bitfield
{
unsigned short eight: 8;
unsigned short four: 4;
unsigned short five: 5;
unsigned short seven: 7;
unsigned int sixteen: 16;
} bitfield;
bitfield
bfi1 (bitfield a)
{
/* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 0, 8" } } */
a.eight = 3;
return a;
}
bitfield
bfi2 (bitfield a)
{
/* { dg-final { scan-assembler "bfi\tx\[0-9\]+, x\[0-9\]+, 16, 5" } } */
a.five = 7;
return a;
}
bitfield
movk (bitfield a)
{
/* { dg-final { scan-assembler "movk\tx\[0-9\]+, 0x1d6b, lsl 32" } } */
a.sixteen = 7531;
return a;
}
bitfield
set1 (bitfield a)
{
/* { dg-final { scan-assembler "orr\tx\[0-9\]+, x\[0-9\]+, 2031616" } } */
a.five = 0x1f;
return a;
}
bitfield
set0 (bitfield a)
{
/* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -2031617" } } */
a.five = 0;
return a;
}
int
main (int argc, char** argv)
{
static bitfield a;
bitfield b = bfi1 (a);
bitfield c = bfi2 (b);
bitfield d = movk (c);
if (d.eight != 3)
abort ();
if (d.five != 7)
abort ();
if (d.sixteen != 7531)
abort ();
d = set1 (d);
if (d.five != 0x1f)
abort ();
d = set0 (d);
if (d.five != 0)
abort ();
return 0;
}
/* { dg-final { cleanup-saved-temps } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment