This is attacking case 3 of PR 94174.

In v4, I attempt to bring over as many patterns from config/arm
as are applicable.  It's not too far away from what I had from v2.

In the process of checking all of the combinations (below), I
discovered that we could probably have a better represenation
for ccmp.  One that the optimizers can actually do something with,
rather than the if_then_else+unspec combo that we have now.

A special case of that is in the last patch: ccmp_iorne.  I think
it should be possible to come up with some sort of logical combo
that would apply to all cases, but haven't put enough thought
into the problem.


r~


Richard Henderson (12):
  aarch64: Provide expander for sub<GPI>3_compare1
  aarch64: Match add<GPI>3_carryin expander and insn
  aarch64: Add cset, csetm, cinc patterns for carry/borrow
  aarch64: Add const_dword_umaxp1
  aarch64: Improvements to aarch64_select_cc_mode from arm
  aarch64: Introduce aarch64_expand_addsubti
  aarch64: Rename CC_ADCmode to CC_NOTCmode
  arm: Merge CC_ADC and CC_B to CC_NOTC
  aarch64: Use CC_NOTCmode for double-word subtract
  aarch64: Adjust result of aarch64_gen_compare_reg
  aarch64: Accept 0 as first argument to compares
  aarch64: Implement TImode comparisons

 gcc/config/aarch64/aarch64-protos.h           |  10 +-
 gcc/config/aarch64/aarch64.c                  | 356 ++++++++-----
 gcc/config/arm/arm.c                          |  30 +-
 gcc/testsuite/gcc.target/aarch64/asm-flag-1.c |   3 +-
 gcc/config/aarch64/aarch64-modes.def          |   6 +-
 gcc/config/aarch64/aarch64-simd.md            |  18 +-
 gcc/config/aarch64/aarch64-speculation.cc     |   5 +-
 gcc/config/aarch64/aarch64.md                 | 473 +++++++++++-------
 gcc/config/aarch64/iterators.md               |   3 +
 gcc/config/aarch64/predicates.md              |  22 +-
 gcc/config/arm/arm-modes.def                  |  12 +-
 gcc/config/arm/arm.md                         |  36 +-
 gcc/config/arm/iterators.md                   |   2 +-
 gcc/config/arm/predicates.md                  |   4 +-
 14 files changed, 580 insertions(+), 400 deletions(-)

---

typedef signed long long s64;
typedef unsigned long long u64;
typedef __uint128_t u128;
typedef __int128_t s128;

#define i128(hi,lo) (((u128)(hi) << 64) | (u64)(lo))

int eq(u128 a, u128 b)  { return a == b; }
int ne(u128 a, u128 b)  { return a != b; }
int ltu(u128 a, u128 b) { return a < b; }
int geu(u128 a, u128 b) { return a >= b; }
int leu(u128 a, u128 b) { return a <= b; }
int gtu(u128 a, u128 b) { return a > b; }
int lt(s128 a, s128 b) { return a < b; }
int ge(s128 a, s128 b) { return a >= b; }
int le(s128 a, s128 b) { return a <= b; }
int gt(s128 a, s128 b) { return a > b; }

int eqS(u128 a, u64 b)  { return a == b; }
int neS(u128 a, u64 b)  { return a != b; }
int ltuS(u128 a, u64 b) { return a < b; }
int geuS(u128 a, u64 b) { return a >= b; }
int leuS(u128 a, u64 b) { return a <= b; }
int gtuS(u128 a, u64 b) { return a > b; }
int ltS(s128 a, s64 b) { return a < b; }
int geS(s128 a, s64 b) { return a >= b; }
int leS(s128 a, s64 b) { return a <= b; }
int gtS(s128 a, s64 b) { return a > b; }

int eqSH(u128 a, u64 b)  { return a == (u128)b << 64; }
int neSH(u128 a, u64 b)  { return a != (u128)b << 64; }
int ltuSH(u128 a, u64 b) { return a < (u128)b << 64; }
int geuSH(u128 a, u64 b) { return a >= (u128)b << 64; }
int leuSH(u128 a, u64 b) { return a <= (u128)b << 64; }
int gtuSH(u128 a, u64 b) { return a > (u128)b << 64; }
int ltSH(s128 a, s64 b) { return a < (s128)b << 64; }
int geSH(s128 a, s64 b) { return a >= (s128)b << 64; }
int leSH(s128 a, s64 b) { return a <= (s128)b << 64; }
int gtSH(s128 a, s64 b) { return a > (s128)b << 64; }

int eqFFHS(u128 a, u64 b)  { return a == i128(-1,b); }
int neFFHS(u128 a, u64 b)  { return a != i128(-1,b); }
int ltuFFHS(u128 a, u64 b) { return a < i128(-1,b); }
int geuFFHS(u128 a, u64 b) { return a >= i128(-1,b); }
int leuFFHS(u128 a, u64 b) { return a <= i128(-1,b); }
int gtuFFHS(u128 a, u64 b) { return a > i128(-1,b); }
int ltFFHS(s128 a, s64 b) { return a < (s128)i128(-1,b); }
int geFFHS(s128 a, s64 b) { return a >= (s128)i128(-1,b); }
int leFFHS(s128 a, s64 b) { return a <= (s128)i128(-1,b); }
int gtFFHS(s128 a, s64 b) { return a > (s128)i128(-1,b); }

int eq0(u128 a) { return a == 0; }
int ne0(u128 a) { return a != 0; }
int ltu0(u128 a) { return a < 0; }
int geu0(u128 a) { return a >= 0; }
int leu0(u128 a) { return a <= 0; }
int gtu0(u128 a) { return a > 0; }
int lt0(s128 a) { return a < 0; }
int ge0(s128 a) { return a >= 0; }
int le0(s128 a) { return a <= 0; }
int gt0(s128 a) { return a > 0; }

int eq1(u128 a) { return a == 1; }
int ne1(u128 a) { return a != 1; }
int ltu1(u128 a) { return a < 1; }
int geu1(u128 a) { return a >= 1; }
int leu1(u128 a) { return a <= 1; }
int gtu1(u128 a) { return a > 1; }
int lt1(s128 a) { return a < 1; }
int ge1(s128 a) { return a >= 1; }
int le1(s128 a) { return a <= 1; }
int gt1(s128 a) { return a > 1; }

int eqm1(u128 a) { return a == -1; }
int nem1(u128 a) { return a != -1; }
int ltum1(u128 a) { return a < -1; }
int geum1(u128 a) { return a >= -1; }
int leum1(u128 a) { return a <= -1; }
int gtum1(u128 a) { return a > -1; }
int ltm1(s128 a) { return a < -1; }
int gem1(s128 a) { return a >= -1; }
int lem1(s128 a) { return a <= -1; }
int gtm1(s128 a) { return a > -1; }

int eq42(u128 a) { return a == 42; }
int ne42(u128 a) { return a != 42; }
int ltu42(u128 a) { return a < 42; }
int geu42(u128 a) { return a >= 42; }
int leu42(u128 a) { return a <= 42; }
int gtu42(u128 a) { return a > 42; }
int lt42(s128 a) { return a < 42; }
int ge42(s128 a) { return a >= 42; }
int le42(s128 a) { return a <= 42; }
int gt42(s128 a) { return a > 42; }

int eqFF(u128 a) { return a == (u64)-1; }
int neFF(u128 a) { return a != (u64)-1; }
int ltuFF(u128 a) { return a < (u64)-1; }
int geuFF(u128 a) { return a >= (u64)-1; }
int leuFF(u128 a) { return a <= (u64)-1; }
int gtuFF(u128 a) { return a > (u64)-1; }
int ltFF(s128 a) { return a < (u64)-1; }
int geFF(s128 a) { return a >= (u64)-1; }
int leFF(s128 a) { return a <= (u64)-1; }
int gtFF(s128 a) { return a > (u64)-1; }

int eq1H(u128 a) { return a == i128(1,0); }
int ne1H(u128 a) { return a != i128(1,0); }
int ltu1H(u128 a) { return a < i128(1,0); }
int geu1H(u128 a) { return a >= i128(1,0); }
int leu1H(u128 a) { return a <= i128(1,0); }
int gtu1H(u128 a) { return a > i128(1,0); }
int lt1H(s128 a) { return a < i128(1,0); }
int ge1H(s128 a) { return a >= i128(1,0); }
int le1H(s128 a) { return a <= i128(1,0); }
int gt1H(s128 a) { return a > i128(1,0); }

int eqFFH(u128 a) { return a == i128(-1,0); }
int neFFH(u128 a) { return a != i128(-1,0); }
int ltuFFH(u128 a) { return a < i128(-1,0); }
int geuFFH(u128 a) { return a >= i128(-1,0); }
int leuFFH(u128 a) { return a <= i128(-1,0); }
int gtuFFH(u128 a) { return a > i128(-1,0); }
int ltFFH(s128 a) { return a < i128(-1,0); }
int geFFH(s128 a) { return a >= i128(-1,0); }
int leFFH(s128 a) { return a <= i128(-1,0); }
int gtFFH(s128 a) { return a > i128(-1,0); }

Reply via email to