diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2023-05-25 19:02:34 +0200 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2023-05-25 19:06:29 +0200 |
commit | ff0a6900700636ac4c7f40b88490a20d19a68db3 (patch) | |
tree | 4626779ce3cb81eb01cf15ad943dc1b45172f438 /gcc/config/avr | |
parent | 19fc92d8a99ed60ee3b652727f222ea656550e55 (diff) | |
download | gcc-ff0a6900700636ac4c7f40b88490a20d19a68db3.zip gcc-ff0a6900700636ac4c7f40b88490a20d19a68db3.tar.gz gcc-ff0a6900700636ac4c7f40b88490a20d19a68db3.tar.bz2 |
target/82931: Make a pattern more generic to match more bit-transfers.
There is already a pattern in avr.md that matches single-bit transfers
from one register to another one, but it only handled bit 0 of 8-bit
registers. This change makes that pattern more generic so it matches
more of similar single-bit transfers.
gcc/
PR target/82931
* config/avr/avr.md (*movbitqi.0): Rename to *movbit<mode>.0-6.
Handle any bit position and use mode QISI.
* config/avr/avr.cc (avr_rtx_costs_1) [IOR]: Return a cost
of 2 insns for bit-transfer of respective style.
gcc/testsuite/
PR target/82931
* gcc.target/avr/pr82931.c: New test.
Diffstat (limited to 'gcc/config/avr')
-rw-r--r-- | gcc/config/avr/avr.cc | 9 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 24 |
2 files changed, 23 insertions, 10 deletions
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 4fa6f53..3170696 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -10843,6 +10843,15 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total += COSTS_N_INSNS (1); return true; } + if (IOR == code + && AND == GET_CODE (XEXP (x, 0)) + && AND == GET_CODE (XEXP (x, 1)) + && single_zero_operand (XEXP (XEXP (x, 0), 1), mode)) + { + // Open-coded bit transfer. + *total = COSTS_N_INSNS (2); + return true; + } *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); if (!CONST_INT_P (XEXP (x, 1))) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index a79c682..3719659 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -9096,16 +9096,20 @@ "bst %3,0\;bld %0,%4" [(set_attr "length" "2")]) -;; Move bit $3.0 into bit $0.0. -;; For bit 0, combiner generates slightly different pattern. -(define_insn "*movbitqi.0" - [(set (match_operand:QI 0 "register_operand" "=r") - (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "single_zero_operand" "n")) - (and:QI (match_operand:QI 3 "register_operand" "r") - (const_int 1))))] - "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" - "bst %3,0\;bld %0,0" +;; Move bit $3.x into bit $0.x. +(define_insn "*movbit<mode>.0-6" + [(set (match_operand:QISI 0 "register_operand" "=r") + (ior:QISI (and:QISI (match_operand:QISI 1 "register_operand" "0") + (match_operand:QISI 2 "single_zero_operand" "n")) + (and:QISI (match_operand:QISI 3 "register_operand" "r") + (match_operand:QISI 4 "single_one_operand" "n"))))] + "GET_MODE_MASK(<MODE>mode) + == (GET_MODE_MASK(<MODE>mode) & (INTVAL(operands[2]) ^ INTVAL(operands[4])))" + { + auto bitmask = GET_MODE_MASK (<MODE>mode) & UINTVAL (operands[4]); + operands[4] = GEN_INT (exact_log2 (bitmask)); + return "bst %T3%T4" CR_TAB "bld %T0%T4"; + } [(set_attr "length" "2")]) ;; Move bit $2.0 into bit $0.7. |