arm: Improve code generation for BFI and BFC [PR105090]
authorRichard Earnshaw <rearnsha@arm.com>
Tue, 7 Jun 2022 11:09:47 +0000 (12:09 +0100)
committerRichard Earnshaw <rearnsha@arm.com>
Tue, 7 Jun 2022 11:12:20 +0000 (12:12 +0100)
commit2005b9b888eeac078f2524b1521885f4b5453894
tree7feb149446b78c04b04813229950996e9beb1010
parentcd22395457f063824c839fd1c0077d15d3dccd6d
arm: Improve code generation for BFI and BFC [PR105090]

This patch, in response to PR105090, makes some general improvements
to the code generation when BFI and BFC instructions are available.
Firstly we handle more cases where the RTL does not generate an INSV
operation due to a lack of a tie between the input and output, but we
nevertheless need to emit BFI later on; we handle this by requiring
the register allocator to tie the operands.  Secondly we handle some
cases where we were previously emitting BFC, but AND with an immediate
would be better; we do this by converting all BFC patterns into AND
using a split pattern.  And finally, we handle some cases where
previously we would emit multiple BIC operations to clear a value, but
could instead use a single BFC instruction.

BFC and BFI express the mask as a pair of values, one for the number
of bits to clear and another for the location of the least significant
bit.  We handle these with a single new output modifier letter that
causes both values to be printed; we use an 'inverted' value so that
it can be used directly with the constant used in an AND rtl
construct.  We've run out of 'new' letters, so to do this we re-use
one of the long-obsoleted Maverick output modifiers.

gcc/ChangeLog:

PR target/105090
* config/arm/arm.cc (arm_bfi_1_p): New function.
(arm_bfi_p): New function.
(arm_rtx_costs_internal): Add costs for BFI idioms.
(arm_print_operand [case 'V']): Format output for BFI/BFC masks.
* config/arm/constraints.md (Dj): New constraint.
* config/arm/arm.md (arm_andsi3_insn): Add alternative to use BFC.
(insv_zero): Convert to an insn with a split.
(*bfi, *bfi_alt1, *bfi_alt2, *bfi_alt3): New patterns.
gcc/config/arm/arm.cc
gcc/config/arm/arm.md
gcc/config/arm/constraints.md