From patchwork Thu Jan 21 10:24:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Levy Hsu X-Patchwork-Id: 1429721 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DLz7Q49f2z9sW1 for ; Thu, 21 Jan 2021 21:25:51 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 77E0B3857821; Thu, 21 Jan 2021 10:25:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from out20-50.mail.aliyun.com (out20-50.mail.aliyun.com [115.124.20.50]) by sourceware.org (Postfix) with ESMTPS id 10AA53857821 for ; Thu, 21 Jan 2021 10:25:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 10AA53857821 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=levyhsu.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=admin@levyhsu.com X-Alimail-AntiSpam: AC=CONTINUE; BC=0.06447794|-1; CH=green; DM=|CONTINUE|false|; DS=CONTINUE|ham_alarm|0.602125-4.06491e-05-0.397835; FP=0|0|0|0|0|-1|-1|-1; HT=ay29a033018047194; MF=admin@levyhsu.com; NM=1; PH=DS; RN=4; RT=4; SR=0; TI=SMTPD_---.JNqBczW_1611224736; Received: from ubuntu.localdomain(mailfrom:admin@levyhsu.com fp:SMTPD_---.JNqBczW_1611224736) by smtp.aliyun-inc.com(10.147.41.143); Thu, 21 Jan 2021 18:25:37 +0800 From: Levy To: gcc-patches@gcc.gnu.org, kito.cheng@gmail.com, jimw@sifive.com Subject: [PATCH] RISC-V: Add implementation for builtin overflow Date: Thu, 21 Jan 2021 18:24:36 +0800 Message-Id: <20210121102436.3674778-1-admin@levyhsu.com> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3039.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: Levy Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Added implementation for builtin overflow detection, new patterns are listed below. signed addition: add t0, t1, t2 slti t3, t2, 0 slt t4, t0, t1 bne t3, t4, overflow unsigned addition: add t0, t1, t2 bltu t0, t1, overflow signed subtraction: sub t0, t1, t2 slti t3, t2, 0 slt t4, t1, t0 bne t3, t4, overflow signed subtraction: add t0, t1, t2 bltu t1, t0, overflow signed multiplication: mulh t4, t1, t2 mul t0, t1, t2 srai t5, t0, 31/63 (RV32/64) bne t4, t5, overflow unsigned multiplication: mulhu t4, t1, t2 mul t0, t1, t2 bne t4, 0, overflow gcc/Changelog: * config/riscv/riscv.md: Add expand pattern for addv4, subv4 and mulv4 * config/riscv/riscv.h: Defined riscv_min_arithmetic_precision for hook TARGET_MIN_ARITHMETIC_PRECISION * config/riscv/riscv.c: Set the riscv_min_arithmetic_precision to 32, allows SImode op calls for addw/subw under RV64. --- gcc/config/riscv/riscv.c | 8 +++ gcc/config/riscv/riscv.h | 5 ++ gcc/config/riscv/riscv.md | 104 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index d489717b2a5..cf94f5c9658 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -351,6 +351,14 @@ static const struct riscv_tune_info riscv_tune_info_table[] = { { "size", generic, &optimize_size_tune_info }, }; +/* Implement TARGET_MIN_ARITHMETIC_PRECISION. */ + +static unsigned int +riscv_min_arithmetic_precision (void) +{ + return 32; +} + /* Return the riscv_tune_info entry for the given name string. */ static const struct riscv_tune_info * diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 172c7ca7c98..62cebd08cff 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -115,6 +115,11 @@ extern const char *riscv_default_mtune (int argc, const char **argv); #define MAX_BITS_PER_WORD 64 +/* Allows SImode op in builtin overflow pattern, see internal-fn.c. */ + +#undef TARGET_MIN_ARITHMETIC_PRECISION +#define TARGET_MIN_ARITHMETIC_PRECISION riscv_min_arithmetic_precision + /* Width of a word, in units (bytes). */ #define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4) #ifndef IN_LIBGCC2 diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 36012ad1f77..a95654d77e9 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -462,6 +462,41 @@ [(set_attr "type" "arith") (set_attr "mode" "DI")]) +(define_expand "addv4" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (plus:GPR (match_operand:GPR 1 "register_operand" " r,r") + (match_operand:GPR 2 "arith_operand" " r,I"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + rtx t3 = gen_reg_rtx (mode); + rtx t4 = gen_reg_rtx (mode); + + emit_insn (gen_add3_insn (operands[0], operands[1], operands[2])); + + rtx cmp1 = gen_rtx_LT (mode, operands[2], const0_rtx); + emit_insn (gen_cstore4 (t3, cmp1, operands[2], const0_rtx)); + + rtx cmp2 = gen_rtx_LT (mode, operands[0], operands[1]); + emit_insn (gen_cstore4 (t4, cmp2, operands[0], operands[1])); + + riscv_expand_conditional_branch (operands[3], NE, t3, t4); + DONE; +}) + +(define_expand "uaddv4" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (plus:GPR (match_operand:GPR 1 "register_operand" " r,r") + (match_operand:GPR 2 "arith_operand" " r,I"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + emit_insn (gen_add3_insn (operands[0], operands[1], operands[2])); + riscv_expand_conditional_branch (operands[3], LTU, operands[0], operands[1]); + + DONE; +}) + (define_insn "*addsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r,r") (sign_extend:DI @@ -518,6 +553,41 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_expand "subv4" + [(set (match_operand:GPR 0 "register_operand" "= r") + (minus:GPR (match_operand:GPR 1 "reg_or_0_operand" " rJ") + (match_operand:GPR 2 "register_operand" " r"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + rtx t3 = gen_reg_rtx (mode); + rtx t4 = gen_reg_rtx (mode); + + emit_insn (gen_sub3_insn (operands[0], operands[1], operands[2])); + + rtx cmp1 = gen_rtx_LT (mode, operands[2], const0_rtx); + emit_insn (gen_cstore4 (t3, cmp1, operands[2], const0_rtx)); + + rtx cmp2 = gen_rtx_LT (mode, operands[1], operands[0]); + emit_insn (gen_cstore4 (t4, cmp2, operands[1], operands[0])); + + riscv_expand_conditional_branch (operands[3], NE, t3, t4); + DONE; +}) + +(define_expand "usubv4" + [(set (match_operand:GPR 0 "register_operand" "= r") + (minus:GPR (match_operand:GPR 1 "reg_or_0_operand" " rJ") + (match_operand:GPR 2 "register_operand" " r"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + emit_insn (gen_sub3_insn (operands[0], operands[1], operands[2])); + riscv_expand_conditional_branch (operands[3], LTU, operands[1], operands[0]); + + DONE; +}) + (define_insn "*subsi3_extended" [(set (match_operand:DI 0 "register_operand" "= r") (sign_extend:DI @@ -609,6 +679,40 @@ [(set_attr "type" "imul") (set_attr "mode" "DI")]) +(define_expand "umulv4" + [(set (match_operand:X 0 "register_operand" "=r") + (mult:X (match_operand:X 1 "register_operand" " r") + (match_operand:X 2 "register_operand" " r"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + rtx hp = gen_reg_rtx (mode); + + emit_insn (gen_umul3_highpart (hp, operands[1], operands[2])); + emit_insn (gen_mul3 (operands[0], operands[1], operands[2])); + + riscv_expand_conditional_branch (operands[3], NE, hp, const0_rtx); + DONE; +}) + +(define_expand "mulv4" + [(set (match_operand:X 0 "register_operand" "=r") + (mult:X (match_operand:X 1 "register_operand" " r") + (match_operand:X 2 "register_operand" " r"))) + (label_ref (match_operand 3 "" ""))] + "" +{ + rtx hp = gen_reg_rtx (mode); + rtx lp = gen_reg_rtx (mode); + + emit_insn (gen_mul3_highpart (hp, operands[1], operands[2])); + emit_insn (gen_mul3 (operands[0], operands[1], operands[2])); + emit_insn (gen_ashr3 (lp, operands[0], GEN_INT (BITS_PER_WORD - 1))); + + riscv_expand_conditional_branch (operands[3], NE, hp, lp); + DONE; +}) + (define_insn "*mulsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI