The CB<cond> family of instructions does not support using the CS or CC condition codes; instead the synonyms HS and LO must be used. GCC has traditionally used the CS and CC names. To work around this while avoiding test churn, add new `j` and `J` format specifiers; they will be used in the next commit when generating CB<cond> instructions.
Also reformat the definition of the `aarch64_cond_code` enum while we're in the same neighbourhood, to make the relationship between each code and its inverse more obvious. gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_cond_code): Reformat. (aarch64_print_operand): Add new 'j' and 'J' format specifiers. --- gcc/config/aarch64/aarch64.cc | 36 +++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 74c4b155b92..9e45a31f159 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -918,11 +918,18 @@ static const scoped_attribute_specs *const aarch64_attribute_table[] = &aarch64_arm_attribute_table }; -typedef enum aarch64_cond_code -{ - AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL, - AARCH64_VS, AARCH64_VC, AARCH64_HI, AARCH64_LS, AARCH64_GE, AARCH64_LT, - AARCH64_GT, AARCH64_LE, AARCH64_AL, AARCH64_NV +/* The condition codes come in opposing pairs. To get the inverse of a given + condition, simply flip the LSB. */ +typedef enum aarch64_cond_code { + AARCH64_EQ = 0x00, AARCH64_NE = 0x01, + AARCH64_CS = 0x02, AARCH64_CC = 0x03, + AARCH64_HS = AARCH64_CS, AARCH64_LO = AARCH64_CC, + AARCH64_MI = 0x04, AARCH64_PL = 0x05, + AARCH64_VS = 0x06, AARCH64_VC = 0x07, + AARCH64_HI = 0x08, AARCH64_LS = 0x09, + AARCH64_GE = 0x0A, AARCH64_LT = 0x0B, + AARCH64_GT = 0x0C, AARCH64_LE = 0x0D, + AARCH64_AL = 0x0E, AARCH64_NV = 0x0F, } aarch64_cc; @@ -12370,6 +12377,9 @@ sizetochar (int size) of regs. 'm': Print a condition (eq, ne, etc). 'M': Same as 'm', but invert condition. + 'j': Same as 'm', but use use `hs` and `lo` + instead of `cs` and `cc`. + 'J': Same as 'j', but invert condition. 'N': Take the duplicated element in a vector constant and print the negative of it in decimal. 'b/h/s/d/q': Print a scalar FP/SIMD register name. @@ -12499,12 +12509,14 @@ aarch64_print_operand (FILE *f, rtx x, int code) case 'M': case 'm': + case 'j': + case 'J': { int cond_code; /* CONST_TRUE_RTX means al/nv (al is the default, don't print it). */ if (x == const_true_rtx) { - if (code == 'M') + if (code == 'M' || code == 'J') fputs ("nv", f); return; } @@ -12517,12 +12529,20 @@ aarch64_print_operand (FILE *f, rtx x, int code) cond_code = aarch64_get_condition_code (x); gcc_assert (cond_code >= 0); - if (code == 'M') + if (code == 'M' || code == 'J') cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code); if (GET_MODE (XEXP (x, 0)) == CC_NZCmode) fputs (aarch64_sve_condition_codes[cond_code], f); else - fputs (aarch64_condition_codes[cond_code], f); + { + auto name = aarch64_condition_codes[cond_code]; + if (code == 'j' || code == 'J') + { + if (cond_code == AARCH64_CS) name = "hs"; + if (cond_code == AARCH64_CC) name = "lo"; + } + fputs (name, f); + } } break; -- 2.45.2