aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/aarch64/aarch64.md32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr100028.c22
2 files changed, 54 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a149748..9a7ed78 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5601,6 +5601,38 @@
[(set_attr "type" "bfm")]
)
+(define_insn "*aarch64_bfxil<mode>_extr"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "0")
+ (match_operand:GPI 2 "const_int_operand" "n"))
+ (zero_extract:GPI
+ (match_operand:GPI 3 "register_operand" "r")
+ (match_operand:GPI 4 "aarch64_simd_shift_imm_<mode>" "n")
+ (match_operand:GPI 5 "aarch64_simd_shift_imm_<mode>" "n"))))]
+ "UINTVAL (operands[2]) == HOST_WIDE_INT_M1U << INTVAL (operands[4])
+ && INTVAL (operands[4])
+ && (UINTVAL (operands[4]) + UINTVAL (operands[5])
+ <= GET_MODE_BITSIZE (<MODE>mode))"
+ "bfxil\t%<GPI:w>0, %<GPI:w>3, %5, %4"
+ [(set_attr "type" "bfm")]
+)
+
+(define_insn "*aarch64_bfxilsi_extrdi"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (match_operator:SI 6 "subreg_lowpart_operator"
+ [(zero_extract:DI
+ (match_operand:DI 3 "register_operand" "r")
+ (match_operand:SI 4 "aarch64_simd_shift_imm_si" "n")
+ (match_operand:SI 5 "aarch64_simd_shift_imm_si" "n"))])))]
+ "UINTVAL (operands[2]) == HOST_WIDE_INT_M1U << INTVAL (operands[4])
+ && INTVAL (operands[4])
+ && UINTVAL (operands[4]) + UINTVAL (operands[5]) <= 32"
+ "bfxil\t%w0, %w3, %5, %4"
+ [(set_attr "type" "bfm")]
+)
+
(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")
diff --git a/gcc/testsuite/gcc.target/aarch64/pr100028.c b/gcc/testsuite/gcc.target/aarch64/pr100028.c
new file mode 100644
index 0000000..a25b929
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr100028.c
@@ -0,0 +1,22 @@
+/* PR target/100028 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#define W 3
+#define L 11
+
+int
+foo (int d, int s)
+{
+ int wmask = (1 << W) - 1;
+ return (d & ~wmask) | ((s >> L) & wmask);
+}
+
+long long int
+bar (long long int d, long long int s)
+{
+ long long int wmask = (1LL << W) - 1;
+ return (d & ~wmask) | ((s >> L) & wmask);
+}
+
+/* { dg-final { scan-assembler-times {\tbfxil\t} 2 } } */