[arm] Early expansion of uaddvdi4.
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 18 Oct 2019 19:04:15 +0000 (19:04 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 18 Oct 2019 19:04:15 +0000 (19:04 +0000)
commitdeb254e029c9430a0c3d0cb044e4ca7b3f15b619
tree298b85caada95864b050d03a65267b8c76b1496f
parented6588f239790be8437515ca2dc5e44568963342
[arm] Early expansion of uaddvdi4.

This code borrows strongly on the uaddvti4 expansion for aarch64 since
the principles are similar.  Firstly, if the one of the low words of
the expansion is 0, we can simply copy the other low word to the
destination and use uaddvsi4 for the upper word.  If that doesn't work
we have to handle three possible cases for the upper work (the lower
word is simply an add-with-carry operation as for adddi3): zero in the
upper word, some other constant and a register (each has a different
canonicalization).  We use CC_ADCmode (a new CC mode variant) to
describe the cases as the introduction of the carry means we can
no-longer use the normal overflow trick of comparing the sum against
one of the operands.

* config/arm/arm-modes.def (CC_ADC): New CC mode.
* config/arm/arm.c (arm_select_cc_mode): Detect selection of
CC_ADCmode.
(maybe_get_arm_condition_code): Handle CC_ADCmode.
* config/arm/arm.md (uaddvdi4): Early expansion of unsigned addition
with overflow.
(addsi3_cin_cout_reg, addsi3_cin_cout_imm, addsi3_cin_cout_0): New
expand patterns.
(addsi3_cin_cout_reg_insn, addsi3_cin_cout_0_insn): New insn patterns
(addsi3_cin_cout_imm_insn): Likewise.
(adddi3_compareC): Delete insn.
* config/arm/predicates.md (arm_carry_operation): Handle CC_ADCmode.

From-SVN: r277183
gcc/ChangeLog
gcc/config/arm/arm-modes.def
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/arm/predicates.md