]> git.ipfire.org Git - thirdparty/gcc.git/commit
[arm] Pattern match insns for a + ~b + Carry
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Oct 2019 16:04:53 +0000 (16:04 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Oct 2019 16:04:53 +0000 (16:04 +0000)
commite1b2c833f06c4744894e1fe7f1f5f41e862e39e5
treece3b64c8ef2a81cef3e94d237f672cb1df5004d4
parente1505d111c330e6cbb20f15b5fe784679cd30330
[arm] Pattern match insns for a + ~b + Carry

On ARM, the SBC instruction is defined as

  Ra - Rb - ~C

where C is the carry flag.  But -Rb = ~Rb + 1, so this is equivalent to

  Ra + ~Rb + 1 - ~C

which then simplifies to

  Ra + ~Rb + C

which is essentially an add-with-carry with one operand inverted.  We
can define RTL patterns to match this.  In thumb2 we can only match
when the operands are both registers, but in Arm state we can also use
RSC to match when Rn is either a constant or a shifted operand.

This overall simplifies some cases of 64-bit arithmetic, for example,

int64_t f (int64_t a, int64_t b) { return a + ~b; }

will now compile to

  MVN  R2, R2
  ADDS R0, R0, R2
  SBC  R1, R1, R3

* config/arm/arm.md (add_not_cin): New insn.
(add_not_shift_cin): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277676 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/config/arm/arm.md