From c8012fbce973bebc5cf2a9905ebfa9fbaec1afa0 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Tue, 19 Jan 2016 13:59:56 +0000 Subject: [PATCH] [Patch 1/4] Simplify the representation of CCMP patterns by using 2015-01-19 Wilco Dijkstra gcc/ * target.def (gen_ccmp_first): Update documentation. (gen_ccmp_next): Likewise. * doc/tm.texi (gen_ccmp_first): Update documentation. (gen_ccmp_next): Likewise. * ccmp.c (expand_ccmp_expr): Extract cmp_code from return value of expand_ccmp_expr_1. Improve comments. * config/aarch64/aarch64.md (ccmp_and): Use if_then_else for ccmp. (ccmp_ior): Remove pattern. (cmp): Remove expand. (cmp): Globalize pattern. (cstorecc4): Use cc_register. (movcc): Remove ccmp_cc_register check. * config/aarch64/aarch64.c (aarch64_get_condition_code_1): Simplify after removal of CC_DNE/* modes. (aarch64_ccmp_mode_to_code): Remove. (aarch64_print_operand): Remove 'K' case. Merge 'm' and 'M' cases. In 'k' case use integer as condition. (aarch64_nzcv_codes): Remove inverted cases. (aarch64_code_to_ccmode): Remove. (aarch64_gen_ccmp_first): Use cmp pattern directly. Return the correct comparison with CC register to be used in folowing CCMP/branch/CSEL. (aarch64_gen_ccmp_next): Use previous comparison and mode in CCMP pattern. Return the comparison with CC register. Invert conditions when bitcode is OR. * config/aarch64/aarch64-modes.def: Remove CC_DNE/* modes. * config/aarch64/predicates.md (ccmp_cc_register): Remove. From-SVN: r232561 --- gcc/ChangeLog | 29 ++++ gcc/ccmp.c | 21 ++- gcc/config/aarch64/aarch64-modes.def | 10 -- gcc/config/aarch64/aarch64.c | 305 ++++++++--------------------------- gcc/config/aarch64/aarch64.md | 68 ++------ gcc/config/aarch64/predicates.md | 17 -- gcc/doc/tm.texi | 36 ++--- gcc/target.def | 36 ++--- 8 files changed, 157 insertions(+), 365 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ea4d2b..93cb42a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2016-01-19 Wilco Dijkstra + + * target.def (gen_ccmp_first): Update documentation. + (gen_ccmp_next): Likewise. + * doc/tm.texi (gen_ccmp_first): Update documentation. + (gen_ccmp_next): Likewise. + * ccmp.c (expand_ccmp_expr): Extract cmp_code from return value of + expand_ccmp_expr_1. Improve comments. + * config/aarch64/aarch64.md (ccmp_and): Use if_then_else for ccmp. + (ccmp_ior): Remove pattern. + (cmp): Remove expand. + (cmp): Globalize pattern. + (cstorecc4): Use cc_register. + (movcc): Remove ccmp_cc_register check. + * config/aarch64/aarch64.c (aarch64_get_condition_code_1): + Simplify after removal of CC_DNE/* modes. + (aarch64_ccmp_mode_to_code): Remove. + (aarch64_print_operand): Remove 'K' case. Merge 'm' and 'M' cases. + In 'k' case use integer as condition. + (aarch64_nzcv_codes): Remove inverted cases. + (aarch64_code_to_ccmode): Remove. + (aarch64_gen_ccmp_first): Use cmp pattern directly. Return the correct + comparison with CC register to be used in folowing CCMP/branch/CSEL. + (aarch64_gen_ccmp_next): Use previous comparison and mode in CCMP + pattern. Return the comparison with CC register. Invert conditions + when bitcode is OR. + * config/aarch64/aarch64-modes.def: Remove CC_DNE/* modes. + * config/aarch64/predicates.md (ccmp_cc_register): Remove. + 2016-01-19 Jan Hubicka * cgraphunit.c (cgraph_node::reset): Clear thunk info and diff --git a/gcc/ccmp.c b/gcc/ccmp.c index 72f2db1..28fe189 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -49,6 +49,10 @@ along with GCC; see the file COPYING3. If not see - gen_ccmp_first expands the first compare in CCMP. - gen_ccmp_next expands the following compares. + Both hooks return a comparison with the CC register that is equivalent + to the value of the gimple comparison. This is used by the next CCMP + and in the final conditional store. + * We use cstorecc4 pattern to convert the CCmode intermediate to the integer mode result that expand_normal is expecting. @@ -114,10 +118,12 @@ ccmp_candidate_p (gimple *g) return false; } -/* PREV is the CC flag from precvious compares. The function expands the - next compare based on G which ops previous compare with CODE. +/* PREV is a comparison with the CC register which represents the + result of the previous CMP or CCMP. The function expands the + next compare based on G which is ANDed/ORed with the previous + compare depending on CODE. PREP_SEQ returns all insns to prepare opearands for compare. - GEN_SEQ returnss all compare insns. */ + GEN_SEQ returns all compare insns. */ static rtx expand_ccmp_next (gimple *g, enum tree_code code, rtx prev, rtx *prep_seq, rtx *gen_seq) @@ -210,7 +216,7 @@ expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq) return NULL_RTX; } -/* Main entry to expand conditional compare statement G. +/* Main entry to expand conditional compare statement G. Return NULL_RTX if G is not a legal candidate or expand fail. Otherwise return the target. */ rtx @@ -233,9 +239,10 @@ expand_ccmp_expr (gimple *g) enum insn_code icode; enum machine_mode cc_mode = CCmode; tree lhs = gimple_assign_lhs (g); + rtx_code cmp_code = GET_CODE (tmp); #ifdef SELECT_CC_MODE - cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx); + cc_mode = SELECT_CC_MODE (cmp_code, XEXP (tmp, 0), const0_rtx); #endif icode = optab_handler (cstore_optab, cc_mode); if (icode != CODE_FOR_nothing) @@ -246,8 +253,8 @@ expand_ccmp_expr (gimple *g) emit_insn (prep_seq); emit_insn (gen_seq); - tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode, - 0, tmp, const0_rtx, 1, mode); + tmp = emit_cstore (target, icode, cmp_code, cc_mode, cc_mode, + 0, XEXP (tmp, 0), const0_rtx, 1, mode); if (tmp) return tmp; } diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def index 1c94b3c..3fab205 100644 --- a/gcc/config/aarch64/aarch64-modes.def +++ b/gcc/config/aarch64/aarch64-modes.def @@ -25,16 +25,6 @@ CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS). */ CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */ CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */ CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */ -CC_MODE (CC_DNE); -CC_MODE (CC_DEQ); -CC_MODE (CC_DLE); -CC_MODE (CC_DLT); -CC_MODE (CC_DGE); -CC_MODE (CC_DGT); -CC_MODE (CC_DLEU); -CC_MODE (CC_DLTU); -CC_MODE (CC_DGEU); -CC_MODE (CC_DGTU); /* Half-precision floating point for __fp16. */ FLOAT_MODE (HF, 2, 0); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 73ef7e5..041e642 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4205,7 +4205,6 @@ aarch64_get_condition_code (rtx x) static int aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code) { - int ne = -1, eq = -1; switch (mode) { case CCFPmode: @@ -4228,56 +4227,6 @@ aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code) } break; - case CC_DNEmode: - ne = AARCH64_NE; - eq = AARCH64_EQ; - break; - - case CC_DEQmode: - ne = AARCH64_EQ; - eq = AARCH64_NE; - break; - - case CC_DGEmode: - ne = AARCH64_GE; - eq = AARCH64_LT; - break; - - case CC_DLTmode: - ne = AARCH64_LT; - eq = AARCH64_GE; - break; - - case CC_DGTmode: - ne = AARCH64_GT; - eq = AARCH64_LE; - break; - - case CC_DLEmode: - ne = AARCH64_LE; - eq = AARCH64_GT; - break; - - case CC_DGEUmode: - ne = AARCH64_CS; - eq = AARCH64_CC; - break; - - case CC_DLTUmode: - ne = AARCH64_CC; - eq = AARCH64_CS; - break; - - case CC_DGTUmode: - ne = AARCH64_HI; - eq = AARCH64_LS; - break; - - case CC_DLEUmode: - ne = AARCH64_LS; - eq = AARCH64_HI; - break; - case CCmode: switch (comp_code) { @@ -4339,12 +4288,6 @@ aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code) break; } - if (comp_code == NE) - return ne; - - if (comp_code == EQ) - return eq; - return -1; } @@ -4385,69 +4328,27 @@ aarch64_const_vec_all_same_int_p (rtx x, HOST_WIDE_INT val) #define AARCH64_CC_Z (1 << 2) #define AARCH64_CC_N (1 << 3) -/* N Z C V flags for ccmp. The first code is for AND op and the other - is for IOR op. Indexed by AARCH64_COND_CODE. */ -static const int aarch64_nzcv_codes[][2] = -{ - {AARCH64_CC_Z, 0}, /* EQ, Z == 1. */ - {0, AARCH64_CC_Z}, /* NE, Z == 0. */ - {AARCH64_CC_C, 0}, /* CS, C == 1. */ - {0, AARCH64_CC_C}, /* CC, C == 0. */ - {AARCH64_CC_N, 0}, /* MI, N == 1. */ - {0, AARCH64_CC_N}, /* PL, N == 0. */ - {AARCH64_CC_V, 0}, /* VS, V == 1. */ - {0, AARCH64_CC_V}, /* VC, V == 0. */ - {AARCH64_CC_C, 0}, /* HI, C ==1 && Z == 0. */ - {0, AARCH64_CC_C}, /* LS, !(C == 1 && Z == 0). */ - {0, AARCH64_CC_V}, /* GE, N == V. */ - {AARCH64_CC_V, 0}, /* LT, N != V. */ - {0, AARCH64_CC_Z}, /* GT, Z == 0 && N == V. */ - {AARCH64_CC_Z, 0}, /* LE, !(Z == 0 && N == V). */ - {0, 0}, /* AL, Any. */ - {0, 0}, /* NV, Any. */ +/* N Z C V flags for ccmp. Indexed by AARCH64_COND_CODE. */ +static const int aarch64_nzcv_codes[] = +{ + 0, /* EQ, Z == 1. */ + AARCH64_CC_Z, /* NE, Z == 0. */ + 0, /* CS, C == 1. */ + AARCH64_CC_C, /* CC, C == 0. */ + 0, /* MI, N == 1. */ + AARCH64_CC_N, /* PL, N == 0. */ + 0, /* VS, V == 1. */ + AARCH64_CC_V, /* VC, V == 0. */ + 0, /* HI, C ==1 && Z == 0. */ + AARCH64_CC_C, /* LS, !(C == 1 && Z == 0). */ + AARCH64_CC_V, /* GE, N == V. */ + 0, /* LT, N != V. */ + AARCH64_CC_Z, /* GT, Z == 0 && N == V. */ + 0, /* LE, !(Z == 0 && N == V). */ + 0, /* AL, Any. */ + 0 /* NV, Any. */ }; -int -aarch64_ccmp_mode_to_code (enum machine_mode mode) -{ - switch (mode) - { - case CC_DNEmode: - return NE; - - case CC_DEQmode: - return EQ; - - case CC_DLEmode: - return LE; - - case CC_DGTmode: - return GT; - - case CC_DLTmode: - return LT; - - case CC_DGEmode: - return GE; - - case CC_DLEUmode: - return LEU; - - case CC_DGTUmode: - return GTU; - - case CC_DLTUmode: - return LTU; - - case CC_DGEUmode: - return GEU; - - default: - gcc_unreachable (); - } -} - - static void aarch64_print_operand (FILE *f, rtx x, int code) { @@ -4546,36 +4447,17 @@ aarch64_print_operand (FILE *f, rtx x, int code) asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]); break; - case 'm': - { - int cond_code; - /* Print a condition (eq, ne, etc). */ - - /* CONST_TRUE_RTX means always -- that's the default. */ - if (x == const_true_rtx) - return; - - if (!COMPARISON_P (x)) - { - output_operand_lossage ("invalid operand for '%%%c'", code); - return; - } - - cond_code = aarch64_get_condition_code (x); - gcc_assert (cond_code >= 0); - fputs (aarch64_condition_codes[cond_code], f); - } - break; - case 'M': + case 'm': { int cond_code; - /* Print the inverse of a condition (eq <-> ne, etc). */ + /* Print a condition (eq, ne, etc) or its inverse. */ - /* CONST_TRUE_RTX means never -- that's the default. */ - if (x == const_true_rtx) + /* CONST_TRUE_RTX means al/nv (al is the default, don't print it). */ + if (x == const_true_rtx) { - fputs ("nv", f); + if (code == 'M') + fputs ("nv", f); return; } @@ -4584,10 +4466,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) output_operand_lossage ("invalid operand for '%%%c'", code); return; } + cond_code = aarch64_get_condition_code (x); gcc_assert (cond_code >= 0); - fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE - (cond_code)], f); + if (code == 'M') + cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code); + fputs (aarch64_condition_codes[cond_code], f); } break; @@ -4828,37 +4712,20 @@ aarch64_print_operand (FILE *f, rtx x, int code) output_addr_const (asm_out_file, x); break; - case 'K': - { - int cond_code; - /* Print nzcv. */ - - if (!COMPARISON_P (x)) - { - output_operand_lossage ("invalid operand for '%%%c'", code); - return; - } - - cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x)); - gcc_assert (cond_code >= 0); - asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][0]); - } - break; - case 'k': { - int cond_code; + HOST_WIDE_INT cond_code; /* Print nzcv. */ - if (!COMPARISON_P (x)) + if (!CONST_INT_P (x)) { output_operand_lossage ("invalid operand for '%%%c'", code); return; } - cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x)); - gcc_assert (cond_code >= 0); - asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][1]); + cond_code = INTVAL (x); + gcc_assert (cond_code >= 0 && cond_code <= AARCH64_NV); + asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code]); } break; @@ -13066,60 +12933,16 @@ aarch64_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, return default_use_by_pieces_infrastructure_p (size, align, op, speed_p); } -static enum machine_mode -aarch64_code_to_ccmode (enum rtx_code code) -{ - switch (code) - { - case NE: - return CC_DNEmode; - - case EQ: - return CC_DEQmode; - - case LE: - return CC_DLEmode; - - case LT: - return CC_DLTmode; - - case GE: - return CC_DGEmode; - - case GT: - return CC_DGTmode; - - case LEU: - return CC_DLEUmode; - - case LTU: - return CC_DLTUmode; - - case GEU: - return CC_DGEUmode; - - case GTU: - return CC_DGTUmode; - - default: - return CCmode; - } -} - static rtx aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq, int code, tree treeop0, tree treeop1) { - enum machine_mode op_mode, cmp_mode, cc_mode; - rtx op0, op1, cmp, target; + machine_mode op_mode, cmp_mode, cc_mode = CCmode; + rtx op0, op1; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); - enum insn_code icode; + insn_code icode; struct expand_operand ops[4]; - cc_mode = aarch64_code_to_ccmode ((enum rtx_code) code); - if (cc_mode == CCmode) - return NULL_RTX; - start_sequence (); expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); @@ -13146,8 +12969,8 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq, return NULL_RTX; } - op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp); - op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp); + op0 = prepare_operand (icode, op0, 0, op_mode, cmp_mode, unsignedp); + op1 = prepare_operand (icode, op1, 1, op_mode, cmp_mode, unsignedp); if (!op0 || !op1) { end_sequence (); @@ -13156,16 +12979,11 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq, *prep_seq = get_insns (); end_sequence (); - cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1); - target = gen_rtx_REG (CCmode, CC_REGNUM); - - create_output_operand (&ops[0], target, CCmode); - create_fixed_operand (&ops[1], cmp); - create_fixed_operand (&ops[2], op0); - create_fixed_operand (&ops[3], op1); + create_fixed_operand (&ops[0], op0); + create_fixed_operand (&ops[1], op1); start_sequence (); - if (!maybe_expand_insn (icode, 4, ops)) + if (!maybe_expand_insn (icode, 2, ops)) { end_sequence (); return NULL_RTX; @@ -13173,22 +12991,20 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq, *gen_seq = get_insns (); end_sequence (); - return gen_rtx_REG (cc_mode, CC_REGNUM); + return gen_rtx_fmt_ee ((rtx_code) code, cc_mode, + gen_rtx_REG (cc_mode, CC_REGNUM), const0_rtx); } static rtx aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree treeop0, tree treeop1, int bit_code) { - rtx op0, op1, cmp0, cmp1, target; - enum machine_mode op_mode, cmp_mode, cc_mode; + rtx op0, op1, target; + machine_mode op_mode, cmp_mode, cc_mode = CCmode; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); - enum insn_code icode = CODE_FOR_ccmp_andsi; + insn_code icode; struct expand_operand ops[6]; - - cc_mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code); - if (cc_mode == CCmode) - return NULL_RTX; + int aarch64_cond; push_to_sequence ((rtx_insn*) *prep_seq); expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); @@ -13203,14 +13019,12 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, case HImode: case SImode: cmp_mode = SImode; - icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_andsi - : CODE_FOR_ccmp_iorsi; + icode = CODE_FOR_ccmpsi; break; case DImode: cmp_mode = DImode; - icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_anddi - : CODE_FOR_ccmp_iordi; + icode = CODE_FOR_ccmpdi; break; default: @@ -13229,15 +13043,22 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, end_sequence (); target = gen_rtx_REG (cc_mode, CC_REGNUM); - cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, cmp_mode, op0, op1); - cmp0 = gen_rtx_fmt_ee (NE, cmp_mode, prev, const0_rtx); + aarch64_cond = aarch64_get_condition_code_1 (cc_mode, (rtx_code) cmp_code); - create_fixed_operand (&ops[0], prev); + if (bit_code != AND) + { + prev = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (prev), + GET_MODE (XEXP (prev, 0))), + VOIDmode, XEXP (prev, 0), const0_rtx); + aarch64_cond = AARCH64_INVERSE_CONDITION_CODE (aarch64_cond); + } + + create_fixed_operand (&ops[0], XEXP (prev, 0)); create_fixed_operand (&ops[1], target); create_fixed_operand (&ops[2], op0); create_fixed_operand (&ops[3], op1); - create_fixed_operand (&ops[4], cmp0); - create_fixed_operand (&ops[5], cmp1); + create_fixed_operand (&ops[4], prev); + create_fixed_operand (&ops[5], GEN_INT (aarch64_cond)); push_to_sequence ((rtx_insn*) *gen_seq); if (!maybe_expand_insn (icode, 6, ops)) @@ -13249,7 +13070,7 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, *gen_seq = get_insns (); end_sequence (); - return target; + return gen_rtx_fmt_ee ((rtx_code) cmp_code, VOIDmode, target, const0_rtx); } #undef TARGET_GEN_CCMP_FIRST diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index bde231b..d8ae8e8 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -271,18 +271,17 @@ "" "") -(define_insn "ccmp_and" - [(set (match_operand 1 "ccmp_cc_register" "") - (compare - (and:SI +(define_insn "ccmp" + [(set (match_operand:CC 1 "cc_register" "") + (if_then_else:CC (match_operator 4 "aarch64_comparison_operator" - [(match_operand 0 "ccmp_cc_register" "") + [(match_operand 0 "cc_register" "") (const_int 0)]) - (match_operator 5 "aarch64_comparison_operator" - [(match_operand:GPI 2 "register_operand" "r,r,r") - (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")])) - (const_int 0)))] - "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])" + (compare:CC + (match_operand:GPI 2 "register_operand" "r,r,r") + (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")) + (match_operand 5 "immediate_operand")))] + "" "@ ccmp\\t%2, %3, %k5, %m4 ccmp\\t%2, %3, %k5, %m4 @@ -290,39 +289,6 @@ [(set_attr "type" "alus_sreg,alus_imm,alus_imm")] ) -(define_insn "ccmp_ior" - [(set (match_operand 1 "ccmp_cc_register" "") - (compare - (ior:SI - (match_operator 4 "aarch64_comparison_operator" - [(match_operand 0 "ccmp_cc_register" "") - (const_int 0)]) - (match_operator 5 "aarch64_comparison_operator" - [(match_operand:GPI 2 "register_operand" "r,r,r") - (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")])) - (const_int 0)))] - "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])" - "@ - ccmp\\t%2, %3, %K5, %M4 - ccmp\\t%2, %3, %K5, %M4 - ccmn\\t%2, #%n3, %K5, %M4" - [(set_attr "type" "alus_sreg,alus_imm,alus_imm")] -) - -(define_expand "cmp" - [(set (match_operand 0 "cc_register" "") - (match_operator:CC 1 "aarch64_comparison_operator" - [(match_operand:GPI 2 "register_operand" "") - (match_operand:GPI 3 "aarch64_plus_operand" "")]))] - "" - { - operands[1] = gen_rtx_fmt_ee (COMPARE, - SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]), - operands[2], operands[3]); - } -) - ;; Expansion of signed mod by a power of 2 using CSNEG. ;; For x0 % n where n is a power of 2 produce: ;; negs x1, x0 @@ -2874,7 +2840,7 @@ ;; Comparison insns ;; ------------------------------------------------------------------- -(define_insn "*cmp" +(define_insn "cmp" [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r") (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))] @@ -2961,7 +2927,7 @@ (define_expand "cstorecc4" [(set (match_operand:SI 0 "register_operand") (match_operator 1 "aarch64_comparison_operator" - [(match_operand 2 "ccmp_cc_register") + [(match_operand 2 "cc_register") (match_operand 3 "const0_operand")]))] "" "{ @@ -3164,19 +3130,15 @@ (match_operand:ALLI 3 "register_operand" "")))] "" { + rtx ccreg; enum rtx_code code = GET_CODE (operands[1]); if (code == UNEQ || code == LTGT) FAIL; - if (!ccmp_cc_register (XEXP (operands[1], 0), - GET_MODE (XEXP (operands[1], 0)))) - { - rtx ccreg; - ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), - XEXP (operands[1], 1)); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); - } + ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); } ) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index f3b514b..e96dc00 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -43,23 +43,6 @@ (ior (match_operand 0 "register_operand") (match_operand 0 "aarch64_ccmp_immediate"))) -(define_special_predicate "ccmp_cc_register" - (and (match_code "reg") - (and (match_test "REGNO (op) == CC_REGNUM") - (ior (match_test "mode == GET_MODE (op)") - (match_test "mode == VOIDmode - && (GET_MODE (op) == CC_DNEmode - || GET_MODE (op) == CC_DEQmode - || GET_MODE (op) == CC_DLEmode - || GET_MODE (op) == CC_DLTmode - || GET_MODE (op) == CC_DGEmode - || GET_MODE (op) == CC_DGTmode - || GET_MODE (op) == CC_DLEUmode - || GET_MODE (op) == CC_DLTUmode - || GET_MODE (op) == CC_DGEUmode - || GET_MODE (op) == CC_DGTUmode)")))) -) - (define_predicate "aarch64_simd_register" (and (match_code "reg") (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS") diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7a11552..aae09bf 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11370,27 +11370,27 @@ modes and they have different conditional execution capability, such as ARM. @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (rtx *@var{prep_seq}, rtx *@var{gen_seq}, int @var{code}, tree @var{op0}, tree @var{op1}) This function prepares to emit a comparison insn for the first compare in a - sequence of conditional comparisions. It returns a appropriate @code{CC} - for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to - prepare the compare are saved in @var{prep_seq} and the compare insns are - saved in @var{gen_seq}. They will be emitted when all the compares in the - the conditional comparision are generated without error. @var{code} is - the @code{rtx_code} of the compare for @var{op0} and @var{op1}. + sequence of conditional comparisions. It returns an appropriate comparison + with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. + The insns to prepare the compare are saved in @var{prep_seq} and the compare + insns are saved in @var{gen_seq}. They will be emitted when all the + compares in the the conditional comparision are generated without error. + @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}. @end deftypefn @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx *@var{prep_seq}, rtx *@var{gen_seq}, rtx @var{prev}, int @var{cmp_code}, tree @var{op0}, tree @var{op1}, int @var{bit_code}) -This function prepare to emit a conditional comparison within a sequence of - conditional comparisons. It returns a appropriate @code{CC} for passing to - @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the - compare are saved in @var{prep_seq} and the compare insns are saved in - @var{gen_seq}. They will be emitted when all the compares in the conditional - comparision are generated without error. The @var{prev} expression is the - result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It - may return @code{NULL} if the combination of @var{prev} and this comparison is - not supported, otherwise the result must be appropriate for passing to - @code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the - @code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code} - is @code{AND} or @code{IOR}, which is the op on the two compares. +This function prepares to emit a conditional comparison within a sequence + of conditional comparisons. It returns an appropriate comparison with + @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. + The insns to prepare the compare are saved in @var{prep_seq} and the compare + insns are saved in @var{gen_seq}. They will be emitted when all the + compares in the conditional comparision are generated without error. The + @var{prev} expression is the result of a prior call to @code{gen_ccmp_first} + or @code{gen_ccmp_next}. It may return @code{NULL} if the combination of + @var{prev} and this comparison is not supported, otherwise the result must + be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. + @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}. + @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the compares. @end deftypefn @deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, struct loop *@var{loop}) diff --git a/gcc/target.def b/gcc/target.def index 946d2e5..d60319e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2611,29 +2611,29 @@ modes and they have different conditional execution capability, such as ARM.", DEFHOOK (gen_ccmp_first, "This function prepares to emit a comparison insn for the first compare in a\n\ - sequence of conditional comparisions. It returns a appropriate @code{CC}\n\ - for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to\n\ - prepare the compare are saved in @var{prep_seq} and the compare insns are\n\ - saved in @var{gen_seq}. They will be emitted when all the compares in the\n\ - the conditional comparision are generated without error. @var{code} is\n\ - the @code{rtx_code} of the compare for @var{op0} and @var{op1}.", + sequence of conditional comparisions. It returns an appropriate comparison\n\ + with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\ + The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\ + insns are saved in @var{gen_seq}. They will be emitted when all the\n\ + compares in the the conditional comparision are generated without error.\n\ + @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.", rtx, (rtx *prep_seq, rtx *gen_seq, int code, tree op0, tree op1), NULL) DEFHOOK (gen_ccmp_next, - "This function prepare to emit a conditional comparison within a sequence of\n\ - conditional comparisons. It returns a appropriate @code{CC} for passing to\n\ - @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the\n\ - compare are saved in @var{prep_seq} and the compare insns are saved in\n\ - @var{gen_seq}. They will be emitted when all the compares in the conditional\n\ - comparision are generated without error. The @var{prev} expression is the\n\ - result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It\n\ - may return @code{NULL} if the combination of @var{prev} and this comparison is\n\ - not supported, otherwise the result must be appropriate for passing to\n\ - @code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the\n\ - @code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code}\n\ - is @code{AND} or @code{IOR}, which is the op on the two compares.", + "This function prepares to emit a conditional comparison within a sequence\n\ + of conditional comparisons. It returns an appropriate comparison with\n\ + @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\ + The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\ + insns are saved in @var{gen_seq}. They will be emitted when all the\n\ + compares in the conditional comparision are generated without error. The\n\ + @var{prev} expression is the result of a prior call to @code{gen_ccmp_first}\n\ + or @code{gen_ccmp_next}. It may return @code{NULL} if the combination of\n\ + @var{prev} and this comparison is not supported, otherwise the result must\n\ + be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\ + @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.\n\ + @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the compares.", rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code), NULL) -- 2.7.4