diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr100028.c | 22 |
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 } } */ |