From patchwork Mon Dec 19 01:08:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christoph_M=C3=BCllner?= X-Patchwork-Id: 34362 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp2134566wrn; Sun, 18 Dec 2022 17:17:18 -0800 (PST) X-Google-Smtp-Source: AA0mqf7emFjSxlhhidPw1EvOryrzldIl6FfDbsWUUdxFlZE0BpovBJKg5qTTDetTIal18Wdi/hxM X-Received: by 2002:a17:906:3a8c:b0:7ad:84c7:503a with SMTP id y12-20020a1709063a8c00b007ad84c7503amr36114307ejd.72.1671412638463; Sun, 18 Dec 2022 17:17:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671412638; cv=none; d=google.com; s=arc-20160816; b=Znm82yyinyEHsRDCo9bqo1twYIqmSW0hufrL9ob9n9C20IyyzRgKncPcrDLdPsKZlC w+kIQHL2UQZmfbYOdEfbUHNDmiMO7ZVAIwsIlXDMVO1FRrfaqLXgzytx1PsUbAuMqHn2 vPMOlzjyWB6nrchdre68LONSnqIaDBh+tH+0qH7kn4+De5tehs2a/Y3pXbXhEYEkKf+G hwWjwazne4ElX1HPQms5JfZQvEJfId29pfj0OgIA9MLMU5Ii5NhzL9CCoabzYkzevM46 nm9OE1jYCYXAUXXsxH2iB/5vF7JJjEYtA9DGBhnihybssYdj+Je6GjjN7fgHZkOK/eNQ QR1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dmarc-filter:delivered-to; bh=KrkWeq7hYcwH/4G9gpbYf5rdN1twBXw434+JXxGLCD8=; b=pyemEYQDkKz69ntFdbYwWzryPql0JripNsjbZQa/CnjoVvzQpBuYlJKxSG2gq0+jDa KU781cftXdhjYgN+/0KTCM06QCJg+iEvFQWXGOwHLYJtNcioZ75AqY7WL237E1sZffI6 OUvVGrHLnL040k1KXgoYe6bhSLlKKU+yB3q0fpcgn5UZiFu78980KZPK7RopBMCjRFqz rc/hB6UnYuAnTEGDGqFjsWeGLRe7o2XqMEIEulSa8ZEn4k3r3y2Rdbl/YQOWUXuWznBb om+tLHSSkpJGKqKF0Q+S5Punb3YNV9+MJCS22wjpUuGPZFC6fW3u80angud+/OZE/PiO iPeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@vrull.eu header.s=google header.b=F5O+OPvI; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id hr25-20020a1709073f9900b0082ad5e78975si414733ejc.803.2022.12.18.17.17.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:17:18 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@vrull.eu header.s=google header.b=F5O+OPvI; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2F12A3A70B14 for ; Mon, 19 Dec 2022 01:12:44 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by sourceware.org (Postfix) with ESMTPS id 1389938FCF78 for ; Mon, 19 Dec 2022 01:08:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1389938FCF78 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x52e.google.com with SMTP id z92so10927335ede.1 for ; Sun, 18 Dec 2022 17:08:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KrkWeq7hYcwH/4G9gpbYf5rdN1twBXw434+JXxGLCD8=; b=F5O+OPvI3eEymMuVzBkQ7kpO2S5gMlRD1we8IdfSs3q5li0MTfDqIAACbBl11a0kW/ x4lr11b0S/rQUNf5j4KjlTQhnithdas7aci7T23YhNkHgrl1ya8F8wtnP+VIWjN4AQHM Jng8phw2cqZjQ0ift5jyhpnczAgEGVypxClcxLI5rPP4ipAnUTep/kXbnf73kcYdvo8U 3IkOD+ZlVycHA/q0ODm7tOIWo+hnN/06ONGyz/Ljs1R6KA398UwN8IUHR+gGTwYhslST J8F4IItEn3Mf0ycaie58MbZbO8854DhdK1aDN/ac4DF3w3O9AnEAZUAxRJ55A5xh+Gta 3fBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KrkWeq7hYcwH/4G9gpbYf5rdN1twBXw434+JXxGLCD8=; b=vejGEvoRgDBfyY5bx8BWeBumQeTLfh6tp0uXhuLMjsMgJh8nYLNq5INzc7Nj9YYoHd JF74QXe1s16kqKDaCNEs1+jyxnsdrV9EsSh+oV6dYeN6EBEUUXYsdiAE1fr/omTzk1Wf Zuu5jJ8mWP9OHd3/m3kI1RFt1vgt+GIxvHDmnsBiVF0401K617/Fbc42T0PzNFK/cvb7 NuatMze3TZK5cw0ht92+bBjYxq/Cz7XQ77yTPQjCk8xqjMkgB9iqRBsjrW6mrgPqKQ7n IN6rKr3aSeAgWnkN84rp8/XppIod3kJZgaXaYkvPV7HPkxjEnKYW7QHfMbt1bcLFz4Vu +hxQ== X-Gm-Message-State: ANoB5pnrIN5QDU5RPPGurDb2Zh18we8LqBEMcuTd/FItBR2KbT3G/f0z cF4O8gZt8o3mqFHyncWUjfjlv89XUVy2UTcZ X-Received: by 2002:a05:6402:1f8e:b0:45c:835c:eab6 with SMTP id c14-20020a0564021f8e00b0045c835ceab6mr37325723edc.36.1671412133050; Sun, 18 Dec 2022 17:08:53 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id eg53-20020a05640228b500b0044dbecdcd29sm3744648edb.12.2022.12.18.17.08.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:52 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Jeff Law , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v2 08/11] riscv: thead: Add support for XTheadCondMov ISA extensions Date: Mon, 19 Dec 2022 02:08:35 +0100 Message-Id: <20221219010838.3878675-9-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221219010838.3878675-1-christoph.muellner@vrull.eu> References: <20221219010838.3878675-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_MANYTO, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752603178861279320?= X-GMAIL-MSGID: =?utf-8?q?1752603178861279320?= From: Christoph Müllner This patch adds support for XTheadCondMov ISA extension. The extension brings a one-sided conditional move (no else-assignment). Given that GCC has a great if-conversion pass, we don't need to do much, besides properly expanding movcc accordingly and adjust the cost model. gcc/ChangeLog: * config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator. * config/riscv/riscv-protos.h (riscv_expand_conditional_move): Add prototype. * config/riscv/riscv.cc (riscv_rtx_costs): Add costs for XTheadCondMov. (riscv_expand_conditional_move): New function. (riscv_expand_conditional_move_onesided): New function. * config/riscv/riscv.md: Add support for XTheadCondMov. * config/riscv/thead.md (*th_cond_mov): Add support for XTheadCondMov. (*th_cond_gpr_mov): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test. * gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test. * gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test. * gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test. * gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test. * gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test. * gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test. * gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test. Changes for v2: - Properly gate expansion constraints to avoid failing INSN lookup - Restrict subreg comparisons Signed-off-by: Christoph Müllner --- gcc/config/riscv/iterators.md | 4 + gcc/config/riscv/riscv-protos.h | 2 +- gcc/config/riscv/riscv.cc | 100 +++++++++++++++--- gcc/config/riscv/riscv.md | 17 ++- gcc/config/riscv/thead.md | 37 +++++++ .../riscv/xtheadcondmov-mveqz-imm-eqz.c | 38 +++++++ .../riscv/xtheadcondmov-mveqz-imm-not.c | 38 +++++++ .../riscv/xtheadcondmov-mveqz-reg-eqz.c | 38 +++++++ .../riscv/xtheadcondmov-mveqz-reg-not.c | 38 +++++++ .../riscv/xtheadcondmov-mvnez-imm-cond.c | 38 +++++++ .../riscv/xtheadcondmov-mvnez-imm-nez.c | 38 +++++++ .../riscv/xtheadcondmov-mvnez-reg-cond.c | 38 +++++++ .../riscv/xtheadcondmov-mvnez-reg-nez.c | 38 +++++++ 13 files changed, 440 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index efdd3ccc9a7..1c5f3dd5681 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -26,6 +26,10 @@ ;; from the same template. (define_mode_iterator GPR [SI (DI "TARGET_64BIT")]) +;; A copy of GPR that can be used when a pattern has two independent +;; modes. +(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")]) + ;; This mode iterator allows :P to be used for patterns that operate on ;; pointer-sized quantities. Exactly one of the two alternatives will match. (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index e17e003f8e2..7975bc4f438 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -58,8 +58,8 @@ extern const char *riscv_output_return (); extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx); -extern void riscv_expand_conditional_move (rtx, rtx, rtx, rtx_code, rtx, rtx); #endif +extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx); extern rtx riscv_legitimize_call_address (rtx); extern void riscv_set_return_address (rtx, rtx); extern bool riscv_expand_block_move (rtx, rtx, rtx); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index b57c1f1d727..21ec7a6225b 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2300,8 +2300,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case IF_THEN_ELSE: - if (TARGET_SFB_ALU - && register_operand (XEXP (x, 1), mode) + if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV) + && reg_or_0_operand (XEXP (x, 1), mode) && sfb_alu_operand (XEXP (x, 2), mode) && comparison_operator (XEXP (x, 0), VOIDmode)) { @@ -3098,13 +3098,30 @@ riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1) } } -/* Convert a comparison into something that can be used in a branch. On - entry, *OP0 and *OP1 are the values being compared and *CODE is the code - used to compare them. Update them to describe the final comparison. */ +/* Convert a comparison into something that can be used in a branch or + conditional move. On entry, *OP0 and *OP1 are the values being + compared and *CODE is the code used to compare them. + + Update *CODE, *OP0 and *OP1 so that they describe the final comparison. + If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are + emitted. */ static void -riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1) +riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1, + bool need_eq_ne_p = false) { + if (need_eq_ne_p) + { + rtx cmp_op0 = *op0; + rtx cmp_op1 = *op1; + if (*code == EQ || *code == NE) + { + *op0 = riscv_zero_if_equal (cmp_op0, cmp_op1); + *op1 = const0_rtx; + return; + } + } + if (splittable_const_int_operand (*op1, VOIDmode)) { HOST_WIDE_INT rhs = INTVAL (*op1); @@ -3290,16 +3307,71 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1) emit_jump_insn (gen_condjump (condition, label)); } -/* If (CODE OP0 OP1) holds, move CONS to DEST; else move ALT to DEST. */ +/* Helper to emit two one-sided conditional moves for the movecc. */ -void -riscv_expand_conditional_move (rtx dest, rtx cons, rtx alt, rtx_code code, - rtx op0, rtx op1) +static void +riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt, + rtx_code code, rtx op0, rtx op1) { - riscv_emit_int_compare (&code, &op0, &op1); - rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, - cons, alt))); + machine_mode mode = GET_MODE (dest); + + gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); + gcc_assert (reg_or_0_operand (cons, mode)); + gcc_assert (reg_or_0_operand (alt, mode)); + + riscv_emit_int_compare (&code, &op0, &op1, true); + rtx cond = gen_rtx_fmt_ee (code, mode, op0, op1); + + rtx tmp1 = gen_reg_rtx (mode); + rtx tmp2 = gen_reg_rtx (mode); + + emit_insn (gen_rtx_SET (tmp1, gen_rtx_IF_THEN_ELSE (mode, cond, + cons, const0_rtx))); + + /* We need to expand a sequence for both blocks and we do that such, + that the second conditional move will use the inverted condition. + We use temporaries that are or'd to the dest register. */ + cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, mode, op0, op1); + emit_insn (gen_rtx_SET (tmp2, gen_rtx_IF_THEN_ELSE (mode, cond, + alt, const0_rtx))); + + emit_insn (gen_rtx_SET (dest, gen_rtx_IOR (mode, tmp1, tmp2))); + } + +/* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST. + Return 0 if expansion failed. */ + +bool +riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) +{ + machine_mode mode = GET_MODE (dest); + rtx_code code = GET_CODE (op); + rtx op0 = XEXP (op, 0); + rtx op1 = XEXP (op, 1); + + if (TARGET_XTHEADCONDMOV + && GET_MODE_CLASS (mode) == MODE_INT + && reg_or_0_operand (cons, mode) + && reg_or_0_operand (alt, mode) + && GET_MODE (op) == mode + && GET_MODE (op0) == mode + && GET_MODE (op1) == mode + && (code == EQ || code == NE)) + { + riscv_expand_conditional_move_onesided (dest, cons, alt, code, op0, op1); + return true; + } + else if (TARGET_SFB_ALU + && mode == word_mode) + { + riscv_emit_int_compare (&code, &op0, &op1); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), + cond, cons, alt))); + return true; + } + + return false; } /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 8bdf3c128f3..34327bfb01f 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -242,6 +242,7 @@ (define_attr "enabled" "no,yes" ;; bitmanip bit manipulation instructions ;; rotate rotation instructions ;; atomic atomic instructions +;; condmove conditional moves ;; Classification of RVV instructions which will be added to each RVV .md pattern and used by scheduler. ;; rdvlenb vector byte length vlenb csrr read ;; rdvl vector length vl csrr read @@ -333,7 +334,7 @@ (define_attr "type" "unknown,branch,jump,call,load,fpload,store,fpstore, mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate, - atomic,rdvlenb,rdvl,vsetvl,vlde,vste,vldm,vstm,vlds,vsts, + atomic,condmove,rdvlenb,rdvl,vsetvl,vlde,vste,vldm,vstm,vlds,vsts, vldux,vldox,vstux,vstox,vldff,vldr,vstr, vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp, vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov, @@ -2288,17 +2289,15 @@ (define_insn "*branch" (define_expand "movcc" [(set (match_operand:GPR 0 "register_operand") (if_then_else:GPR (match_operand 1 "comparison_operator") - (match_operand:GPR 2 "register_operand") + (match_operand:GPR 2 "reg_or_0_operand") (match_operand:GPR 3 "sfb_alu_operand")))] - "TARGET_SFB_ALU" + "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV" { - rtx cmp = operands[1]; - /* We only handle word mode integer compares for now. */ - if (GET_MODE (XEXP (cmp, 0)) != word_mode) + if (riscv_expand_conditional_move (operands[0], operands[1], + operands[2], operands[3])) + DONE; + else FAIL; - riscv_expand_conditional_move (operands[0], operands[2], operands[3], - GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1)); - DONE; }) (define_insn "*movcc" diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index c3cbb49eb58..9f03d1d43b4 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -106,3 +106,40 @@ (define_insn "*th_tst" "TARGET_XTHEADBS" "th.tst\t%0,%1,%2" [(set_attr "type" "bitmanip")]) + +;; XTheadCondMov + +(define_insn "*th_cond_mov" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (if_then_else:GPR + (match_operator 4 "equality_operator" + [(match_operand:GPR2 1 "register_operand" "r,r") + (const_int 0)]) + (match_operand:GPR 2 "reg_or_0_operand" "rJ,0") + (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))] + "TARGET_XTHEADCONDMOV" +{ + if (which_alternative == 0) + return "th.mv%C4z\t%0,%z2,%1"; + + /* Invert the condition and take else-block. */ + rtx_code code = GET_CODE (operands[4]); + code = (code == EQ) ? NE : EQ; + operands[4] = gen_rtx_fmt_ee (code, VOIDmode, const0_rtx, const0_rtx); + return "th.mv%C4z\t%0,%z3,%1"; +} + [(set_attr "type" "condmove") + (set_attr "mode" "")]) + +(define_insn "*th_cond_gpr_mov" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (if_then_else:GPR + (match_operand:GPR2 1 "register_operand" "r,r") + (match_operand:GPR 2 "reg_or_0_operand" "rJ,0") + (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))] + "TARGET_XTHEADCONDMOV" + "@ + th.mvnez\t%0,%z2,%1 + th.mveqz\t%0,%z3,%1" + [(set_attr "type" "condmove") + (set_attr "mode" "")]) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c new file mode 100644 index 00000000000..913ae43f21b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond) +{ + if (cond == 0) + return 1025; + return x; +} + +long +not_long_int (long x, int cond) +{ + if (cond == 0) + return 1025l; + return x; +} + +int +not_int_long (int x, long cond) +{ + if (cond == 0) + return 1025; + return x; +} + +long +not_long_long (long x, int cond) +{ + if (cond == 0) + return 1025l; + return x; +} + +/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c new file mode 100644 index 00000000000..1bc8b838233 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond) +{ + if (!cond) + return 1025; + return x; +} + +long +not_long_int (long x, int cond) +{ + if (!cond) + return 1025l; + return x; +} + +int +not_int_long (int x, long cond) +{ + if (!cond) + return 1025; + return x; +} + +long +not_long_long (long x, int cond) +{ + if (!cond) + return 1025l; + return x; +} + +/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c new file mode 100644 index 00000000000..8ef5869a89b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond, int v) +{ + if (cond == 0) + return v; + return x; +} + +long +not_long_int (long x, int cond, long v) +{ + if (cond == 0) + return v; + return x; +} + +int +not_int_long (int x, long cond, int v) +{ + if (cond == 0) + return v; + return x; +} + +long +not_long_long (long x, int cond, long v) +{ + if (cond == 0) + return v; + return x; +} + +/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c new file mode 100644 index 00000000000..f9568bee27f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond, int v) +{ + if (!cond) + return v; + return x; +} + +long +not_long_int (long x, int cond, long v) +{ + if (!cond) + return v; + return x; +} + +int +not_int_long (int x, long cond, int v) +{ + if (!cond) + return v; + return x; +} + +long +not_long_long (long x, int cond, long v) +{ + if (!cond) + return v; + return x; +} + +/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c new file mode 100644 index 00000000000..8feddbeb79d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond) +{ + if (cond) + return 1025; + return x; +} + +long +not_long_int (long x, int cond) +{ + if (cond) + return 1025l; + return x; +} + +int +not_int_long (int x, long cond) +{ + if (cond) + return 1025; + return x; +} + +long +not_long_long (long x, int cond) +{ + if (cond) + return 1025l; + return x; +} + +/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c new file mode 100644 index 00000000000..7c08e20c25d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond) +{ + if (cond != 0) + return 1025; + return x; +} + +long +not_long_int (long x, int cond) +{ + if (cond != 0) + return 1025l; + return x; +} + +int +not_int_long (int x, long cond) +{ + if (cond != 0) + return 1025; + return x; +} + +long +not_long_long (long x, int cond) +{ + if (cond != 0) + return 1025l; + return x; +} + +/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c new file mode 100644 index 00000000000..c1619509af9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond, int v) +{ + if (cond) + return v; + return x; +} + +long +not_long_int (long x, int cond, long v) +{ + if (cond) + return v; + return x; +} + +int +not_int_long (int x, long cond, int v) +{ + if (cond) + return v; + return x; +} + +long +not_long_long (long x, int cond, long v) +{ + if (cond) + return v; + return x; +} + +/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c new file mode 100644 index 00000000000..ff95a57927a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +not_int_int (int x, int cond, int v) +{ + if (cond != 0) + return v; + return x; +} + +long +not_long_int (long x, int cond, long v) +{ + if (cond != 0) + return v; + return x; +} + +int +not_int_long (int x, long cond, int v) +{ + if (cond != 0) + return v; + return x; +} + +long +not_long_long (long x, int cond, long v) +{ + if (cond != 0) + return v; + return x; +} + +/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */