From patchwork Wed Nov 25 19:14:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wilco Dijkstra X-Patchwork-Id: 549465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 0E10E140316 for ; Sat, 28 Nov 2015 00:49:41 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ksc4trz1; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:references:in-reply-to:subject:date:message-id :mime-version:content-type; q=dns; s=default; b=xezNYZ0ovcYi/LlX UZt9/W/CV87ZGICrFCCx8qYysS97nwwlzm3vaxr0Xk62FzUoJY0B+Er02dQ/KXyK qlzO7wJe3NIOjSFyE9s3hz3LzwKMwulC3BwfomqFQZmpfVfOVKtkLg1xhdMKnPCh Wb4Fb323xtQ8OECyFNNkKpLE75k= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:references:in-reply-to:subject:date:message-id :mime-version:content-type; s=default; bh=y9Ocmrrnp267mI1ntWyYIU ZZ2O0=; b=ksc4trz18jW3PtUZ+xFJ+XZR6FzEihzV7s9EeCQKWKJ3LHxWacytHa IbebLJOtfEk76DsMu2AizY4h6BAqpQwVnnf+U5xKh2CBG9OwcrWg7Ryl81Lw5e+P 5oJsE3HJ6VhryfRHlEen6cb0si+DZhTobLK8HdOgcMyN0aRwNOEu0= Received: (qmail 56661 invoked by alias); 27 Nov 2015 13:49:33 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 56647 invoked by uid 89); 27 Nov 2015 13:49:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL, BAYES_50, DATE_IN_PAST_24_48, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 27 Nov 2015 13:49:29 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-34-rYvMHgVBR_CTatc6eQvgeA-1; Fri, 27 Nov 2015 13:49:23 +0000 Received: from E107166VM ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 27 Nov 2015 13:49:22 +0000 From: "Wilco Dijkstra" To: "James Greenhalgh" Cc: References: <000501d12166$bff6ac10$3fe40430$@arm.com> <20151124151856.GB10173@arm.com> In-Reply-To: Subject: RE: [PATCH 1/4 v2][AArch64] Generalize CCMP support Date: Wed, 25 Nov 2015 19:14:26 -0000 Message-ID: <000c01d127b5$80186020$80492060$@arm.com> MIME-Version: 1.0 X-MC-Unique: rYvMHgVBR_CTatc6eQvgeA-1 > James Greenhalgh wrote: > > Could you please repost this with the word-wrapping issues fixed. > > I can't apply it to my tree for review or to commit it on your behalf in the current form. So it looks like Outlook no longer supports sending emails without wrapping and the maximum is only 132 characters... Now attached. Wilco --- 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 ++--- 7 files changed, 128 insertions(+), 365 deletions(-) diff --git a/gcc/ccmp.c b/gcc/ccmp.c index 20348d9..58ac126 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -65,6 +65,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. @@ -130,10 +134,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) @@ -226,7 +232,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 @@ -249,9 +255,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) @@ -262,8 +269,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 3bf3b2d..0c529e9 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 3bb4e64..c8bee3b 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -3907,7 +3907,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: @@ -3930,56 +3929,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) { @@ -4041,12 +3990,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; } @@ -4087,69 +4030,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 (); - } -} - - void aarch64_print_operand (FILE *f, rtx x, char code) { @@ -4248,36 +4149,17 @@ aarch64_print_operand (FILE *f, rtx x, char 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; } @@ -4286,10 +4168,12 @@ aarch64_print_operand (FILE *f, rtx x, char 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; @@ -4533,37 +4417,20 @@ aarch64_print_operand (FILE *f, rtx x, char 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; @@ -12500,60 +12367,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); @@ -12580,8 +12403,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 (); @@ -12590,16 +12413,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; @@ -12607,22 +12425,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); @@ -12637,14 +12453,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: @@ -12663,15 +12477,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)) @@ -12683,7 +12504,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 db1a19c..fab65c6 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -261,18 +261,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 @@ -280,39 +279,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 @@ -2816,7 +2782,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")))] @@ -2903,7 +2869,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")]))] "" "{ @@ -3072,19 +3038,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 046f852..f89fb61 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 3b1e2dc..3b7cec3 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11333,27 +11333,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 two 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 773b6ef..64892e0 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2605,29 +2605,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 two compares.", rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code), NULL)