From patchwork Mon Dec 19 01:08:28 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: 62113 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A41E339DDDD3 for ; Mon, 19 Dec 2022 01:09:12 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id 240F339578D5 for ; Mon, 19 Dec 2022 01:08:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 240F339578D5 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-x52a.google.com with SMTP id i9so10915813edj.4 for ; Sun, 18 Dec 2022 17:08:45 -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=156m9hq+H+Ml6/vC47x+jDR6zkiK0hnJt3iazsD8Ttk=; b=I33wY2ZGtP3hw55+x8X9HNTjKMCLWV3p67aTz/9yMrvSUduH4mWZZR50PfJPU6kLLb 1qoAc0L7STkxh8ZvD8bKV/TJG+whUKZjcrSeWTkaKNXKav1mfWmhOs1iNmCJrr7HckcS EgT7w911YxKEYB0Nfq96LtyvdXFggqnhkUavup36dniib2Qs0pDCHyFWK7+l2nXnZkYu nlk84brHs4KR3j1fbGPaAj+WfCAwmqNFoWX0BkTNip4evZ1HXW4Ey8KHPhe53J/W5ltS L/BuKN+n93Ia9CbD4nORcnOOYMtTA4SDiyVzwf5sy/w3kF+Ikgt6GyIEcSTdiwrW4c6F Iw4Q== 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=156m9hq+H+Ml6/vC47x+jDR6zkiK0hnJt3iazsD8Ttk=; b=xC6FS+GVzxzlFPqEgz+OpRT8+LyMAVDVVVIuUhJ9UWqy1I/6fwyqrwwLEybC2H7chm Btjhh5zxH3o1znqScAHjGQp9fddUXogayxus5WlFcUd3I73aK+3VPW5YoT5CmiztzA1r QowgCLH5I0U/kwq1TZnA7ngjgTLsvVdyFXxgVV7TpUV6zGW4ijCX/UDmzsn72XRNW2gv KvkEVs8VknFCDMRn1LeyGrCLjhD5Us9n7fmsLhz8qjcaWFVQKTkWo3BO8LWQpP+2m28z jxjWu6eKIOSCjZPhnLX9gwnXHZ1tp/lTx5u0+9KgcuGa8Qc5s8Vyoji7HPYc1irYW6oB R1UA== X-Gm-Message-State: ANoB5pn8bx0hnnsehDfCv3Crd+wNNPNv2tlrth5JFpxQGD4QaR/Mr4jF MPdT3iN/0e8Kcnex5wFmBWvGljPgfHrpl9vE X-Google-Smtp-Source: AA0mqf7JstxvFIp3v12rTm+G5gMeRkyKhRjTDWmcjoQZBv32dn0xx3SlQliZH7cL8BapPBknmQPFDw== X-Received: by 2002:aa7:d5ce:0:b0:46b:aedf:f32b with SMTP id d14-20020aa7d5ce000000b0046baedff32bmr52494522eds.4.1671412123449; Sun, 18 Dec 2022 17:08:43 -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.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:42 -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 01/11] riscv: attr: Synchronize comments with code Date: Mon, 19 Dec 2022 02:08:28 +0100 Message-Id: <20221219010838.3878675-2-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, 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner The comment above the enumeration of existing attributes got out of order and a few entries were forgotten. This patch synchronizes the comments according to the list. This commit does not include any functional change. gcc/ChangeLog: * config/riscv/riscv.md: Sync comments with code. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index df57e2b0b4a..a8bb331f25c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -220,7 +220,6 @@ (define_attr "enabled" "no,yes" ;; mfc transfer from coprocessor ;; const load constant ;; arith integer arithmetic instructions -;; auipc integer addition to PC ;; logical integer logical instructions ;; shift integer shift instructions ;; slt set less than instructions @@ -236,9 +235,13 @@ (define_attr "enabled" "no,yes" ;; fcvt floating point convert ;; fsqrt floating point square root ;; multi multiword sequence (or user asm statements) +;; auipc integer addition to PC +;; sfb_alu SFB ALU instruction ;; nop no operation ;; ghost an instruction that produces no real code ;; bitmanip bit manipulation instructions +;; rotate rotation instructions +;; atomic atomic instructions ;; 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 From patchwork Mon Dec 19 01:08:29 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: 62114 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B028A3A604C7 for ; Mon, 19 Dec 2022 01:10:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by sourceware.org (Postfix) with ESMTPS id 5ADAD39578D0 for ; Mon, 19 Dec 2022 01:08:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5ADAD39578D0 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-x52c.google.com with SMTP id i9so10915845edj.4 for ; Sun, 18 Dec 2022 17:08:46 -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=lh+zxEIWJBqquCtSwUtBl6+u5FWf/VWLRsOsKrXCteY=; b=SAgA5tOHfVyIqkWAMvGv9AdlZJCVsEX+bM+3d14b81iMjPKlJ7kckkTsU86yoA9kqt /y8jXuN6aS7L4Fpp0nKwXXfsYUpEd1qpjBW3On8FaC7G/OUqoNtrrt4xEqsYsCSjtxiF fVz9ZiT9g9+iAXYqf1syUEZeGlIwOC9XsnkQjNtlCohwsdWybv2Tl+QKTmbGD8WWLc+l fLD/rpiZlR6Z4Q+jJfdjVnxqhJmyHCrIAMTRne2z2eaanM/oFmLhbf/FsClf2KPS+4Xs d1QjkSAgHr/5it/MPFHgFodb9Hptj3fYbWKeQSNapv4de1lZrmgdGoX0oH4osuAZvOJA nW/A== 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=lh+zxEIWJBqquCtSwUtBl6+u5FWf/VWLRsOsKrXCteY=; b=dlrFSCyIwEHYqFIi8Jp2siJjxohLWLVJIJlbmAPtTHDUNKqT6eHmkT9WsfqugCl0BT HX/gO48dwr7MwV54eTTa3I5ZhizNmCPn2mMrB6UG+HZNTWWVM7S3Ozav76A9/Dy9puak mHuofImpDDHB455izXFbqndcqKJEvCg1yDp8kNiImA63ijN2WJSTBqocCx1YOKr+1oSw 92hF2386yu8njbzjTrbsMFk+kibG4dEY2MOA96dajcbjb4SHxhwAd9yiuBYkvXjXnGpy IrfZocKPtXyJ2vOWD1P3XYQ6u5TFNj1neL+ZoB8Y35obgEXjPppFPfhgBKlta0JqtqgR /Cng== X-Gm-Message-State: ANoB5pljSH4BIfp0HRKLwG6rNm+50KamZ1Iw0eE0OZhqf5HINqFKT09h gKyPQtVSZOdM7GUToAtaRHtYU9YrwaupcdGR X-Google-Smtp-Source: AA0mqf7Nhci954TejtNdhtrJ2ilWTKuOAN1pRthG+pOvzIMmUpFkuEuXIi5q1B/l0cVEmCDdYubGig== X-Received: by 2002:aa7:dc14:0:b0:46d:e3f8:4ed1 with SMTP id b20-20020aa7dc14000000b0046de3f84ed1mr42678794edu.35.1671412124722; Sun, 18 Dec 2022 17:08:44 -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.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:44 -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 02/11] riscv: Restructure callee-saved register save/restore code Date: Mon, 19 Dec 2022 02:08:29 +0100 Message-Id: <20221219010838.3878675-3-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, 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This patch restructures the loop over the GP registers which saves/restores then as part of the prologue/epilogue. No functional change is intended by this patch, but it offers the possibility to use load-pair/store-pair instructions. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_next_saved_reg): New function. (riscv_is_eh_return_data_register): New function. (riscv_for_each_saved_reg): Restructure loop. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.cc | 94 +++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 6dd2ab2d11e..a8d5e1dac7f 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4835,6 +4835,49 @@ riscv_save_restore_reg (machine_mode mode, int regno, fn (gen_rtx_REG (mode, regno), mem); } +/* Return the next register up from REGNO up to LIMIT for the callee + to save or restore. OFFSET will be adjusted accordingly. + If INC is set, then REGNO will be incremented first. */ + +static unsigned int +riscv_next_saved_reg (unsigned int regno, unsigned int limit, + HOST_WIDE_INT *offset, bool inc = true) +{ + if (inc) + regno++; + + while (regno <= limit) + { + if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) + { + *offset = *offset - UNITS_PER_WORD; + break; + } + + regno++; + } + return regno; +} + +/* Return TRUE if provided REGNO is eh return data register. */ + +static bool +riscv_is_eh_return_data_register (unsigned int regno) +{ + unsigned int i, regnum; + + if (!crtl->calls_eh_return) + return false; + + for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++) + if (regno == regnum) + { + return true; + } + + return false; +} + /* Call FN for each register that is saved by the current function. SP_OFFSET is the offset of the current stack pointer from the start of the frame. */ @@ -4844,36 +4887,31 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, bool epilogue, bool maybe_eh_return) { HOST_WIDE_INT offset; + unsigned int regno; + unsigned int start = GP_REG_FIRST; + unsigned int limit = GP_REG_LAST; /* Save the link register and s-registers. */ - offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant (); - for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) - if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) - { - bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno]; - - /* If this is a normal return in a function that calls the eh_return - builtin, then do not restore the eh return data registers as that - would clobber the return value. But we do still need to save them - in the prologue, and restore them for an exception return, so we - need special handling here. */ - if (epilogue && !maybe_eh_return && crtl->calls_eh_return) - { - unsigned int i, regnum; - - for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; - i++) - if (regno == regnum) - { - handle_reg = FALSE; - break; - } - } - - if (handle_reg) - riscv_save_restore_reg (word_mode, regno, offset, fn); - offset -= UNITS_PER_WORD; - } + offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant () + + UNITS_PER_WORD; + for (regno = riscv_next_saved_reg (start, limit, &offset, false); + regno <= limit; + regno = riscv_next_saved_reg (regno, limit, &offset)) + { + if (cfun->machine->reg_is_wrapped_separately[regno]) + continue; + + /* If this is a normal return in a function that calls the eh_return + builtin, then do not restore the eh return data registers as that + would clobber the return value. But we do still need to save them + in the prologue, and restore them for an exception return, so we + need special handling here. */ + if (epilogue && !maybe_eh_return + && riscv_is_eh_return_data_register (regno)) + continue; + + riscv_save_restore_reg (word_mode, regno, offset, fn); + } /* This loop must iterate over the same space as its companion in riscv_compute_frame_info. */ From patchwork Mon Dec 19 01:08:30 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: 62118 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B03033A626D0 for ; Mon, 19 Dec 2022 01:11:33 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id D87FD3946DE2 for ; Mon, 19 Dec 2022 01:08:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D87FD3946DE2 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-x532.google.com with SMTP id d20so10975382edn.0 for ; Sun, 18 Dec 2022 17:08:47 -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=fLqUVVB8zsXr0A3+oA/g2ZrUtLjIXJXDDNYbVq/0OnU=; b=K2a5tZl3jE73evg/pkqXVedUc768QGD+v/+jJ15KqIMsOQPsU8ZqgtBonGkJLIGHMc VETs7yZSNU3CbEO9tTYmYKGdMJ2YerZTw6uPLc6vS6t8EbstJlL22McqUrQVcHn33k5D SZzePf2fa/nj1MS1pj+97LU1wCY+kmTToBJoTZNQKmgFuL+foT9dLSzLUOJ72hfwaMFU zf7HC48eAn7t9lDhKAb+je9zeGdau1BKPBcvp1iHUJmQN2k4AroQV8QIdx5vUwu18URI Y25X3NTocyhLtOwHLyOtfe78PTXNEGEvcU/j3XaXwE3s5XpOwZd02aXd6P0L2JBFu01M /JQQ== 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=fLqUVVB8zsXr0A3+oA/g2ZrUtLjIXJXDDNYbVq/0OnU=; b=oJlM5nQaRnzjTPCaa+7oDtarN1t4ARUmZcnmAutT+I7WS1tKL0TopObgP0Pfwk6346 qg3oSafvWO7PwFMizK2rxuPtVBSUm8lzZfuFHYGTNSH49qbnYpKEAWItPa0jdhVDYWvm M5rsPx41j6JuglF60XEtjcjkSiGSzYIW068d9KL1s4WleKgKAdVtCfzx1/NAZctkD1pw aqQyRSbS74QVbPe0zVcMkAulAD23886BEi+j6blGOZCBS/vhUjZJNNOsfIm/4v1FoNkq Ky5aSjkxUPRRUXsDPW255dymRkM8yMehgsZRMvjYNehXX4y4166GRxaArqHt9z3YLfoh R7gQ== X-Gm-Message-State: AFqh2koCxl7nM4eWWe2BopNU6RkagRN/XD8fpnayi07TXfk0HmhmzjTV YMKBdOC4yO0n/Z/aFzLaYcTcnYaEDoS4mhXy X-Google-Smtp-Source: AMrXdXvwkYOCP1S+aErR1SUdrUg5DA7T3ciT0nIh8OO+4mxRnUxIob0leWpHKSaeE3q5vkUXk3v/og== X-Received: by 2002:a05:6402:1f05:b0:475:32d2:7992 with SMTP id b5-20020a0564021f0500b0047532d27992mr10029352edb.12.1671412126081; Sun, 18 Dec 2022 17:08:46 -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.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:45 -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 03/11] riscv: Add basic XThead* vendor extension support Date: Mon, 19 Dec 2022 02:08:30 +0100 Message-Id: <20221219010838.3878675-4-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This patch add basic support for the following XThead* ISA extensions: * XTheadBa * XTheadBb * XTheadBs * XTheadCmo * XTheadCondMov * XTheadFMemIdx * XTheadFmv * XTheadInt * XTheadMac * XTheadMemIdx * XTheadMemPair * XTheadSync The extensions are just recognized by the compiler and feature test macros are generated (which this patch also brings tests for). gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add xthead* extensions. * config/riscv/riscv-opts.h (MASK_XTHEADBA): New. (TARGET_XTHEADBA): New. (MASK_XTHEADBB): New. (TARGET_XTHEADBB): New. (MASK_XTHEADBS): New. (TARGET_XTHEADBS): New. (MASK_XTHEADCMO): New. (TARGET_XTHEADCMO): New. (MASK_XTHEADCONDMOV): New. (TARGET_XTHEADCONDMOV): New. (MASK_XTHEADFMEMIDX): New. (TARGET_XTHEADFMEMIDX): New. (MASK_XTHEADFMV): New. (TARGET_XTHEADFMV): New. (MASK_XTHEADINT): New. (TARGET_XTHEADINT): New. (MASK_XTHEADMAC): New. (TARGET_XTHEADMAC): New. (MASK_XTHEADMEMIDX): New. (TARGET_XTHEADMEMIDX): New. (MASK_XTHEADMEMPAIR): New. (TARGET_XTHEADMEMPAIR): new. (MASK_XTHEADSYNC): New. (TARGET_XTHEADSYNC): New. * config/riscv/riscv.opt: Add riscv_xthead_subext. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadba.c: New test. * gcc.target/riscv/xtheadbb.c: New test. * gcc.target/riscv/xtheadbs.c: New test. * gcc.target/riscv/xtheadcmo.c: New test. * gcc.target/riscv/xtheadcondmov.c: New test. * gcc.target/riscv/xtheadfmemidx.c: New test. * gcc.target/riscv/xtheadfmv.c: New test. * gcc.target/riscv/xtheadint.c: New test. * gcc.target/riscv/xtheadmac.c: New test. * gcc.target/riscv/xtheadmemidx.c: New test. * gcc.target/riscv/xtheadmempair.c: New test. * gcc.target/riscv/xtheadsync.c: New test. Signed-off-by: Christoph Müllner --- gcc/common/config/riscv/riscv-common.cc | 26 +++++++++++++++++++ gcc/config/riscv/riscv-opts.h | 26 +++++++++++++++++++ gcc/config/riscv/riscv.opt | 3 +++ gcc/testsuite/gcc.target/riscv/xtheadba.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbb.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbs.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadcmo.c | 14 ++++++++++ .../gcc.target/riscv/xtheadcondmov.c | 14 ++++++++++ .../gcc.target/riscv/xtheadfmemidx.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadfmv.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadint.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadmac.c | 14 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 14 ++++++++++ .../gcc.target/riscv/xtheadmempair.c | 13 ++++++++++ gcc/testsuite/gcc.target/riscv/xtheadsync.c | 14 ++++++++++ 15 files changed, 222 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 4b7f777c103..84f7de8a16e 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -222,6 +222,19 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0}, + {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0}, + /* Terminate the list. */ {NULL, ISA_SPEC_CLASS_NONE, 0, 0} }; @@ -1247,6 +1260,19 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL}, {"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT}, + {"xtheadba", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA}, + {"xtheadbb", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB}, + {"xtheadbs", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBS}, + {"xtheadcmo", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCMO}, + {"xtheadcondmov", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV}, + {"xtheadfmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX}, + {"xtheadfmv", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMV}, + {"xtheadint", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADINT}, + {"xtheadmac", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMAC}, + {"xtheadmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX}, + {"xtheadmempair", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMPAIR}, + {"xtheadsync", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC}, + {NULL, NULL, 0} }; diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index 25fd85b09b1..4d433d5e9fe 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -189,4 +189,30 @@ enum stack_protector_guard { ? 0 \ : 32 << (__builtin_popcount (riscv_zvl_flags) - 1)) +#define MASK_XTHEADBA (1 << 0) +#define MASK_XTHEADBB (1 << 1) +#define MASK_XTHEADBS (1 << 2) +#define MASK_XTHEADCMO (1 << 3) +#define MASK_XTHEADCONDMOV (1 << 4) +#define MASK_XTHEADFMEMIDX (1 << 5) +#define MASK_XTHEADFMV (1 << 6) +#define MASK_XTHEADINT (1 << 7) +#define MASK_XTHEADMAC (1 << 8) +#define MASK_XTHEADMEMIDX (1 << 9) +#define MASK_XTHEADMEMPAIR (1 << 10) +#define MASK_XTHEADSYNC (1 << 11) + +#define TARGET_XTHEADBA ((riscv_xthead_subext & MASK_XTHEADBA) != 0) +#define TARGET_XTHEADBB ((riscv_xthead_subext & MASK_XTHEADBB) != 0) +#define TARGET_XTHEADBS ((riscv_xthead_subext & MASK_XTHEADBS) != 0) +#define TARGET_XTHEADCMO ((riscv_xthead_subext & MASK_XTHEADCMO) != 0) +#define TARGET_XTHEADCONDMOV ((riscv_xthead_subext & MASK_XTHEADCONDMOV) != 0) +#define TARGET_XTHEADFMEMIDX ((riscv_xthead_subext & MASK_XTHEADFMEMIDX) != 0) +#define TARGET_XTHEADFMV ((riscv_xthead_subext & MASK_XTHEADFMV) != 0) +#define TARGET_XTHEADINT ((riscv_xthead_subext & MASK_XTHEADINT) != 0) +#define TARGET_XTHEADMAC ((riscv_xthead_subext & MASK_XTHEADMAC) != 0) +#define TARGET_XTHEADMEMIDX ((riscv_xthead_subext & MASK_XTHEADMEMIDX) != 0) +#define TARGET_XTHEADMEMPAIR ((riscv_xthead_subext & MASK_XTHEADMEMPAIR) != 0) +#define TARGET_XTHEADSYNC ((riscv_xthead_subext & MASK_XTHEADSYNC) != 0) + #endif /* ! GCC_RISCV_OPTS_H */ diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 7c3ca48d1cc..3f2dd24d59b 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -233,6 +233,9 @@ int riscv_zm_subext TargetVariable int riscv_sv_subext +TargetVariable +int riscv_xthead_subext + Enum Name(isa_spec_class) Type(enum riscv_isa_spec_class) Supported ISA specs (for use with the -misa-spec= option): diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba.c b/gcc/testsuite/gcc.target/riscv/xtheadba.c new file mode 100644 index 00000000000..14cdb1ffe2e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadba.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadba" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */ + +#ifndef __riscv_xtheadba +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadbb.c new file mode 100644 index 00000000000..66988abf221 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ + +#ifndef __riscv_xtheadbb +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs.c b/gcc/testsuite/gcc.target/riscv/xtheadbs.c new file mode 100644 index 00000000000..808d7378a7b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbs.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbs" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */ + +#ifndef __riscv_xtheadbs +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcmo.c b/gcc/testsuite/gcc.target/riscv/xtheadcmo.c new file mode 100644 index 00000000000..eab8fef421c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcmo.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcmo" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcmo" { target { rv64 } } } */ + +#ifndef __riscv_xtheadcmo +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c new file mode 100644 index 00000000000..a239c3f9f46 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */ + +#ifndef __riscv_xtheadcondmov +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c new file mode 100644 index 00000000000..e450c5e5c5a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadfmemidx" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */ + +#ifndef __riscv_xtheadfmemidx +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv.c b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c new file mode 100644 index 00000000000..e97e8f461f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadfmv" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadfmv" { target { rv64 } } } */ + +#ifndef __riscv_xtheadfmv +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint.c b/gcc/testsuite/gcc.target/riscv/xtheadint.c new file mode 100644 index 00000000000..ee6989a380e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadint.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadint" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadint" { target { rv64 } } } */ + +#ifndef __riscv_xtheadint +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmac.c b/gcc/testsuite/gcc.target/riscv/xtheadmac.c new file mode 100644 index 00000000000..7c635407b31 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmac.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadmac" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadmac" { target { rv64 } } } */ + +#ifndef __riscv_xtheadmac +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c new file mode 100644 index 00000000000..076eab00f54 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */ + +#ifndef __riscv_xtheadmemidx +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair.c new file mode 100644 index 00000000000..5135d2175dc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadmempair" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadmempair" { target { rv64 } } } */ + +#ifndef __riscv_xtheadmempair +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} diff --git a/gcc/testsuite/gcc.target/riscv/xtheadsync.c b/gcc/testsuite/gcc.target/riscv/xtheadsync.c new file mode 100644 index 00000000000..835d60c96e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadsync.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadsync" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadsync" { target { rv64 } } } */ + +#ifndef __riscv_xtheadsync +#error Feature macro not defined +#endif + +int +foo (int a) +{ + return a; +} + From patchwork Mon Dec 19 01:08:31 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: 62115 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BDD0A3A60F51 for ; Mon, 19 Dec 2022 01:10:29 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id 3826C39578CC for ; Mon, 19 Dec 2022 01:08:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3826C39578CC 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-x534.google.com with SMTP id d20so10975421edn.0 for ; Sun, 18 Dec 2022 17:08:49 -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=0ZB/A9MWz0YQPSxZVDUsvKiYhaBKS8/08BbAUm93+hk=; b=k7TijdCsvvOHVvflrrvq1V82+fEPk9qhLigGJUG8fEPZ5ruor7qovmoSOKtH/g/4QO ufdxqoFwY823GEFy7S8zgDzniPre5FwsPKLTtjSrSt/IHShvizXIIZPLwrRPjKgTEzqy A7BuCrqhcLLaqu5ZfDJw9U0xOAm03RaisfJa6UJ6ukZjZ33+hyzOqaKTt5msa5Ve9bOw 8rmItsSJSxDgEH+tz8aHlXdpJitMieMG0W1T8Obb5u/kfgVlEzD3MwYdjopOXwpOdKPl SvENJY/VoD71VD3n/WzrgcUNgZ9z+nyfadwQ6152jDhWpL1Os0uIhbfEwnRHVyOQu557 h6Kg== 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=0ZB/A9MWz0YQPSxZVDUsvKiYhaBKS8/08BbAUm93+hk=; b=YPYTBQ68L/0fqeWfwcGp9qnuhD1AV3VFbgFYqSQceOCYRmXW8obTFwP6juHX2WO9eP piYY+bdl26yaTmuKvA6YFZfAaNE0LpVv+QZ4l31JcVvCe8uP7RQbLZf+EfgKuMjv3PY8 ALdMZAWdyKB3gANEn8D2w4PSicHGX9kavePbejfm8egwkRb8YJqJZCfOvOJxxObIBxus 8w2RfxT3Sy/HxIaLo6B0FLkx8+fWbns/XzGotNlYDObBXV8UouYYKjmWWJvqxK9k8HBr 67UQuH6YbHdBxlG/3+nfMsr899xUQ0WjasXRmaG7CrSIK7yWaeFalbxUty455vzI4JmE 5QEQ== X-Gm-Message-State: ANoB5pnHSe9scC69zeWg6jbr7NhOSplawMB78I0lvuRticReq1Z7ebEt zPkzG18cILqCD3LiMunCug+g/SYzHir+76dD X-Google-Smtp-Source: AA0mqf5icSdb6u3IWwn0hIOkTREfwVuEnkkkAoEGP1bJkNcWTrZEeKJ3NE8ao+awlysXjDu8qqc1ng== X-Received: by 2002:aa7:c6d3:0:b0:46c:6ed1:83ac with SMTP id b19-20020aa7c6d3000000b0046c6ed183acmr31285831eds.9.1671412127571; Sun, 18 Dec 2022 17:08:47 -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.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:47 -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 04/11] riscv: riscv-cores.def: Add T-Head XuanTie C906 Date: Mon, 19 Dec 2022 02:08:31 +0100 Message-Id: <20221219010838.3878675-5-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.2 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_NUMSUBJECT, 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906". The C906 is shipped for quite some time (it is the core of the Allwinner D1). Note, that the tuning struct for the C906 is already part of GCC (it is also name "thead-c906"). gcc/ChangeLog: * config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906". gcc/testsuite/ChangeLog: * gcc.target/riscv/mcpu-thead-c906.c: New test. Changes for v2: - Enable all supported vendor extensions Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv-cores.def | 4 +++ .../gcc.target/riscv/mcpu-thead-c906.c | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index 31ad34682c5..307381802fa 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -73,4 +73,8 @@ RISCV_CORE("sifive-s76", "rv64imafdc", "sifive-7-series") RISCV_CORE("sifive-u54", "rv64imafdc", "sifive-5-series") RISCV_CORE("sifive-u74", "rv64imafdc", "sifive-7-series") +RISCV_CORE("thead-c906", "rv64imafdc_xtheadba_xtheadbb_xtheadbs_xtheadcmo_" + "xtheadcondmov_xtheadfmemidx_xtheadmac_" + "xtheadmemidx_xtheadmempair_xtheadsync", + "thead-c906") #undef RISCV_CORE diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c new file mode 100644 index 00000000000..a71b43a6167 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */ +/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */ +/* T-Head XuanTie C906 => rv64imafdc */ + +#if !((__riscv_xlen == 64) \ + && !defined(__riscv_32e) \ + && defined(__riscv_mul) \ + && defined(__riscv_atomic) \ + && (__riscv_flen == 64) \ + && defined(__riscv_compressed) \ + && defined(__riscv_xtheadba) \ + && defined(__riscv_xtheadbb) \ + && defined(__riscv_xtheadbs) \ + && defined(__riscv_xtheadcmo) \ + && defined(__riscv_xtheadcondmov) \ + && defined(__riscv_xtheadfmemidx) \ + && defined(__riscv_xtheadmac) \ + && defined(__riscv_xtheadmemidx) \ + && defined(__riscv_xtheadmempair) \ + && defined(__riscv_xtheadsync)) +#error "unexpected arch" +#endif + +int main() +{ + return 0; +} From patchwork Mon Dec 19 01:08:32 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: 62119 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D17E439012CC for ; Mon, 19 Dec 2022 01:11:38 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by sourceware.org (Postfix) with ESMTPS id 8964739578EB for ; Mon, 19 Dec 2022 01:08:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8964739578EB 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-x529.google.com with SMTP id r26so10853158edc.10 for ; Sun, 18 Dec 2022 17:08:50 -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=OUgg8Du+/Wff+DQETawiCgu8tK0Xr9+pCS0ZJabuwZA=; b=AfyhcD1Niy8qh8XmDWHjI7b7nAoGud3DpKVBZdiYFDVwcrpfwg9qxGhiDn56Xdaq97 XoDiINqrke8j7D9RBbji6BarQmlurqisJTlgZKrH8CBq7DsZaa0U2257dmxadq2swrM4 doUi5M/Dv2CqrudBxKydXloHuy6UkafsP7KptKR0QduM34R46NCHC6UK/MJYEy5CuO0v mGnhXc99JhkpbYxpARwtHIETXd0a4veaJRXiNoxiykrDjfiIJJMRrEnbdLXbzovMRs7O bBDEmUIRTX3ffcGY3TVfj5o5cjs/AuRWdEja23YWNUjTBsrqckRS+EC+QnR60RqP/xy9 punA== 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=OUgg8Du+/Wff+DQETawiCgu8tK0Xr9+pCS0ZJabuwZA=; b=DyFLzK6vRiObEQ+cKwbqxsVpGpVMAamsASWSpDKaUE29oRzhkNUWgK48sEEK2paqOc vygW4GhQF5649evmDmO0kKoRP/E/HHDvffqum6dYhrw7eOrclqBpoW3Qz0rAhSFIZlTM VkXe1lwH4VUtg1K8cmq8sNO9cbOhw3dE6Ii5tUrVYQslW+8PtWy0ZUbP2qLA6uJCNtkj l0K9X8RxcfJHOwMOljo+f24DoIUF6W1vWPwCD9WGJNlt5Ah7sIIvFes00DY2EEW4/jkc ou6RT/cw2m82L++BrKeHalfutqmzOZiCQs3SwXsCP4Kiwb+Y8WRAXkx3RkFoJoJWn8V9 A2XA== X-Gm-Message-State: ANoB5pn8i41qam6gRUypCthwHRjX5S7MkH+tH7QoiEahW5ESo4ZJXKAs A8r9d0VxbCNFsI2JNBE8a/z48P0pRUKKDpRy X-Google-Smtp-Source: AA0mqf6BsEBKRNQ/5Dh/uyVc6Z8D0SN8wu+521dPJuhXHx97adPwKxbYEUkg990xjZ+lOD5COiUqjw== X-Received: by 2002:aa7:da85:0:b0:46c:b385:83d2 with SMTP id q5-20020aa7da85000000b0046cb38583d2mr50564935eds.0.1671412128937; Sun, 18 Dec 2022 17:08:48 -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.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:48 -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 05/11] riscv: thead: Add support for the XTheadBa ISA extension Date: Mon, 19 Dec 2022 02:08:32 +0100 Message-Id: <20221219010838.3878675-6-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This patch adds support for the XTheadBa ISA extension. The new INSN pattern is defined in a new file to separate this vendor extension from the standard extensions. gcc/ChangeLog: * config/riscv/riscv.md: Include thead.md * config/riscv/thead.md: New file. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadba-addsl.c: New test. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.md | 1 + gcc/config/riscv/thead.md | 31 +++++++++++ .../gcc.target/riscv/xtheadba-addsl.c | 55 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 gcc/config/riscv/thead.md create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index a8bb331f25c..571349b1ca5 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3073,4 +3073,5 @@ (define_insn "riscv_prefetchi_" (include "pic.md") (include "generic.md") (include "sifive-7.md") +(include "thead.md") (include "vector.md") diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md new file mode 100644 index 00000000000..0257cbfad3e --- /dev/null +++ b/gcc/config/riscv/thead.md @@ -0,0 +1,31 @@ +;; Machine description for T-Head vendor extensions +;; Copyright (C) 2021-2022 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; XTheadBa + +(define_insn "*th_addsl" + [(set (match_operand:X 0 "register_operand" "=r") + (plus:X (ashift:X (match_operand:X 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "I")) + (match_operand:X 3 "register_operand" "r")))] + "TARGET_XTHEADBA + && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)" + "th.addsl\t%0,%1,%3,%2" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c new file mode 100644 index 00000000000..5004735a246 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadba" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +long +test_1 (long a, long b) +{ + /* th.addsl aX, aX, 1 */ + return a + (b << 1); +} + +int +foos (short *x, int n) +{ + /* th.addsl aX, aX, 1 */ + return x[n]; +} + +long +test_2 (long a, long b) +{ + /* th.addsl aX, aX, 2 */ + return a + (b << 2); +} + +int +fooi (int *x, int n) +{ + /* th.addsl aX, aX, 2 */ + return x[n]; +} + +long +test_3 (long a, long b) +{ + /* th.addsl aX, aX, 3 */ + return a + (b << 3); +} + +long +fool (long *x, int n) +{ + /* th.addsl aX, aX, 2 (rv32) */ + /* th.addsl aX, aX, 3 (rv64) */ + return x[n]; +} + +/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 2 } } */ + +/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 3 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 2 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 2 { target { rv64 } } } } */ From patchwork Mon Dec 19 01:08:33 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: 62116 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2934539EB741 for ; Mon, 19 Dec 2022 01:10:41 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id BCB9939E8F0E for ; Mon, 19 Dec 2022 01:08:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BCB9939E8F0E 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-x52a.google.com with SMTP id r26so10853194edc.10 for ; Sun, 18 Dec 2022 17:08:51 -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=jwS2qz+WVrg2mL0XVwn3XBT0Yb8VsX9YZyklh5sNnd0=; b=LveyQQXPx9kS/ppgwE2PIGI/ZDXAkXEVN9hYSlFq5mo62yT0+YTKNftpzmPCCyEwrF +/0+0FVgqwbu/i4qUsDB3SUrZipIqzATtWmxxTkGGRpcL3kEqoxLuZlPwj1GQ6HL2ur8 ypgji+MRjP/kyONO/8d6m35KNmxLK/c3+B7mOf6Qij1BU5lGA4qzasoLOPLd6eN0+M05 RP5Khq2S5rDe6JRVkcUyylLc9nj2IW4nWLddGfChVmNEnORu/u4T/Gk4Vp6JvB0O12fd KjMmivAMja+Wr4AsziXefJm6+ToEwp669w7Ztc5aUMLSq8Z3KZ4pfs/lMx3aLrsk7S7I dbzA== 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=jwS2qz+WVrg2mL0XVwn3XBT0Yb8VsX9YZyklh5sNnd0=; b=Y8/7jLfqU/mfVyEvyvUXcAskUz2NU5lAEtpiRXnIJHk8DEN5uxvg7/2+Auyg4eMH8c ccIZx77L4oaV1+hvSFYNTr7m17gwxN92sqOb8U4rUwKjoxWM6ukfwxdV6Ls3lPdKDMHc ZY6Xw4BO26hLMcLsqz2fZZU7h6cr5j5LsBpKpX4IOHDF/Bc/2lc5cOnKuvqwRMeQF14Y CQaS5LucNN0WMbxTl2VPrlasSESesJlbTE5sfonWaw3k2JNKJQHdIL62YdfdN+mOk8mz fbO6rOQN6lpn/UfnbN7m1HGQ2rJEcFBQRuyqFqAREvK4V1tX6cBY2TNdICDzPenafVQr wIdA== X-Gm-Message-State: AFqh2koMnUQ79FDcYOc5H9AjPHlc+vIOeOmfh4U3t6qVE3lxjSQc7h5F PZC79UZzP4r3RfKyIVNpD8GwpKT81HTqdL5T X-Google-Smtp-Source: AMrXdXthWx/kcsUe/8chQwFjKt6pkUfvio/5f53hHCHK3gy3f2Ym4SFLYiJ5mL3Y+jUUBK68O89/ig== X-Received: by 2002:a05:6402:25c7:b0:461:c5b4:a7d0 with SMTP id x7-20020a05640225c700b00461c5b4a7d0mr2805395edb.24.1671412130193; Sun, 18 Dec 2022 17:08:50 -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.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:49 -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 06/11] riscv: thead: Add support for the XTheadBs ISA extension Date: Mon, 19 Dec 2022 02:08:33 +0100 Message-Id: <20221219010838.3878675-7-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This patch adds support for the XTheadBs ISA extension. The new INSN pattern is defined in a new file to separate this vendor extension from the standard extensions. The cost model adjustment reuses the xbs:bext cost. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_rtx_costs): Add xthead:tst cost. * config/riscv/thead.md (*th_tst): New INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadbs-tst.c: New test. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.cc | 4 ++-- gcc/config/riscv/thead.md | 11 +++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 13 +++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index a8d5e1dac7f..537515771c6 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2400,8 +2400,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; } - /* bext pattern for zbs. */ - if (TARGET_ZBS && outer_code == SET + /* bit extraction pattern (zbs:bext, xtheadbs:tst). */ + if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 1) { diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 0257cbfad3e..0e23644ef59 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -29,3 +29,14 @@ (define_insn "*th_addsl" "th.addsl\t%0,%1,%3,%2" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) + +;; XTheadBs + +(define_insn "*th_tst" + [(set (match_operand:X 0 "register_operand" "=r") + (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "immediate_operand" "i")))] + "TARGET_XTHEADBS" + "th.tst\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c new file mode 100644 index 00000000000..674cec09128 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbs" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +long +foo1 (long i) +{ + return 1L & (i >> 20); +} + +/* { dg-final { scan-assembler-times "th.tst\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */ From patchwork Mon Dec 19 01:08:34 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: 62117 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E3FE39EC027 for ; Mon, 19 Dec 2022 01:11:05 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id 3B88039DCB09 for ; Mon, 19 Dec 2022 01:08:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3B88039DCB09 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-x532.google.com with SMTP id d14so10837764edj.11 for ; Sun, 18 Dec 2022 17:08:53 -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=9sJT7RIaGd0weDV+9F/M8UWl7r4HL3qsL4TyTHlwScw=; b=KaMm7MPFtxXDa/SKtbaSnpEkzf7R6Zgt2J3OjiXwooFilKP6aNfwCoxjSm+YdJcIwE 2pSvHlsxEPVSJ4R1NHubYM9DwKyRCFFVzitbHbFGjndY6osTNed4Xz3dbmW9Oq6sIntn KTfTV45h5x8rZX/jnt1dv3UWzLLNTVeuuL5aQvwjqyUI5A/zx+U3W/MnW/8ratADLCJa ewnXTqr2eKP62LBCZHAzYDiCqF9mXNo2Xzs7ecEo3Ldh52O+qS36Nv862p1esxwI/jGs pPDyktCdXRd2LIOUOLqeAzn+tdrYrFAVh6snZJRZ3Ey0x+jms0QQ9mmRgzsOAJFSIf5y oqMQ== 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=9sJT7RIaGd0weDV+9F/M8UWl7r4HL3qsL4TyTHlwScw=; b=JkWa5dFDWPftkGGsuK1DcQmL4/h/QMwIj5mdWqLE9MHmua+POu951/osoOAtOWttTh yRiR4A36vgWxG2AoKluem2jGMoGTZDIzOidIGQCOAGXOOZaf/5K79W/dFzfYmFYSBcVY nH5Iy4YNeQd5291TmdPrHhVV8crmf5PVaEeymn5C5nFTl4lRoQxwfDPcfbSl5e3mZyEr 3le8qOQw1Bw1rA2IoMzjzsv9zue4ysN0gt6CMdW6s1SBiiY5ItVu+qXuPmsqmaLuQaMO GQXYOnQqrV/DMp6HWmHXj2PVGGUjsyKuVsVil8DU/epGmMIvRkLuWg/ANJsNLQTXEP6P dk7Q== X-Gm-Message-State: ANoB5pmr61UArAjjt53DramT8dxd+5c5mnYu0PijtJ5HHxLTVubA9ms9 EHKbcUj8TGvXPW6lWiZcp7ULNDK2x2fFOXR/ X-Google-Smtp-Source: AA0mqf7K28PRHqlZxWn/17EDUDJuXOIYK5b6wtS9anmt6xbn5WyHHb7x9i7EHkRqhLF5kcZIdJ6J2g== X-Received: by 2002:aa7:dc13:0:b0:467:559e:530c with SMTP id b19-20020aa7dc13000000b00467559e530cmr34373775edu.18.1671412131611; Sun, 18 Dec 2022 17:08:51 -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.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:51 -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 07/11] riscv: thead: Add support for th XTheadBb ISA extension Date: Mon, 19 Dec 2022 02:08:34 +0100 Message-Id: <20221219010838.3878675-8-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner This patch adds support for the XTheadBb ISA extension. Thus, there is a functional overlap of the new instructions with existing Bitmanip instruction, which allows a good amount of code sharing. However, the vendor extensions are cleanly separated from the standard extensions (e.g. by using INSN expand pattern that will re-emit RTL that matches the patterns of either Bitmanip or XThead INSNs). gcc/ChangeLog: * config/riscv/bitmanip.md (clzdi2): New expand. (clzsi2): New expand. (ctz2): New expand. (popcount2): New expand. (si2): Rename INSN. (*si2): Hide INSN name. (di2): Rename INSN. (*di2): Hide INSN name. (rotrsi3): Remove INSN. (rotr3): Add expand. (*rotrsi3): New INSN. (rotrdi3): Rename INSN. (*rotrdi3): Hide INSN name. (rotrsi3_sext): Rename INSN. (*rotrsi3_sext): Hide INSN name. (bswap2): Remove INSN. (bswapdi2): Add expand. (bswapsi2): Add expand. (*bswap2): Hide INSN name. * config/riscv/riscv.cc (riscv_rtx_costs): Add costs for sign extraction. * config/riscv/riscv.md (extv): New expand. (extzv): New expand. * config/riscv/thead.md (*th_srrisi3): New INSN. (*th_srridi3): New INSN. (*th_ext): New INSN. (*th_extu): New INSN. (*th_clz2): New INSN. (*th_revsi2): New INSN. (*th_revdi2): New INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadbb-ext.c: New test. * gcc.target/riscv/xtheadbb-extu-2.c: New test. * gcc.target/riscv/xtheadbb-extu.c: New test. * gcc.target/riscv/xtheadbb-ff1.c: New test. * gcc.target/riscv/xtheadbb-rev.c: New test. * gcc.target/riscv/xtheadbb-srri.c: New test. Changes for v2: - Merge all XTheadB* support patches - Remove useless operand sanity checks for extv and extzv - Prefer c.andi over th.extu if possible - Add ff1 tests for clz/ctz - Fix ext/extu test cases - Enable tests for RV32 Signed-off-by: Christoph Müllner --- gcc/config/riscv/bitmanip.md | 52 +++++++++++++-- gcc/config/riscv/riscv.cc | 9 +++ gcc/config/riscv/riscv.md | 20 ++++++ gcc/config/riscv/thead.md | 66 +++++++++++++++++++ gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 20 ++++++ .../gcc.target/riscv/xtheadbb-extu-2.c | 22 +++++++ .../gcc.target/riscv/xtheadbb-extu.c | 22 +++++++ gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c | 18 +++++ gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 45 +++++++++++++ .../gcc.target/riscv/xtheadbb-srri.c | 21 ++++++ 10 files changed, 289 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index d17133d58c1..70e72a35d7d 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -185,6 +185,26 @@ (define_insn "*slliuw" ;; ZBB extension. +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand") + (clz:DI (match_operand:DI 1 "register_operand")))] + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)") + +(define_expand "clzsi2" + [(set (match_operand:SI 0 "register_operand") + (clz:SI (match_operand:SI 1 "register_operand")))] + "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)") + +(define_expand "ctz2" + [(set (match_operand:GPR 0 "register_operand") + (ctz:GPR (match_operand:GPR 1 "register_operand")))] + "TARGET_ZBB") + +(define_expand "popcount2" + [(set (match_operand:GPR 0 "register_operand") + (popcount:GPR (match_operand:GPR 1 "register_operand")))] + "TARGET_ZBB") + (define_insn "*_not" [(set (match_operand:X 0 "register_operand" "=r") (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r")) @@ -216,7 +236,7 @@ (define_insn "*xor_not" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) -(define_insn "si2" +(define_insn "*si2" [(set (match_operand:SI 0 "register_operand" "=r") (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))] "TARGET_ZBB" @@ -233,7 +253,7 @@ (define_insn "*disi2" [(set_attr "type" "bitmanip") (set_attr "mode" "SI")]) -(define_insn "di2" +(define_insn "*di2" [(set (match_operand:DI 0 "register_operand" "=r") (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))] "TARGET_64BIT && TARGET_ZBB" @@ -273,7 +293,17 @@ (define_insn "*zero_extendhi2_zbb" [(set_attr "type" "bitmanip,load") (set_attr "mode" "HI")]) -(define_insn "rotrsi3" +(define_expand "rotr3" + [(set (match_operand:GPR 0 "register_operand") + (rotatert:GPR (match_operand:GPR 1 "register_operand") + (match_operand:QI 2 "arith_operand")))] + "TARGET_ZBB || TARGET_XTHEADBB" +{ + if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) + FAIL; +}) + +(define_insn "*rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "arith_operand" "rI")))] @@ -281,7 +311,7 @@ (define_insn "rotrsi3" "ror%i2%~\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "rotrdi3" +(define_insn "*rotrdi3" [(set (match_operand:DI 0 "register_operand" "=r") (rotatert:DI (match_operand:DI 1 "register_operand" "r") (match_operand:QI 2 "arith_operand" "rI")))] @@ -289,7 +319,7 @@ (define_insn "rotrdi3" "ror%i2\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "rotrsi3_sext" +(define_insn "*rotrsi3_sext" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "register_operand" "r"))))] @@ -329,7 +359,17 @@ (define_insn "orcb2" "TARGET_ZBB" "orc.b\t%0,%1") -(define_insn "bswap2" +(define_expand "bswapdi2" + [(set (match_operand:DI 0 "register_operand") + (bswap:DI (match_operand:DI 1 "register_operand")))] + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)") + +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "register_operand") + (bswap:SI (match_operand:SI 1 "register_operand")))] + "(!TARGET_64BIT && TARGET_ZBB) || TARGET_XTHEADBB") + +(define_insn "*bswap2" [(set (match_operand:X 0 "register_operand" "=r") (bswap:X (match_operand:X 1 "register_operand" "r")))] "TARGET_ZBB" diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 537515771c6..b57c1f1d727 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2408,6 +2408,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; } + gcc_fallthrough (); + case SIGN_EXTRACT: + if (TARGET_XTHEADBB && outer_code == SET + && CONST_INT_P (XEXP (x, 1)) + && CONST_INT_P (XEXP (x, 2))) + { + *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); + return true; + } return false; case ASHIFT: diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 571349b1ca5..8bdf3c128f3 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3067,6 +3067,26 @@ (define_insn "riscv_prefetchi_" "prefetch.i\t%a0" ) +(define_expand "extv" + [(set (match_operand:GPR 0 "register_operand" "=r") + (sign_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +) + +(define_expand "extzv" + [(set (match_operand:GPR 0 "register_operand" "=r") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + if (TARGET_XTHEADBB + && (INTVAL (operands[2]) < 8) && (INTVAL (operands[3]) == 0)) + FAIL; +}) + (include "bitmanip.md") (include "sync.md") (include "peephole.md") diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 0e23644ef59..c3cbb49eb58 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -30,6 +30,72 @@ (define_insn "*th_addsl" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) +;; XTheadBb + +(define_insn "*th_srrisi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (rotatert:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "I")))] + "TARGET_XTHEADBB" + { return TARGET_64BIT ? "th.srriw\t%0,%1,%2" : "th.srri\t%0,%1,%2"; } + [(set_attr "type" "bitmanip")]) + +(define_insn "*th_srridi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (rotatert:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "I")))] + "TARGET_XTHEADBB && TARGET_64BIT" + "th.srri\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*th_ext" + [(set (match_operand:GPR 0 "register_operand" "=r") + (sign_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); + return "th.ext\t%0,%1,%2,%3"; +} + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*th_extu" + [(set (match_operand:GPR 0 "register_operand" "=r") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); + return "th.extu\t%0,%1,%2,%3"; +} + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*th_clz2" + [(set (match_operand:X 0 "register_operand" "=r") + (clz:X (match_operand:X 1 "register_operand" "r")))] + "TARGET_XTHEADBB" + "th.ff1\t%0,%1" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*th_revsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (bswap:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_XTHEADBB" + { return TARGET_64BIT ? "th.revw\t%0,%1" : "th.rev\t%0,%1"; } + [(set_attr "type" "bitmanip")]) + +(define_insn "*th_revdi2" + [(set (match_operand:DI 0 "register_operand" "=r") + (bswap:DI (match_operand:DI 1 "register_operand" "r")))] + "TARGET_XTHEADBB && TARGET_64BIT" + "th.rev\t%0,%1" + [(set_attr "type" "bitmanip")]) + ;; XTheadBs (define_insn "*th_tst" diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c new file mode 100644 index 00000000000..60fb7d44e39 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + long a:9; + long b:26; + long c:22; +}; + +long +foo (struct bar *s) +{ + return s->b; +} + +/* { dg-final { scan-assembler "th.ext\t" } } */ +/* { dg-final { scan-assembler-not "andi" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c new file mode 100644 index 00000000000..029be93f401 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + unsigned long a:6; + unsigned long b:26; + unsigned long c:22; +}; + +/* We prefer andi over th.extu because it can be compressed. */ + +unsigned long +foo (struct bar *s) +{ + return s->a; +} + +/* { dg-final { scan-assembler-not "th.extu\t" } } */ +/* { dg-final { scan-assembler "andi\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c new file mode 100644 index 00000000000..e0492f1f5ad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + unsigned long a:5; + unsigned long b:26; + unsigned long c:22; +}; + +unsigned long +foo (struct bar *s) +{ + return s->b; +} + +/* { dg-final { scan-assembler "th.extu\t" } } */ +/* { dg-final { scan-assembler-not "andi" } } */ +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c new file mode 100644 index 00000000000..72038c4e281 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +foo (unsigned long a) +{ + return __builtin_clzl (a); +} + +int +bar (unsigned long a) +{ + return __builtin_ctzl (a); +} + +/* { dg-final { scan-assembler-times "th.ff1\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c new file mode 100644 index 00000000000..411d52007d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ + +unsigned int +foo32 (unsigned int x) +{ + return (((x << 24) & 0xff000000) + | ((x << 8) & 0xff0000) + | ((x >> 8) & 0xff00) + | ((x >> 24) & 0xff)); +} + +unsigned int +foo32_1 (unsigned int x) +{ + return __builtin_bswap32 (x); +} + +#if __riscv_xlen == 64 +unsigned long +foo64 (unsigned long x) +{ + return (((x << 56) & 0xff00000000000000ull) + | ((x << 40) & 0xff000000000000ull) + | ((x << 24) & 0xff0000000000ull) + | ((x << 8) & 0xff00000000ull) + | ((x >> 8) & 0xff000000) + | ((x >> 24) & 0xff0000) + | ((x >> 40) & 0xff00) + | ((x >> 56) & 0xff)); +} + +unsigned long +foo64_1 (unsigned long x) +{ + return __builtin_bswap64 (x); +} +#endif + +/* { dg-final { scan-assembler-times "th.rev\t" 2 { target { rv32 } } } } */ + +/* { dg-final { scan-assembler-times "th.revw\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.rev\t" 2 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c new file mode 100644 index 00000000000..033a500dfe9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +unsigned long +foo1 (unsigned long rs1) +{ + long shamt = __riscv_xlen - 11; + return (rs1 << shamt) + | (rs1 >> ((__riscv_xlen - shamt) & (__riscv_xlen - 1))); +} +unsigned long +foo2 (unsigned long rs1) +{ + unsigned long shamt = __riscv_xlen - 11; + return (rs1 >> shamt) + | (rs1 << ((__riscv_xlen - shamt) & (__riscv_xlen - 1))); +} + +/* { dg-final { scan-assembler-times "th.srri" 2 } } */ 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: 62120 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EAE92396CDEB for ; Mon, 19 Dec 2022 01:12:20 +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-Google-Smtp-Source: AA0mqf4KriS+4RQDAU5T73HEa45y9AVrLMzaiEG3odGxlHaOJo/xg6OIbe6FWIX8DP1AmyRhYJ4DNg== 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" 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 } } */ From patchwork Mon Dec 19 01:08:36 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: 62121 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2631538D2D32 for ; Mon, 19 Dec 2022 01:12:31 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id AEE1739DCB0B for ; Mon, 19 Dec 2022 01:08:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AEE1739DCB0B 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-x52a.google.com with SMTP id r26so10853326edc.10 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=gGVaHhAnrWoIVEAhkeKjZ+WvIAsXAD1lbuUP5ylGKWs=; b=eQaxyWFq6Rw627qxRBtTMhT2izEj4bYtgRDGbKfxUrN2kcKNxl90GYZ+rZqcD5P/g4 phVLDU7vVAtYV+pc+p7m53DQ9dB6lyGJmzZuG8izLWkiyE59erKuhLQFiXY32yLsWLiM nQBQUYnr+3zDfCEmRqSEq4JuYWM/X9jNeqM/XY48vajLbojWF/1M30JnJDtMa3CPjLth mvhouGoF59PjBYlsiwcDgFHI0sRCN+ygnexsm01G8gnRnNvCr3XPoRT3XgDu+FGML+AL YXBATyZjTBLG02nYrnlWF1NZVQ6KqwlmNpa/nr3GILVc/MF8Cu5LCkbe9gXTpG9KZeRa XmQA== 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=gGVaHhAnrWoIVEAhkeKjZ+WvIAsXAD1lbuUP5ylGKWs=; b=5mtCIPMqLmzcogWHbVzuqKwq9VHtLOAvSB5KvXTkoOnUbkFJIcrnd+jFBBSm1kWxKN SZzxxU+EwD8joCqpJ0vsF2Uy4waM1pVGSUt7uzLMYsds/pgJwvEuuM7DkCzQ5ylYy/Xu FdL2FDC/K+Oyxvsf9SoDpuSPmT3i1afUolW0eppaVEHcgJ/YcxFvB/aWnV01btmxxqkr f1WCBnHOAHrrUJwKEgZG+a79ICzunv9f3Klx3xETFFoa8S5WfVoGbKiEagbNphy0b0iW hA4fz1p9fPIFoh+Z5oR8dA5IBpXJseJ/sPZqdhHgwehuCx1r/Y5RykQLHf1HqwtP3Xpu sS1Q== X-Gm-Message-State: ANoB5pnoyoUWWsEnJjlv8CNXEA2R5EilnNeNb2IqJSQvkh99tNEXKyRA l27z1Rb+qfwHJxh2+I1X8dk8qeH658ovpmDE X-Google-Smtp-Source: AA0mqf5CzocNhPH+Y4fOB091Lm29f0NKrp/xKh5RVH+sloCSuo8ciIn2aHVUVEm5eFUOuUHeiVdqqw== X-Received: by 2002:a05:6402:5486:b0:467:c3cb:49aa with SMTP id fg6-20020a056402548600b00467c3cb49aamr33443656edb.4.1671412134796; Sun, 18 Dec 2022 17:08:54 -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.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:54 -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 09/11] riscv: thead: Add support for XTheadMac ISA extension Date: Mon, 19 Dec 2022 02:08:36 +0100 Message-Id: <20221219010838.3878675-10-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner The XTheadMac ISA extension provides multiply-accumulate/subtract instructions: * mula/mulaw/mulah * muls/mulsw/mulsh To benefit from middle-end passes, we expand the following named patterns in riscv.md (as they are not T-Head-specific): * maddhisi4 * msubhisi4 gcc/ChangeLog: * config/riscv/riscv.md (maddhisi4): New expand. (msubhisi4): New expand. * config/riscv/thead.md (*th_mula): New pattern. (*th_mulawsi): New pattern. (*th_mulawsi2): New pattern. (*th_maddhisi4): New pattern. (*th_sextw_maddhisi4): New pattern. (*th_muls): New pattern. (*th_mulswsi): New pattern. (*th_mulswsi2): New pattern. (*th_msubhisi4): New pattern. (*th_sextw_msubhisi4): New pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/thead-mula-muls.c: New test. Co-Developed-by: Xianmiao Qu Signed-off-by: Xianmiao Qu Signed-off-by: Christoph Müllner Changed in v2: - Add missing prefix in on INSN --- gcc/config/riscv/riscv.md | 18 +++ gcc/config/riscv/thead.md | 121 ++++++++++++++++++ .../gcc.target/riscv/xtheadmac-mula-muls.c | 43 +++++++ 3 files changed, 182 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 34327bfb01f..20506451e7c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3086,6 +3086,24 @@ (define_expand "extzv" FAIL; }) +(define_expand "maddhisi4" + [(set (match_operand:SI 0 "register_operand") + (plus:SI + (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand")) + (sign_extend:SI (match_operand:HI 2 "register_operand"))) + (match_operand:SI 3 "register_operand")))] + "TARGET_XTHEADMAC" +) + +(define_expand "msubhisi4" + [(set (match_operand:SI 0 "register_operand") + (minus:SI + (match_operand:SI 3 "register_operand") + (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand")) + (sign_extend:SI (match_operand:HI 2 "register_operand")))))] + "TARGET_XTHEADMAC" +) + (include "bitmanip.md") (include "sync.md") (include "peephole.md") diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 9f03d1d43b4..d9cac15cc5f 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -143,3 +143,124 @@ (define_insn "*th_cond_gpr_mov" th.mveqz\t%0,%z3,%1" [(set_attr "type" "condmove") (set_attr "mode" "")]) + +;; XTheadMac + +(define_insn "*th_mula" + [(set (match_operand:X 0 "register_operand" "=r") + (plus:X (mult:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "register_operand" "r")) + (match_operand:X 3 "register_operand" "0")))] + "TARGET_XTHEADMAC" + "th.mula\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "")] +) + +(define_insn "*th_mulawsi" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")) + (match_operand:SI 3 "register_operand" "0"))))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulaw\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_mulawsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")) + (match_operand:SI 3 "register_operand" "0")))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulaw\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_maddhisi4" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI + (mult:SI + (sign_extend:SI (match_operand:HI 1 "register_operand" " r")) + (sign_extend:SI (match_operand:HI 2 "register_operand" " r"))) + (match_operand:SI 3 "register_operand" " 0")))] + "TARGET_XTHEADMAC" + "th.mulah\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_sextw_maddhisi4" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (plus:SI + (mult:SI + (sign_extend:SI (match_operand:HI 1 "register_operand" " r")) + (sign_extend:SI (match_operand:HI 2 "register_operand" " r"))) + (match_operand:SI 3 "register_operand" " 0"))))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulah\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_muls" + [(set (match_operand:X 0 "register_operand" "=r") + (minus:X (match_operand:X 3 "register_operand" "0") + (mult:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "register_operand" "r"))))] + "TARGET_XTHEADMAC" + "th.muls\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "")] +) + +(define_insn "*th_mulswsi" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (minus:SI (match_operand:SI 3 "register_operand" "0") + (mult:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")))))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulsw\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_mulswsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (match_operand:SI 3 "register_operand" "0") + (mult:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulsw\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_msubhisi4" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (match_operand:SI 3 "register_operand" " 0") + (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " r")) + (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))))] + "TARGET_XTHEADMAC" + "th.mulsh\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) + +(define_insn "*th_sextw_msubhisi4" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (minus:SI (match_operand:SI 3 "register_operand" " 0") + (mult:SI + (sign_extend:SI (match_operand:HI 1 "register_operand" " r")) + (sign_extend:SI (match_operand:HI 2 "register_operand" " r"))))))] + "TARGET_XTHEADMAC && TARGET_64BIT" + "th.mulsh\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")] +) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c b/gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c new file mode 100644 index 00000000000..751a4be5091 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmac-mula-muls.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadmac" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadmac" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ + +long f_mula(long a, long b, long c) +{ + return a + b * c; +} + +long f_muls(long a, long b, long c) +{ + return a - b * c; +} + +#if __riscv_xlen == 64 +int f_mulaw(int a, int b, int c) +{ + return a + b * c; +} + +int f_mulsw(int a, int b, int c) +{ + return a - b * c; +} +#endif + +long f_mulah(int a, unsigned short b, unsigned short c) +{ + return a + (int)(short)b * (int)(short)c; +} + +long f_mulsh(int a, unsigned short b, unsigned short c) +{ + return a - (int)(short)b * (int)(short)c; +} + +/* { dg-final { scan-assembler-times "th.mula\t" 1 } } */ +/* { dg-final { scan-assembler-times "th.muls\t" 1 } } */ +/* { dg-final { scan-assembler-times "th.mulaw\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.mulsw\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.mulah\t" 1 } } */ +/* { dg-final { scan-assembler-times "th.mulsh\t" 1 } } */ From patchwork Mon Dec 19 01:08:37 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: 62122 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C1D4D384EF6D for ; Mon, 19 Dec 2022 01:12:57 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id 2073439DCB3C for ; Mon, 19 Dec 2022 01:08:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2073439DCB3C 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-x532.google.com with SMTP id d20so10975710edn.0 for ; Sun, 18 Dec 2022 17:08:57 -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=bwiPWAjN9yyxKi6iR7a0qHQiUghB0vob6hW2tF939uw=; b=Ktcw9tjII3wgZwccvJugV6ONAmrwYbrqc09Ebj8lcoQkrhUAp2kNkO2SPbYacZ/ZHD QWTl4cgrPIMMllJ8YlOr4/K+jah0LJYPiW6NYytlAa+E1gGC2iEZerhYs0gOLy5zJ2Dw m/Q46jL0IUfxIsIkYXM/bw6UM101NfKxL4gxYuJrLtKeVkzNfUfvI5WxIil6AZJrnkBj 5hSgO/IVN/Z7ciCJFtO3jhx1Xz0urLRBrkAkpVhkRVqJBXJV6NPeF8hDgT+dFFxwd5KF sZSRyTqm3bgWzJRYZ6uGzJcW43WJMJpaTVhCYcuxvt4HxHlLs/rQ4i2AMGixBbn9GNFt Z74w== 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=bwiPWAjN9yyxKi6iR7a0qHQiUghB0vob6hW2tF939uw=; b=34k1VJM4sSFox0TyqaUcFce8Gkc7Q5zUU/jmEubL3JTECrFJovjVjHpn/KuLTA/2ol dgLgFFmFbv7BCQMZOpnZde+6e0sQm9UZmiVPu+jBkGG2111gg4lwlNYmt7Qv3SzP/Wa/ uHAy4+M6p4GsyocdiK4Q8ErY1h7gO2G8nwnK83RfmUNz65qdgALiwsFYJJsj7ftel8Y/ 7kJK8Meemt1PqWkg9IFvUFH1AwKkE5xE6C2ruwwu187zfM8dJT/ZkEhyvGvN+/UX3Wmw LHksUJKbtSHTN2ViZYfHTyV8ZFdfsMgjxU6EUDvMkRUnI/bGFyeQzszoXnUTog+40DwB WEFA== X-Gm-Message-State: ANoB5plesmc2fF5VF8Vzet66WXNzhGDZITrUejbfrpoHUdZHILk7Aeyk eKz0owCWc0ylcdEdgsk3ZnQFqkwBNzxaIMYn X-Google-Smtp-Source: AA0mqf5/wDyCZC2n4KSa/Su4uX5fqomtrCKplykWklozIZBFZjIal8aGvIhSAEXi/caTQFi1xgDuXQ== X-Received: by 2002:a05:6402:3648:b0:462:9baa:7507 with SMTP id em8-20020a056402364800b004629baa7507mr35461204edb.8.1671412136199; Sun, 18 Dec 2022 17:08:56 -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.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:55 -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 10/11] riscv: thead: Add support for XTheadFmv ISA extension Date: Mon, 19 Dec 2022 02:08:37 +0100 Message-Id: <20221219010838.3878675-11-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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Christoph Müllner The XTheadFmv ISA extension provides instructions to move data between 32-bit GP registers and 64-bit FP registers. gcc/ChangeLog: * config/riscv/constraints.md (TARGET_XTHEADFMV ? FP_REGS : NO_REGS) New constraint "th_f_fmv". (TARGET_XTHEADFMV ? GR_REGS : NO_REGS): New constraint "th_r_fmv". * config/riscv/riscv.cc (riscv_split_doubleword_move): Add split code for XTheadFmv. (riscv_secondary_memory_needed): XTheadFmv does not need secondary memory. * config/riscv/riscv.md: Add new UNSPEC_XTHEADFMV and UNSPEC_XTHEADFMV_HW. Add support for XTheadFmv to movdf_hardfloat_rv32. * config/riscv/thead.md (th_fmv_hw_w_x): New INSN. (th_fmv_x_w): New INSN. (th_fmv_x_hw): New INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadfmv-fmv.c: New test. Co-Developed-by: Xianmiao Qu Signed-off-by: Xianmiao Qu Signed-off-by: Christoph Müllner --- gcc/config/riscv/constraints.md | 8 +++++ gcc/config/riscv/riscv.cc | 25 ++++++++++++-- gcc/config/riscv/riscv.md | 11 +++++-- gcc/config/riscv/thead.md | 33 +++++++++++++++++++ .../gcc.target/riscv/xtheadfmv-fmv.c | 24 ++++++++++++++ 5 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 51cffb2bcb6..f3b1af774e1 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -156,3 +156,11 @@ (define_constraint "Wdm" "Vector duplicate memory operand" (and (match_operand 0 "memory_operand") (match_code "reg" "0"))) + +;; Vendor ISA extension constraints. + +(define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS : NO_REGS" + "A floating-point register for XTheadFmv.") + +(define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS" + "An integer register for XTheadFmv.") diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 21ec7a6225b..fc18ce2c766 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2754,11 +2754,29 @@ riscv_split_64bit_move_p (rtx dest, rtx src) void riscv_split_doubleword_move (rtx dest, rtx src) { - rtx low_dest; + /* XTheadFmv has instructions for accessing the upper bits of a double. */ + if (!TARGET_64BIT && TARGET_XTHEADFMV) + { + if (FP_REG_RTX_P (dest)) + { + rtx low_src = riscv_subword (src, false); + rtx high_src = riscv_subword (src, true); + emit_insn (gen_th_fmv_hw_w_x (dest, high_src, low_src)); + return; + } + if (FP_REG_RTX_P (src)) + { + rtx low_dest = riscv_subword (dest, false); + rtx high_dest = riscv_subword (dest, true); + emit_insn (gen_th_fmv_x_w (low_dest, src)); + emit_insn (gen_th_fmv_x_hw (high_dest, src)); + return; + } + } /* The operation can be split into two normal moves. Decide in which order to do them. */ - low_dest = riscv_subword (dest, false); + rtx low_dest = riscv_subword (dest, false); if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src)) { riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true)); @@ -5752,7 +5770,8 @@ riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1, { return (!riscv_v_ext_vector_mode_p (mode) && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD - && (class1 == FP_REGS) != (class2 == FP_REGS)); + && (class1 == FP_REGS) != (class2 == FP_REGS) + && !TARGET_XTHEADFMV); } /* Implement TARGET_REGISTER_MOVE_COST. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 20506451e7c..ef6ae443059 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -100,6 +100,10 @@ (define_c_enum "unspecv" [ ;; Zihintpause unspec UNSPECV_PAUSE + + ;; XTheadFmv unspec + UNSPEC_XTHEADFMV + UNSPEC_XTHEADFMV_HW ]) (define_constants @@ -1836,16 +1840,17 @@ (define_expand "movdf" DONE; }) + ;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead. ;; (However, we can still use fcvt.d.w to zero a floating-point register.) (define_insn "*movdf_hardfloat_rv32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m") - (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*th_f_fmv,*th_r_fmv, *r,*r,*m") + (match_operand:DF 1 "move_operand" " f,G,m,f,G,*th_r_fmv,*th_f_fmv,*r*G,*m,*r"))] "!TARGET_64BIT && TARGET_DOUBLE_FLOAT && (register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode))" { return riscv_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store") + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) (define_insn "*movdf_hardfloat_rv64" diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index d9cac15cc5f..d3e3644c73f 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -144,6 +144,39 @@ (define_insn "*th_cond_gpr_mov" [(set_attr "type" "condmove") (set_attr "mode" "")]) +;; XTheadFmv + +;; In RV32, we lack fmv.x.d and fmv.d.x, but XTheadFmv has instructions +;; that cover this case. + +(define_insn "th_fmv_hw_w_x" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] + UNSPEC_XTHEADFMV))] + "!TARGET_64BIT && TARGET_XTHEADFMV" + "fmv.w.x\t%0,%2\n\tth.fmv.hw.x\t%0,%1" + [(set_attr "move_type" "move") + (set_attr "mode" "DF")]) + +(define_insn "th_fmv_x_w" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:DF 1 "register_operand" "f")] + UNSPEC_XTHEADFMV))] + "!TARGET_64BIT && TARGET_XTHEADFMV" + "fmv.x.w\t%0,%1" + [(set_attr "move_type" "move") + (set_attr "mode" "DF")]) + +(define_insn "th_fmv_x_hw" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:DF 1 "register_operand" "f")] + UNSPEC_XTHEADFMV_HW))] + "!TARGET_64BIT && TARGET_XTHEADFMV" + "th.fmv.x.hw\t%0,%1" + [(set_attr "move_type" "move") + (set_attr "mode" "DF")]) + ;; XTheadMac (define_insn "*th_mula" diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c new file mode 100644 index 00000000000..10d035e9e1d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target { rv32 } } } */ +/* { dg-options "-march=rv32gc_xtheadfmv" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +double +ll2d (long long ll) +{ + return *(double*)≪ +} + +long long +d2ll (double d) +{ + return *(long long*)&d; +} + +/* { dg-final { scan-assembler "fmv.w.x" } } */ +/* { dg-final { scan-assembler "th.fmv.hw.x" } } */ +/* { dg-final { scan-assembler "fmv.x.w" } } */ +/* { dg-final { scan-assembler "th.fmv.x.hw" } } */ +/* { dg-final { scan-assembler-not "sw" } } */ +/* { dg-final { scan-assembler-not "fld" } } */ +/* { dg-final { scan-assembler-not "fsd" } } */ +/* { dg-final { scan-assembler-not "lw" } } */ From patchwork Mon Dec 19 01:08:38 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: 62123 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 13BD83A1AC55 for ; Mon, 19 Dec 2022 01:14:14 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 7B90F3A63F02 for ; Mon, 19 Dec 2022 01:09:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7B90F3A63F02 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-ej1-x630.google.com with SMTP id fc4so18027319ejc.12 for ; Sun, 18 Dec 2022 17:09:00 -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=Rl0waIdIvhxDpg6ajhMZO7Yc11gmM9OTySMMp8Cc1ys=; b=biyRjiPthNf7sWmI/d80CDNxnFtWzwiYtU2TwIPeml5ByCLE9Y2Nn1vOFhXjq4SSRs kGMToza3RywUm+JtlzPO8AMXD/sKyGXw7vbnJpmCFe7/4+na9tJaIpoiQlF9qObuop/6 UKhebQegpXdc3m/gpuq4oB6BPKISveoqqWMBbMclWJx2OebQc677uRXEmXM0r6tys/mZ 1A0Mj7jwCyxEAn3UwI9xiMnH/1mPClCyvxCzsfE9hvBwYGlmuhszIFa1tdk2s9gXGe4H JQ55oh1zcs2d8RWu41ZpCiItjkugudC4wEaMM3luYeTkjmdF5xkuBe5RMKZD2GOcD0VC x7kg== 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=Rl0waIdIvhxDpg6ajhMZO7Yc11gmM9OTySMMp8Cc1ys=; b=d+61LhHrlbwMpVyAvNynmozlbspuPvjP3RuKb5KnVOUGWv5bFRd0qAwyKyGU0SwylP JIYl/glNKLU3uA0qa1uX0Rxr9FKxTiYmTM69hQAHhNaOJ4LNFtAl/YICRIAa84bHwWg/ anyDfqsd/q7hfhiTP0LsrstI0nDh1Ud61hAbvSauXse5TzaDjscp1/4Sf7Fqws0pdUMQ 2XUYS8omFPmn9ep/4uHxKO4X8XNN+nqP94mdvhaax/hDSAEAbniTPSqjz16qr2TRiDMd J+mte0o3hwSLUl/JuNmPYY/BY8p+3jUW+lPITWVdY4sXk/7/4Pwtow7aqpfuNvwpU8B8 hN7A== X-Gm-Message-State: ANoB5pkC2ZiyLk/cneMboma2w2f7qRmM5nRDW0zuN67Jez2sitx0jUFX DrCI1JtbrzM2z7wKpEmlhHqHfREnD8c1JeFK X-Google-Smtp-Source: AA0mqf609yX2lwiTOPlk+DoV0ZItWiNGo4zX1+oUy/d0qYcQd5FYoLhImuUo+gnlAOM9EkFVYoOXdQ== X-Received: by 2002:a17:907:1042:b0:7c0:be5d:59a9 with SMTP id oy2-20020a170907104200b007c0be5d59a9mr32337811ejb.20.1671412137723; Sun, 18 Dec 2022 17:08:57 -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.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 17:08:57 -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: "moiz.hussain" , =?utf-8?q?Christoph_M=C3=BCllner?= , "M . Moiz Hussain" Subject: [PATCH v2 11/11] riscv: thead: Add support for XTheadMemPair ISA extension Date: Mon, 19 Dec 2022 02:08:38 +0100 Message-Id: <20221219010838.3878675-12-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=-11.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, LIKELY_SPAM_BODY, 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: "moiz.hussain" The XTheadMemPair ISA extension provides load/store pair instructions: * th.ldd * th.sdd * th.lwd * th.lwud * th.swd This patch adds the following unnamed patterns to the peephole.md stage, which take care of reordering loads/stores appropriately: * load/store pair patterns for 4 instructions * load/store pair patterns for 2 instructions The generation of the load/store-pair instructions (based on ordered load/store sequences) is inspired by the approaches of other backends. The CFA expansion (save/restore registers on/from stack) is done quite late, therefore it needs special-treatment. This patch tries to minimize the impact for the default case and follows the pattern of other backends. gcc/ChangeLog: * config/riscv/peephole.md: New load/store pair ordering peephole optimizations. * config/riscv/predicates.md (reg_or_const_operand): New predicate. * config/riscv/riscv-protos.h (riscv_load_store_bonding_p_2instr): New prototype. (riscv_load_store_bonding_p_4instr): Likewise. (riscv_ldrstr_offset_compare): Likewise. (extract_base_offset_in_addr): Likewise. (th_riscv_output_mempair_move): Likewise. (th_riscv_gen_adjusted_mempair): Likewise. * config/riscv/riscv.cc (extract_base_offset_in_addr): New function. (riscv_split_plus): Likewise. (th_riscv_output_mempair_move): Likewise. (riscv_load_store_bonding_p_4instr): Likewise. (riscv_load_store_bonding_p_2instr): Likewise. (riscv_ldrstr_offset_compare): Likewise. (th_riscv_gen_adjusted_mempair): Likewise. (riscv_save_reg): Moved before new uses. (riscv_restore_reg): Moved before new uses. (riscv_for_each_saved_reg): Adjusted for load/store-pair support in CFA expansion. * config/riscv/thead.md (th_mov_mempair_): New INSN. (th_mov_mempair_di_si_zero_ext): New INSN. (th_mov_mempair_di_si_sign_ext): New INSN. (th_mov_mempair_si_si_zero_ext): New INSN. (th_mov_mempair_si_si_sign_ext): New INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadmempair-1.c: New test. * gcc.target/riscv/xtheadmempair-10.c: New test. * gcc.target/riscv/xtheadmempair-11.c: New test. * gcc.target/riscv/xtheadmempair-12.c: New test. * gcc.target/riscv/xtheadmempair-13.c: New test. * gcc.target/riscv/xtheadmempair-14.c: New test. * gcc.target/riscv/xtheadmempair-15.c: New test. * gcc.target/riscv/xtheadmempair-16.c: New test. * gcc.target/riscv/xtheadmempair-17.c: New test. * gcc.target/riscv/xtheadmempair-18.c: New test. * gcc.target/riscv/xtheadmempair-19.c: New test. * gcc.target/riscv/xtheadmempair-2.c: New test. * gcc.target/riscv/xtheadmempair-20.c: New test. * gcc.target/riscv/xtheadmempair-3.c: New test. * gcc.target/riscv/xtheadmempair-4.c: New test. * gcc.target/riscv/xtheadmempair-5.c: New test. * gcc.target/riscv/xtheadmempair-6.c: New test. * gcc.target/riscv/xtheadmempair-7.c: New test. * gcc.target/riscv/xtheadmempair-8.c: New test. * gcc.target/riscv/xtheadmempair-9.c: New test. * gcc.target/riscv/xtheadmempair-helper.h: New test. Co-Developed-by: Christoph Müllner Signed-off-by: Christoph Müllner Signed-off-by: M. Moiz Hussain Signed-off-by: Christoph Müllner --- gcc/config/riscv/peephole.md | 298 ++++++++ gcc/config/riscv/predicates.md | 4 + gcc/config/riscv/riscv-protos.h | 9 + gcc/config/riscv/riscv.cc | 701 +++++++++++++++++- gcc/config/riscv/thead.md | 86 +++ .../gcc.target/riscv/xtheadmempair-1.c | 29 + .../gcc.target/riscv/xtheadmempair-10.c | 36 + .../gcc.target/riscv/xtheadmempair-11.c | 18 + .../gcc.target/riscv/xtheadmempair-12.c | 20 + .../gcc.target/riscv/xtheadmempair-13.c | 23 + .../gcc.target/riscv/xtheadmempair-14.c | 30 + .../gcc.target/riscv/xtheadmempair-15.c | 15 + .../gcc.target/riscv/xtheadmempair-16.c | 18 + .../gcc.target/riscv/xtheadmempair-17.c | 13 + .../gcc.target/riscv/xtheadmempair-18.c | 49 ++ .../gcc.target/riscv/xtheadmempair-19.c | 86 +++ .../gcc.target/riscv/xtheadmempair-2.c | 26 + .../gcc.target/riscv/xtheadmempair-20.c | 21 + .../gcc.target/riscv/xtheadmempair-3.c | 30 + .../gcc.target/riscv/xtheadmempair-4.c | 20 + .../gcc.target/riscv/xtheadmempair-5.c | 21 + .../gcc.target/riscv/xtheadmempair-6.c | 19 + .../gcc.target/riscv/xtheadmempair-7.c | 22 + .../gcc.target/riscv/xtheadmempair-8.c | 29 + .../gcc.target/riscv/xtheadmempair-9.c | 37 + .../gcc.target/riscv/xtheadmempair-helper.h | 52 ++ 26 files changed, 1680 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-16.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-17.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-18.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-19.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-20.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-helper.h diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index d9477f46338..e0f04b09345 100644 --- a/gcc/config/riscv/peephole.md +++ b/gcc/config/riscv/peephole.md @@ -38,3 +38,301 @@ (define_peephole2 { operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5])); }) + +;; --- T-HEAD EXTENSION MEMPAIR - 4 instr LOADS -> 2 pairs --- +;; LOAD T-HEAD: Four DI loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "memory_operand" "")) + (set (match_operand:DI 2 "register_operand" "") + (match_operand:DI 3 "memory_operand" "")) + (set (match_operand:DI 4 "register_operand" "") + (match_operand:DI 5 "memory_operand" "")) + (set (match_operand:DI 6 "register_operand" "") + (match_operand:DI 7 "memory_operand" "")) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && riscv_load_store_bonding_p_4instr (operands, DImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, DImode, + SIGN_EXTEND, true)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: Four SI unsigned loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (zero_extend:DI (match_operand:SI 3 "memory_operand" ""))) + (set (match_operand:DI 4 "register_operand" "") + (zero_extend:DI (match_operand:SI 5 "memory_operand" ""))) + (set (match_operand:DI 6 "register_operand" "") + (zero_extend:DI (match_operand:SI 7 "memory_operand" ""))) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_4instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + ZERO_EXTEND, true)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: Four SI signed loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (sign_extend:DI (match_operand:SI 3 "memory_operand" ""))) + (set (match_operand:DI 4 "register_operand" "") + (sign_extend:DI (match_operand:SI 5 "memory_operand" ""))) + (set (match_operand:DI 6 "register_operand" "") + (sign_extend:DI (match_operand:SI 7 "memory_operand" ""))) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_4instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + SIGN_EXTEND, true)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: Four SI loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "memory_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "memory_operand" "")) + (set (match_operand:SI 4 "register_operand" "") + (match_operand:SI 5 "memory_operand" "")) + (set (match_operand:SI 6 "register_operand" "") + (match_operand:SI 7 "memory_operand" "")) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_4instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + SIGN_EXTEND, true)) + DONE; + else + FAIL; +}) + +;;--- T-HEAD EXTENSION MEMPAIR - 4 instr STORES -> 2 pairs --- +;; STORE T-HEAD: Four DI stores, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "reg_or_const_operand" "")) + (set (match_operand:DI 2 "memory_operand" "") + (match_operand:DI 3 "reg_or_const_operand" "")) + (set (match_operand:DI 4 "memory_operand" "") + (match_operand:DI 5 "reg_or_const_operand" "")) + (set (match_operand:DI 6 "memory_operand" "") + (match_operand:DI 7 "reg_or_const_operand" "")) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && riscv_load_store_bonding_p_4instr (operands, DImode, false)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, false, DImode, + SIGN_EXTEND, true)) + DONE; + else + FAIL; +}) + +;; STORE T-HEAD: Four SI stores, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 8 "r") + (set (match_operand:SI 0 "memory_operand" "") + (match_operand:SI 1 "reg_or_const_operand" "")) + (set (match_operand:SI 2 "memory_operand" "") + (match_operand:SI 3 "reg_or_const_operand" "")) + (set (match_operand:SI 4 "memory_operand" "") + (match_operand:SI 5 "reg_or_const_operand" "")) + (set (match_operand:SI 6 "memory_operand" "") + (match_operand:SI 7 "reg_or_const_operand" "")) + (match_dup 8)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_4instr (operands, SImode, false)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, false, SImode, + SIGN_EXTEND, true)) + DONE; + else + FAIL; +}) + +;; --- T-HEAD EXTENSION MEMPAIR - 2 instr LOADS -> 1 pair --- +;; LOAD T-HEAD: A pair of two DI loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "memory_operand" "")) + (set (match_operand:DI 2 "register_operand" "") + (match_operand:DI 3 "memory_operand" "")) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && riscv_load_store_bonding_p_2instr (operands, DImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, DImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: A pair of two DI extend unsigned SI loads, +;; with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (zero_extend:DI (match_operand:SI 3 "memory_operand" ""))) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_2instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + ZERO_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: A pair of two DI extend signed SI loads, +;; with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:DI 2 "register_operand" "") + (sign_extend:DI (match_operand:SI 3 "memory_operand" ""))) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_2instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: A pair of two SI extend unsigned SI loads, +;; with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:SI 2 "register_operand" "") + (zero_extend:SI (match_operand:SI 3 "memory_operand" ""))) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR && !TARGET_64BIT + && riscv_load_store_bonding_p_2instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + ZERO_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: A pair of two SI extend signed SI loads, +;; with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:SI 1 "memory_operand" ""))) + (set (match_operand:SI 2 "register_operand" "") + (sign_extend:SI (match_operand:SI 3 "memory_operand" ""))) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR && !TARGET_64BIT + && riscv_load_store_bonding_p_2instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; LOAD T-HEAD: A pair of two SI loads, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "memory_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "memory_operand" "")) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR && !TARGET_64BIT + && riscv_load_store_bonding_p_2instr (operands, SImode, true)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, true, SImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; T-HEAD EXTENSION MEMPAIR - 2 instr STORES -> 1 pair +;; STORE T-HEAD: A pair of two DI stores, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "reg_or_const_operand" "")) + (set (match_operand:DI 2 "memory_operand" "") + (match_operand:DI 3 "reg_or_const_operand" "")) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && riscv_load_store_bonding_p_2instr (operands, DImode, false)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, false, DImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) + +;; STORE T-HEAD: A pair of two SI stores, with non-adjusted offset +(define_peephole2 + [(match_scratch:P 4 "r") + (set (match_operand:SI 0 "memory_operand" "") + (match_operand:SI 1 "reg_or_const_operand" "")) + (set (match_operand:SI 2 "memory_operand" "") + (match_operand:SI 3 "reg_or_const_operand" "")) + (match_dup 4)] + "TARGET_XTHEADMEMPAIR + && riscv_load_store_bonding_p_2instr (operands, SImode, false)" + [(const_int 0)] +{ + if (th_riscv_gen_adjusted_mempair (operands, false, SImode, + SIGN_EXTEND, false)) + DONE; + else + FAIL; +}) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 5a5a49bf7c0..956a58bf41b 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -59,6 +59,10 @@ (define_predicate "reg_or_0_operand" (ior (match_operand 0 "const_0_operand") (match_operand 0 "register_operand"))) +(define_predicate "reg_or_const_operand" + (ior (match_operand 0 "const_int_operand") + (match_operand 0 "register_operand"))) + ;; Only use branch-on-bit sequences when the mask is not an ANDI immediate. (define_predicate "branch_on_bit_operand" (and (match_code "const_int") diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 7975bc4f438..b42533574d0 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -54,7 +54,16 @@ extern bool riscv_split_64bit_move_p (rtx, rtx); extern void riscv_split_doubleword_move (rtx, rtx); extern const char *riscv_output_move (rtx, rtx); extern const char *riscv_output_return (); +extern bool riscv_load_store_bonding_p_2instr (rtx*, machine_mode, bool); +extern bool riscv_load_store_bonding_p_4instr (rtx*, machine_mode, bool); +extern int riscv_ldrstr_offset_compare (const void *, const void *); +extern bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset); #ifdef RTX_CODE +extern const char *th_riscv_output_mempair_move (rtx*, machine_mode, + enum rtx_code); +extern bool th_riscv_gen_adjusted_mempair (rtx*, bool, machine_mode, + enum rtx_code, bool, + bool has_scratch = true); 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); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index fc18ce2c766..3ed84619278 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "alias.h" #include "tree.h" +#include "fold-const.h" #include "stringpool.h" #include "attribs.h" #include "varasm.h" @@ -57,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "predict.h" #include "tree-pass.h" +#include "tree-dfa.h" #include "opts.h" #include "tm-constrs.h" #include "rtl-iter.h" @@ -2943,6 +2945,570 @@ riscv_output_move (rtx dest, rtx src) gcc_unreachable (); } +/* If MEM is in the form of "base+offset", extract the two parts + of address and set to BASE and OFFSET, otherwise return false + after clearing BASE and OFFSET. */ + +bool +extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) +{ + rtx addr; + + gcc_assert (MEM_P (mem)); + + addr = XEXP (mem, 0); + + if (REG_P (addr)) + { + *base = addr; + *offset = const0_rtx; + return true; + } + + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) && CONST_INT_P (XEXP (addr, 1))) + { + *base = XEXP (addr, 0); + *offset = XEXP (addr, 1); + return true; + } + + *base = NULL_RTX; + *offset = NULL_RTX; + + return false; +} + +/* If X is a PLUS of a CONST_INT, return the two terms in *BASE_PTR + and *OFFSET_PTR. Return X in *BASE_PTR and 0 in *OFFSET_PTR otherwise. */ + +static void +riscv_split_plus (rtx x, rtx *base_ptr, HOST_WIDE_INT *offset_ptr) +{ + if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))) + { + *base_ptr = XEXP (x, 0); + *offset_ptr = INTVAL (XEXP (x, 1)); + } + else + { + *base_ptr = x; + *offset_ptr = 0; + } +} + +const char * +th_riscv_output_mempair_move (rtx *operands, machine_mode mode, + enum rtx_code code) +{ + unsigned width; + rtx reg1, reg2, mem1, mem2, base1, base2; + HOST_WIDE_INT offset1, offset2; + rtx output_operands[5]; + + width = GET_MODE_SIZE (mode).to_constant (); + + // LOAD + if (which_alternative == 0) + { + reg1 = copy_rtx (operands[0]); + reg2 = copy_rtx (operands[2]); + mem1 = copy_rtx (operands[1]); + mem2 = copy_rtx (operands[3]); + } + // STORE OR CONST STORE + else if ( (which_alternative == 1) + || (which_alternative == 2)) + { + reg1 = copy_rtx (operands[1]); + reg2 = copy_rtx (operands[3]); + mem1 = copy_rtx (operands[0]); + mem2 = copy_rtx (operands[2]); + } + else + abort (); + + riscv_split_plus (XEXP (mem1, 0), &base1, &offset1); + riscv_split_plus (XEXP (mem2, 0), &base2, &offset2); + + // LOAD + if (which_alternative == 0) + { + switch (width) + { + case 4: + { + gcc_assert (!(offset1 % 8)); + output_operands[0] = copy_rtx (reg1); + output_operands[1] = copy_rtx (reg2); + output_operands[2] = copy_rtx (base1); + output_operands[3] = gen_rtx_CONST_INT (mode, (offset1 >> 3)); + output_operands[4] = gen_rtx_CONST_INT (mode, 3); + + if (code == ZERO_EXTEND) + output_asm_insn ("th.lwud\t%0, %1, (%2), %3, %4", + output_operands); + else if (code == SIGN_EXTEND) + output_asm_insn ("th.lwd\t%0, %1, (%2), %3, %4", + output_operands); + else + abort (); + } + break; + case 8: + { + gcc_assert (!(offset1 % 16)); + output_operands[0] = copy_rtx (reg1); + output_operands[1] = copy_rtx (reg2); + output_operands[2] = copy_rtx (base1); + output_operands[3] = gen_rtx_CONST_INT (mode, (offset1 >> 4)); + output_operands[4] = gen_rtx_CONST_INT (mode, 4); + + output_asm_insn ("th.ldd\t%0, %1, (%2), %3, %4", output_operands); + } + break; + default: + abort (); + } + } + // STORE OR CONST STORE + else if (which_alternative == 1 || which_alternative == 2) + { + switch (width) + { + case 4: + { + gcc_assert (!(offset1 % 8)); + output_operands[0] = copy_rtx (reg1); + output_operands[1] = copy_rtx (reg2); + output_operands[2] = copy_rtx (base1); + output_operands[3] = gen_rtx_CONST_INT (mode, (offset1 >> 3)); + output_operands[4] = gen_rtx_CONST_INT (mode, 3); + + output_asm_insn ("th.swd\t%z0, %z1, (%2), %3, %4", + output_operands); + } + break; + case 8: + { + gcc_assert (!(offset1 % 16)); + output_operands[0] = copy_rtx (reg1); + output_operands[1] = copy_rtx (reg2); + output_operands[2] = copy_rtx (base1); + output_operands[3] = gen_rtx_CONST_INT (mode, (offset1 >> 4)); + output_operands[4] = gen_rtx_CONST_INT (mode, 4); + + output_asm_insn ("th.sdd\t%z0, %z1, (%2), %3, %4", + output_operands); + } + break; + default: + abort (); + } + } + // UNKNOWN + else + abort (); + + return ""; +} + +/* Given OPERANDS of consecutive load/store, check if we can merge + them into load-pair or store-pair instructions by adjusting the + offset. LOAD is true if they are load instructions. + MODE is the mode of memory operands. + + Given below consecutive stores: + + sd a2, 0x100 (a1) + sd a3, 0x108 (a1) + sd a4, 0x110 (a1) + sd a5, 0x118 (a1) + + Though the offsets are out of the range supported by stp, we can + still pair them after adjusting the offset, like: + + addi t0, a1, 0x100 + th.sdd a2, a3, 0 (t0), 0, 4 + th.sdd a4, a5, 16 (t0), 0, 4 + + The peephole patterns detecting this opportunity should guarantee + the scratch register is avaliable. + + The function works for 4 consecutive load/store pairs. */ + +bool +riscv_load_store_bonding_p_4instr (rtx *operands, machine_mode mode, + bool load_p) +{ + HOST_WIDE_INT msize; + msize = GET_MODE_SIZE (mode).to_constant (); + + constexpr int NUM_INSTR = 4; + + rtx reg[NUM_INSTR], mem[NUM_INSTR], base[NUM_INSTR]; + rtx temp_operands[2*NUM_INSTR]; + + enum reg_class rc[NUM_INSTR]; + HOST_WIDE_INT offset[NUM_INSTR]; + + /* We make changes on a copy as we may still bail out. */ + for (int i = 0; i < (2*NUM_INSTR); i++) + temp_operands[i] = copy_rtx (operands[i]); + + /* Sort the operands. */ + gcc_stablesort (temp_operands, NUM_INSTR, 2 * sizeof (rtx *), + riscv_ldrstr_offset_compare); + + for (int i = 0; i < NUM_INSTR; i++) + { + reg[i] = (load_p)? temp_operands[2*i] : temp_operands[(2*i) + 1]; + mem[i] = (load_p)? temp_operands[(2*i) + 1] : temp_operands[(2*i)]; + } + + for (int i = 0; i < NUM_INSTR; i++) + { + riscv_split_plus (XEXP (mem[i], 0), &base[i], &offset[i]); + rc[i] = REGNO_REG_CLASS (REGNO (reg[i])); + } + + for (int i = 0; i < NUM_INSTR; i++) + { + /* All bases are reg. */ + if (!REG_P (base[i])) + return false; + + /* The mems cannot be volatile. */ + if (MEM_VOLATILE_P (mem[i])) + return false; + + /* Base regs do not match. */ + if (!rtx_equal_p (base[i], base[(i+1) % NUM_INSTR])) + return false; + } + + /* Either of the loads is clobbering base register. + It is legitimate to bond loads if second load clobbers base register. + However, hardware does not support such bonding. */ + if (load_p + && (REGNO (reg[0]) == REGNO (base[0]) + || (REGNO (reg[1]) == REGNO (base[0]))) + && (REGNO (reg[2]) == REGNO (base[0]) + || (REGNO (reg[3]) == REGNO (base[3]))) + && (REGNO (reg[1]) == REGNO (base[1]) + || (REGNO (reg[2]) == REGNO (base[2])))) + return false; + + /* Loading in same registers. */ + if (load_p + && (REGNO (reg[0]) == REGNO (reg[1])) + && (REGNO (reg[1]) == REGNO (reg[2])) + && (REGNO (reg[2]) == REGNO (reg[3]))) + return false; + + /* The loads/stores are not of same type. */ + if (rc[0] != rc[1] + && rc[1] != rc[2] + && rc[2] != rc[3] + && !reg_class_subset_p (rc[0], rc[1]) + && !reg_class_subset_p (rc[1], rc[0]) + && !reg_class_subset_p (rc[2], rc[3]) + && !reg_class_subset_p (rc[3], rc[2]) + && !reg_class_subset_p (rc[1], rc[2]) + && !reg_class_subset_p (rc[2], rc[3])) + return false; + + if ((abs (offset[0] - offset[1]) != msize) + || (abs (offset[2] - offset[3]) != msize) + || (abs (offset[1] - offset[2]) != msize)) + return false; + + return true; +} + +/* Given OPERANDS of consecutive load/store, check if we can merge + them into load-pair or store-pair instructions by adjusting the + offset. LOAD is true if they are load instructions. + MODE is the mode of memory operands. + + Given below consecutive stores: + + sd a2, 0x100 (a1) + sd a3, 0x108 (a1) + sd a4, 0x110 (a1) + sd a5, 0x118 (a1) + + Though the offsets are out of the range supported by stp, we can + still pair them after adjusting the offset, like: + + addi t0, a1, 0x100 + th.sdd a2, a3, 0 (t0), 0, 4 + th.sdd a4, a5, 16 (t0), 0, 4 + + The peephole patterns detecting this opportunity should guarantee + the scratch register is avaliable. + + The function works for 2 consecutive load/store pairs. */ + +bool +riscv_load_store_bonding_p_2instr (rtx *operands, machine_mode mode, + bool load_p) +{ + HOST_WIDE_INT msize; + msize = GET_MODE_SIZE (mode).to_constant (); + + constexpr int NUM_INSTR = 2; + + rtx reg[NUM_INSTR], mem[NUM_INSTR], base[NUM_INSTR]; + rtx temp_operands[2*NUM_INSTR]; + + enum reg_class rc[NUM_INSTR]; + HOST_WIDE_INT offset[NUM_INSTR]; + + /* We make changes on a copy as we may still bail out. */ + for (int i = 0; i < (2*NUM_INSTR); i++) + temp_operands[i] = copy_rtx (operands[i]); + + /* Sort the operands. */ + gcc_stablesort (temp_operands, NUM_INSTR, 2 * sizeof (rtx *), + riscv_ldrstr_offset_compare); + + for (int i = 0; i < NUM_INSTR; i++) + { + reg[i] = (load_p)? temp_operands[2*i] : temp_operands[(2*i) + 1]; + mem[i] = (load_p)? temp_operands[(2*i) + 1] : temp_operands[(2*i)]; + } + + for (int i = 0; i < NUM_INSTR; i++) + { + riscv_split_plus (XEXP (mem[i], 0), &base[i], &offset[i]); + rc[i] = REGNO_REG_CLASS (REGNO (reg[i])); + } + + for (int i = 0; i < NUM_INSTR; i++) + { + /* All bases are reg. */ + if (!REG_P (base[i])) + return false; + + /* The mems cannot be volatile. */ + if (MEM_VOLATILE_P (mem[i])) + return false; + + /* Base regs do not match. */ + if (!rtx_equal_p (base[i], base[(i+1) % NUM_INSTR])) + return false; + } + + /* Either of the loads is clobbering base register. + It is legitimate to bond loads if second load clobbers base register. + However, hardware does not support such bonding. */ + if (load_p + && (REGNO (reg[0]) == REGNO (base[0]) + || (REGNO (reg[1]) == REGNO (base[0])))) + return false; + + /* Loading in same registers. */ + if (load_p + && REGNO (reg[0]) == REGNO (reg[1])) + return false; + + /* The loads/stores are not of same type. */ + if (rc[0] != rc[1] + && !reg_class_subset_p (rc[0], rc[1]) + && !reg_class_subset_p (rc[1], rc[0])) + return false; + + if (abs (offset[0] - offset[1]) != msize) + return false; + + return true; +} + +/* Taking X and Y to be pairs of RTX, one pointing to a MEM rtx and the + other pointing to a REG rtx containing an offset, compare the offsets + of the two pairs. + + Return: + 1 iff offset (X) > offset (Y) + 0 iff offset (X) == offset (Y) + -1 iff offset (X) < offset (Y) */ + +int +riscv_ldrstr_offset_compare (const void *x, const void *y) +{ + const rtx * operands_1 = (const rtx *) x; + const rtx * operands_2 = (const rtx *) y; + rtx mem_1, mem_2, base, offset_1, offset_2; + + if (MEM_P (operands_1[0])) + mem_1 = operands_1[0]; + else + mem_1 = operands_1[1]; + + if (MEM_P (operands_2[0])) + mem_2 = operands_2[0]; + else + mem_2 = operands_2[1]; + + /* Extract the offsets. */ + extract_base_offset_in_addr (mem_1, &base, &offset_1); + extract_base_offset_in_addr (mem_2, &base, &offset_2); + + gcc_assert (offset_1 != NULL_RTX && offset_2 != NULL_RTX); + + return wi::cmps (INTVAL (offset_1), INTVAL (offset_2)); +} + +/* Given OPERANDS of consecutive load/store, this function pairs them + into LDP/STP after adjusting the offset. It depends on the fact + that the operands can be sorted so the offsets are correct for STP. + MODE is the mode of memory operands. CODE is the rtl operator + which should be applied to all memory operands, it's SIGN_EXTEND, + ZERO_EXTEND or UNKNOWN. */ + +bool +th_riscv_gen_adjusted_mempair (rtx *operands, bool load, + machine_mode mode, + enum rtx_code code, + bool is_four_insns, + bool has_scratch) +{ + rtx base, offset_1, t1, t2, scratch; + HOST_WIDE_INT off_val_1, base_off, new_off_1, + off_upper_limit, off_lower_limit, msize; + + constexpr int NUM_INSTR_MAX = 4; + int NUM_INSTR = 2; + if (is_four_insns) + NUM_INSTR = 4; + + rtx temp_operands[2*NUM_INSTR_MAX], mem[NUM_INSTR_MAX]; + bool emit_adjust_insn = false; + bool misaligned_offset = false; + + if (has_scratch) + scratch = copy_rtx (operands[2*NUM_INSTR]); + + msize = GET_MODE_SIZE (mode).to_constant (); + + /* Sort the mem operands. */ + gcc_stablesort (operands, NUM_INSTR, 2 * sizeof (rtx *), + riscv_ldrstr_offset_compare); + + /* We make changes on a copy as we may still bail out. */ + for (int i = 0; i < (2*NUM_INSTR); i++) + temp_operands[i] = copy_rtx (operands[i]); + + for (int i = 0; i < NUM_INSTR; i++) + mem[i] = copy_rtx (load? temp_operands[(2*i) + 1] : temp_operands[2*i]); + + extract_base_offset_in_addr (mem[0], &base, &offset_1); + gcc_assert (base != NULL_RTX && offset_1 != NULL_RTX); + + off_val_1 = INTVAL (offset_1); + + switch (msize) + { + case 4: + { + off_upper_limit = 3 << 3; + off_lower_limit = 0; + misaligned_offset = (off_val_1 % 8) ? true : false; + } + break; + case 8: + { + off_upper_limit = 3 << 4; + off_lower_limit = 0; + misaligned_offset = (off_val_1 % 16) ? true : false; + } + break; + default: + abort (); + } + + /* Offset of the first STP/LDP. */ + if ((off_val_1 < off_lower_limit) + || (off_val_1 > off_upper_limit) + || misaligned_offset) + { + emit_adjust_insn = true; + new_off_1 = 0; + base_off = abs (new_off_1 - off_val_1); + } + + for (int i = 0; i < NUM_INSTR; i++) + { + if (has_scratch && emit_adjust_insn) + { + replace_equiv_address_nv (mem[i], plus_constant (Pmode, scratch, + (new_off_1 + (i*msize))), true); + } + + operands[2*i] = (load)? temp_operands[2*i] : mem[i]; + operands[(2*i) + 1] = (load)? mem[i] : temp_operands[(2*i) + 1]; + } + + if (is_four_insns) + { + if (!riscv_load_store_bonding_p_4instr (operands, mode, load)) + { + return false; + } + } + else + { + if (!riscv_load_store_bonding_p_2instr (operands, mode, load)) + { + return false; + } + } + + /* Sign extension for loads. */ + for (int i = 0; i < NUM_INSTR; i++) + { + if (load && GET_MODE_SIZE (GET_MODE (mem[i])).to_constant () == 4) + { + if (code == ZERO_EXTEND) + { + mem[i] = gen_rtx_ZERO_EXTEND (Pmode, mem[i]); + } + else if (code == SIGN_EXTEND) + { + mem[i] = gen_rtx_SIGN_EXTEND (Pmode, mem[i]); + } + else + { + abort (); + } + } + + operands[2*i] = (load)? temp_operands[2*i] : mem[i]; + operands[(2*i) + 1] = (load)? mem[i] : temp_operands[(2*i) + 1]; + } + + /* Emit adjusting instruction. */ + if (has_scratch && emit_adjust_insn) + { + emit_insn (gen_rtx_SET (scratch, plus_constant (Pmode, base, base_off))); + } + + /* Emit ld/sd paired instructions. */ + t1 = gen_rtx_SET (operands[0], operands[1]); + t2 = gen_rtx_SET (operands[2], operands[3]); + + emit_insn (gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2))); + if (is_four_insns) + { + t1 = gen_rtx_SET (operands[4], operands[5]); + t2 = gen_rtx_SET (operands[6], operands[7]); + emit_insn (gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2))); + } + + return true; +} + const char * riscv_output_return () { @@ -4916,6 +5482,35 @@ riscv_set_return_address (rtx address, rtx scratch) riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address); } +/* Save register REG to MEM. Make the instruction frame-related. */ + +static void +riscv_save_reg (rtx reg, rtx mem) +{ + riscv_emit_move (mem, reg); + riscv_set_frame_expr (riscv_frame_set (mem, reg)); +} + +/* Restore register REG from MEM. */ + +static void +riscv_restore_reg (rtx reg, rtx mem) +{ + rtx insn = riscv_emit_move (reg, mem); + rtx dwarf = NULL_RTX; + dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); + + if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM) + { + rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (epilogue_cfa_sp_offset)); + dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); + } + + REG_NOTES (insn) = dwarf; + RTX_FRAME_RELATED_P (insn) = 1; +} + /* A function to save or store a register. The first argument is the register and the second is the stack slot. */ typedef void (*riscv_save_restore_fn) (rtx, rtx); @@ -4985,8 +5580,8 @@ static void riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, bool epilogue, bool maybe_eh_return) { - HOST_WIDE_INT offset; - unsigned int regno; + HOST_WIDE_INT offset, offset2; + unsigned int regno, regno2; unsigned int start = GP_REG_FIRST; unsigned int limit = GP_REG_LAST; @@ -5009,7 +5604,78 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, && riscv_is_eh_return_data_register (regno)) continue; - riscv_save_restore_reg (word_mode, regno, offset, fn); + if (TARGET_XTHEADMEMPAIR && regno < limit) + { + offset2 = offset; + regno2 = riscv_next_saved_reg (regno + 1, limit, &offset2, false); + } + + if (TARGET_XTHEADMEMPAIR && regno2 <= limit + && !riscv_is_eh_return_data_register (regno2) + && !cfun->machine->reg_is_wrapped_separately[regno2]) + { + if ((fn == riscv_save_reg) || (fn == riscv_restore_reg)) + { + rtx operands[4], reg1, reg2, mem1, mem2; + HOST_WIDE_INT mem_stride; + + reg1 = gen_rtx_REG (Pmode, regno); + mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + offset)); + reg2 = gen_rtx_REG (Pmode, regno2); + mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + offset2)); + + if (fn == riscv_restore_reg) + { + operands[0] = copy_rtx (reg1); + operands[1] = copy_rtx (mem1); + operands[2] = copy_rtx (reg2); + operands[3] = copy_rtx (mem2); + } + else if (fn == riscv_save_reg) + { + operands[0] = copy_rtx (mem1); + operands[1] = copy_rtx (reg1); + operands[2] = copy_rtx (mem2); + operands[3] = copy_rtx (reg2); + } + else + abort (); + + /* Sort the mem operands. */ + gcc_stablesort (operands, 2, 2 * sizeof (rtx *), + riscv_ldrstr_offset_compare); + + mem_stride = abs (offset - offset2); + + /* Offset alignment should be matching the pair immediate. */ + if ((mem_stride == 8) && (offset % 16)) + emit_insn (gen_th_mov_mempair_DI (operands[0], operands[1], + operands[2], operands[3])); + else if ((mem_stride == 4) && (offset % 8)) + emit_insn (gen_th_mov_mempair_SI (operands[0], operands[1], + operands[2], operands[3])); + else + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + continue; + } + + offset = offset2; + regno = regno2; + } + else + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + } + } + else + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + } } /* This loop must iterate over the same space as its companion in @@ -5027,35 +5693,6 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } -/* Save register REG to MEM. Make the instruction frame-related. */ - -static void -riscv_save_reg (rtx reg, rtx mem) -{ - riscv_emit_move (mem, reg); - riscv_set_frame_expr (riscv_frame_set (mem, reg)); -} - -/* Restore register REG from MEM. */ - -static void -riscv_restore_reg (rtx reg, rtx mem) -{ - rtx insn = riscv_emit_move (reg, mem); - rtx dwarf = NULL_RTX; - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - - if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM) - { - rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (epilogue_cfa_sp_offset)); - dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); - } - - REG_NOTES (insn) = dwarf; - RTX_FRAME_RELATED_P (insn) = 1; -} - /* For stack frames that can't be allocated with a single ADDI instruction, compute the best value to initially allocate. It must at a minimum allocate enough space to spill the callee-saved registers. If TARGET_RVC, diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index d3e3644c73f..b039dd6e2e1 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -297,3 +297,89 @@ (define_insn "*th_sextw_msubhisi4" [(set_attr "type" "imul") (set_attr "mode" "SI")] ) + +;; XTheadMemPair + +;; MEMPAIR load/store 64/32 bit +(define_insn "th_mov_mempair_" + [(set (match_operand:GPR 0 "nonimmediate_operand" "=r, m, m") + (match_operand:GPR 1 "move_operand" "m, r, T")) + (set (match_operand:GPR 2 "nonimmediate_operand" "=r, m, m") + (match_operand:GPR 3 "move_operand" "m, r, T"))] + "TARGET_XTHEADMEMPAIR && reload_completed + && (register_operand (operands[0], mode) + || reg_or_const_operand (operands[1], mode)) + && (register_operand (operands[2], mode) + || reg_or_const_operand (operands[3], mode))" + { return th_riscv_output_mempair_move (operands, mode, + SIGN_EXTEND); } + [(set_attr "move_type" "load, store, const") + (set_attr "mode" "")]) + +;; MEMPAIR load DI extended unsigned SI +(define_insn "th_mov_mempair_di_si_zero_ext" + [(set (match_operand 0 "nonimmediate_operand" "=r") + (zero_extend:DI (match_operand 1 "move_operand" "m"))) + (set (match_operand 2 "nonimmediate_operand" "=r") + (zero_extend:DI (match_operand 3 "move_operand" "m")))] + "TARGET_XTHEADMEMPAIR && reload_completed + && (register_operand (operands[0], DImode) + || reg_or_const_operand (operands[1], SImode)) + && (register_operand (operands[2], DImode) + || reg_or_const_operand (operands[3], SImode))" + { return th_riscv_output_mempair_move (operands, SImode, + ZERO_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "DI") + (set_attr "length" "8")]) + +;; MEMPAIR load DI extended signed SI +(define_insn "th_mov_mempair_di_si_sign_ext" + [(set (match_operand 0 "nonimmediate_operand" "=r") + (sign_extend:DI (match_operand 1 "move_operand" "m"))) + (set (match_operand 2 "nonimmediate_operand" "=r") + (sign_extend:DI (match_operand 3 "move_operand" "m")))] + "TARGET_XTHEADMEMPAIR && reload_completed + && (register_operand (operands[0], DImode) + || reg_or_const_operand (operands[1], SImode)) + && (register_operand (operands[2], DImode) + || reg_or_const_operand (operands[3], SImode))" + { return th_riscv_output_mempair_move (operands, SImode, + SIGN_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "DI") + (set_attr "length" "8")]) + +;; MEMPAIR load SI extended unsigned SI +(define_insn "th_mov_mempair_si_si_zero_ext" + [(set (match_operand 0 "nonimmediate_operand" "=r") + (zero_extend:SI (match_operand 1 "move_operand" "m"))) + (set (match_operand 2 "nonimmediate_operand" "=r") + (zero_extend:SI (match_operand 3 "move_operand" "m")))] + "TARGET_XTHEADMEMPAIR && reload_completed + && (register_operand (operands[0], SImode) + || reg_or_const_operand (operands[1], SImode)) + && (register_operand (operands[2], SImode) + || reg_or_const_operand (operands[3], SImode))" + { return th_riscv_output_mempair_move (operands, SImode, + ZERO_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "SI") + (set_attr "length" "4")]) + +;; MEMPAIR load SI extended signed SI +(define_insn "th_mov_mempair_si_si_sign_ext" + [(set (match_operand 0 "nonimmediate_operand" "=r") + (sign_extend:SI (match_operand 1 "move_operand" "m"))) + (set (match_operand 2 "nonimmediate_operand" "=r") + (sign_extend:SI (match_operand 3 "move_operand" "m")))] + "TARGET_XTHEADMEMPAIR && reload_completed + && (register_operand (operands[0], SImode) + || reg_or_const_operand (operands[1], SImode)) + && (register_operand (operands[2], SImode) + || reg_or_const_operand (operands[3], SImode))" + { return th_riscv_output_mempair_move (operands, SImode, + SIGN_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "SI") + (set_attr "length" "4")]) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c new file mode 100644 index 00000000000..64085e236a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-funroll-loops"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +#define A_SIZE 32 + +unsigned long long array[A_SIZE]; +unsigned long long temp[A_SIZE]; + +void bar (void); + +int +foo (void) +{ + for (int i=0; i + +struct S0 +{ + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; +} a; + +struct S2 +{ + uint64_t f0; + uint64_t f2; + struct S0 f3; +}; + +void +fn1 (struct S2 b) +{ + a = b.f3; +} + +/* { dg-final { scan-assembler-times "addi\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.ldd\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 2 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "addi\t" 4 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 5 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 5 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-11.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-11.c new file mode 100644 index 00000000000..23c07c8839a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-11.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int arr[4][4] = {{0, 1, 1, -1}, {-1, -1, 1, -1}, {1, -1, 1, 1}, {1, -1, -1, 0}}; + +long long +foo () +{ + long long ll; + ll = arr[1][0]; + ll += arr[1][1]; + ll += arr[1][2]; + return ll; +} + +/* { dg-final { scan-assembler-times "th.lwd\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-12.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-12.c new file mode 100644 index 00000000000..b348dc1884d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-12.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +unsigned int arr[4][4] = {{0, 1, 1, 2}, {2, 2, 1, 2}, {1, 2, 1, 1}, {1, 2, 2, 0}}; + +unsigned long long +foo () +{ + unsigned long long ll; + ll = arr[1][0]; + ll += arr[1][1]; + return ll; +} + +/* { dg-final { scan-assembler-times "th.lwud\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 1 { target { rv32 } } } } */ + + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-13.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-13.c new file mode 100644 index 00000000000..fcb96c0b622 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-13.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +typedef float __attribute__ ((vector_size (8))) fvec; +typedef int __attribute__ ((vector_size (8))) ivec; + +struct vec_pair +{ + fvec a; + ivec b; +}; + +void +ldp (fvec *a, ivec *b, struct vec_pair *p) +{ + *a = p->a; + *b = p->b; +} + +/* { dg-final { scan-assembler-times "th.ldd\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 2 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-14.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-14.c new file mode 100644 index 00000000000..6fa991ee271 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-14.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +void +store (int *arr, int x, int y, int z) +{ + arr[400] = x; + arr[401] = y; + + arr[500] = z; + arr[501] = x; +} + +void +store_long (long long int *arr, long long int x, long long int y) +{ + arr[400] = x; + arr[401] = y; + + arr[403] = y; + arr[404] = x; +} + +/* { dg-final { scan-assembler-times "addi\t" 4 } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 6 { target { rv32 } } } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-15.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-15.c new file mode 100644 index 00000000000..297f86e18ca --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-15.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +long long +load_long (long long int *arr) +{ + return arr[400] << 1 + arr[401] << 1 + arr[403] << 1 + arr[404] << 1; +} + +/* { dg-final { scan-assembler-times "addi\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.ldd\t" 1 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "th.lwd\t" 1 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-16.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-16.c new file mode 100644 index 00000000000..a65c5526de9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-16.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +void +store_offset (int *array, int x, int y) +{ + array[1085] = x; + array[1084] = y; + + array[1086] = y; + array[1087] = x; +} + +/* { dg-final { scan-assembler-times "addi\t" 1 } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 2 } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-17.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-17.c new file mode 100644 index 00000000000..be2162e2f60 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-17.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int +load (int *arr) +{ + return (arr[400] + arr[401] + arr[527] + arr[528]); +} + +/* { dg-final { scan-assembler-times "addi\t" 2 } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-18.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-18.c new file mode 100644 index 00000000000..75105d2765b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-18.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +#include "xtheadmempair-helper.h" +#include + +CONST_FN (2, int32_t, 0); + +CONST_FN (4, int32_t, 0); + +CONST_FN (8, int32_t, 0); + +CONST_FN (16, int32_t, 0); + +CONST_FN (2, int32_t, 1); + +CONST_FN (4, int32_t, 1); + +CONST_FN (8, int32_t, 1); + +DUP_FN (2, int32_t); + +DUP_FN (4, int32_t); + +DUP_FN (8, int32_t); + +CONS2_FN (1, int32_t); + +CONS2_FN (2, int32_t); + +CONS2_FN (4, int32_t); + +CONS2_FN (8, int32_t); + +CONS2_FN (16, int32_t); + +CONS4_FN (1, int32_t); + +CONS4_FN (2, int32_t); + +CONS4_FN (4, int32_t); + +CONS4_FN (8, int32_t); + +/* { dg-final { scan-assembler-times "th.swd\t" 68 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 10 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 90 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-19.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-19.c new file mode 100644 index 00000000000..803619291eb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-19.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +#include "xtheadmempair-helper.h" +#include + +CONST_FN (2, int64_t, 0); +/* "th.sdd\t" 1 target: rv64 */ +/* "th.swd\t" 2 target: rv32 */ + +CONST_FN (4, int64_t, 0); +/* "th.sdd\t" 2 target: rv64 */ +/* "th.swd\t" 4 target: rv32 */ + +CONST_FN (8, int64_t, 0); +/* "th.sdd\t" 4 target: rv64 */ +/* "th.swd\t" 8 target: rv32 */ + +CONST_FN (16, int64_t, 0); +/* "th.sdd\t" 8 target: rv64 */ +/* "th.swd\t" 16 target: rv32 */ + +CONST_FN (2, int64_t, 1); +/* "th.sdd\t" 1 target: rv64 */ +/* "th.swd\t" 2 target: rv32 */ + +CONST_FN (4, int64_t, 1); +/* "th.sdd\t" 2 target: rv64 */ +/* "th.swd\t" 4 target: rv32 */ + +CONST_FN (8, int64_t, 1); +/* "th.sdd\t" 4 target: rv64 */ +/* "th.swd\t" 8 target: rv32 */ + +DUP_FN (2, int64_t); +/* "th.sdd\t" 1 target: rv64 */ +/* "th.swd\t" 2 target: rv32 */ + +DUP_FN (4, int64_t); +/* "th.sdd\t" 2 target: rv64 */ +/* "th.swd\t" 4 target: rv32 */ + +DUP_FN (8, int64_t); +/* "th.sdd\t" 4 target: rv64 */ +/* "th.swd\t" 8 target: rv32 */ + +CONS2_FN (1, int64_t); +/* "th.sdd\t" 1 target: rv64 */ +/* "th.swd\t" 2 target: rv32 */ + +CONS2_FN (2, int64_t); +/* "th.sdd\t" 2 target: rv64 */ +/* "th.swd\t" 4 target: rv32 */ + +CONS2_FN (4, int64_t); +/* "th.sdd\t" 4 target: rv64 */ +/* "th.swd\t" 8 target: rv32 */ + +CONS2_FN (8, int64_t); +/* "th.sdd\t" 8 target: rv64 */ +/* "th.swd\t" 16 target: rv32 */ + +CONS2_FN (16, int64_t); +/* "th.sdd\t" 16 target: rv64 */ +/* "th.swd\t" 32 target: rv32 */ + +CONS4_FN (1, int64_t); +/* "th.sdd\t" 2 target: rv64 */ +/* "th.swd\t" 4 target: rv32 */ + +CONS4_FN (2, int64_t); +/* "th.sdd\t" 4 target: rv64 */ +/* "th.swd\t" 8 target: rv32 */ + +CONS4_FN (4, int64_t); +/* "th.sdd\t" 8 target: rv64 */ +/* "th.swd\t" 16 target: rv32 */ + +CONS4_FN (8, int64_t); +/* "th.sdd\t" 16 target: rv64 */ +/* "th.swd\t" 32 target: rv32 */ + +/* { dg-final { scan-assembler-times "th.sdd\t" 90 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 180 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c new file mode 100644 index 00000000000..85e9ada91c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +#include + +#if __riscv_xlen == 32 + uint64_t a; + #define XLEN 32 +#else + __int128 a; + #define XLEN 64 +#endif + +void +foo (int e) +{ + a = 25 << 52 + 10 + e; + uint64_t c, d; + c = a >> XLEN; + d = a; +} + +/* { dg-final { scan-assembler-times "th.sdd\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 1 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-20.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-20.c new file mode 100644 index 00000000000..b50ada4e22e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-20.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +typedef struct +{ + int a, b, c, d, e; +} S; + +void foo (S *); + +void +test (int x) +{ + S s = { .a = x }; + foo (&s); +} + +/* { dg-final { scan-assembler-times "th.sdd\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 2 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c new file mode 100644 index 00000000000..73758c85458 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906 --param=sched-autopref-queue-depth=10" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906 --param=sched-autopref-queue-depth=10" { target { rv32 } } } */ + +int arr[4][4]; + +void +foo (int x, int y) +{ + arr[0][1] = x; + arr[1][0] = y; + arr[2][0] = x; + arr[1][1] = y; + arr[0][2] = x; + arr[0][3] = y; + arr[1][2] = x; + arr[2][1] = y; + arr[3][0] = x; + arr[3][1] = y; + arr[2][2] = x; + arr[1][3] = y; + arr[2][3] = x; + arr[3][2] = y; +} + +/* { dg-final { scan-assembler-times "addi\t" 5 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 7 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "addi\t" 5 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 7 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-4.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-4.c new file mode 100644 index 00000000000..c6ed5a830f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-4.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int x[4] = {-4,-5,6,7}; + +int +foo() +{ + int a,b,c,d; + + a = x[0]; + b = x[1]; + c = x[2]; + d = x[3]; + return a+b+c+d; +} + +/* { dg-final { scan-assembler-times "th.lwd\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-5.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-5.c new file mode 100644 index 00000000000..29015e09fac --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int x[4] = {-4,-5,6,7}; +int y[4]; + +unsigned int* +foo() +{ + y[0] = (unsigned int) x[0]; + y[2] = (unsigned int) x[1]; + y[1] = (unsigned int) x[2]; + y[3] = (unsigned int) x[3]; + return y; +} + +/* { dg-final { scan-assembler-times "th.lwud\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 2 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 2 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-6.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-6.c new file mode 100644 index 00000000000..906a4e29650 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-6.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int x[4] = {-4,-5,6,7}; + +int +foo() +{ + int a,b,c; + + a = x[0]; + b = x[1]; + c = x[2]; + return a+b+c; +} + +/* { dg-final { scan-assembler-times "th.lwd\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-7.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-7.c new file mode 100644 index 00000000000..d1ace43b285 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-7.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +int x[4] = {-4,-5,6,7}; +int y[4]; + +unsigned int* +foo() +{ + y[2] = (unsigned int) x[1]; + y[1] = (unsigned int) x[2]; + y[3] = (unsigned int) x[3]; + return y; +} + +/* { dg-final { scan-assembler-times "th.lwd\t" 1 } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 1 } } */ +/* { dg-final { scan-assembler-times "addi\t" 5 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "addi\t" 4 { target { rv32 } } } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-8.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-8.c new file mode 100644 index 00000000000..f0e775e06d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-8.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-funroll-loops"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +typedef int VINT32 __attribute__ ((vector_size((16)))); + +/* Note: When compiling for RV32, 321r.sched2 changes the ordering of some + loads/stores sequences (after the peephole passes), which disables these + optimization opportunities. */ + +void +memory_operation (void * __restrict src, void * __restrict dest, int num) +{ + VINT32 *vsrc = (VINT32 *) src; + VINT32 *vdest = (VINT32 *) dest; + int i; + + for (i = 0; i < num - 1; i += 2) + { + vdest[i] = vdest[i] + vsrc[i]; + vdest[i + 1] = vdest[i + 1] + vsrc[i + 1]; + } +} + +/* { dg-final { scan-assembler-times "th.lwd\t" 8 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 4 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 4 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-9.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-9.c new file mode 100644 index 00000000000..432c7d24fbc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-9.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906" { target { rv32 } } } */ + +#include + +struct S0 +{ + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; +} a; + +struct S2 +{ + uint64_t f0; + uint64_t f2; + struct S0 f3; +}; + +void +fn1 () +{ + struct S2 b = {0, 1, 7, 4073709551611, 4, 8, 7}; + a = b.f3; +} + +/* { dg-final { scan-assembler-times "addi\t" 4 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.ldd\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 2 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "addi\t" 8 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 2 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 3 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-helper.h b/gcc/testsuite/gcc.target/riscv/xtheadmempair-helper.h new file mode 100644 index 00000000000..ef139c6b940 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-helper.h @@ -0,0 +1,52 @@ +#ifndef __XTHEADMEMPAIR_HELPER_H +#define __XTHEADMEMPAIR_HELPER_H + +#define PRAGMA(X) _Pragma (#X) +#define UNROLL(COUNT) PRAGMA (GCC unroll (COUNT)) + +#define CONST_FN(COUNT, TYPE, VAL) \ + void \ + const_##COUNT##_##TYPE##_##VAL (TYPE *x) \ + { \ + UNROLL (COUNT) \ + for (int i = 0; i < COUNT; ++i) \ + x[i] = VAL; \ + } + +#define DUP_FN(COUNT, TYPE) \ + void \ + dup_##COUNT##_##TYPE (TYPE *x, TYPE val) \ + { \ + UNROLL (COUNT) \ + for (int i = 0; i < COUNT; ++i) \ + x[i] = val; \ + } + +#define CONS2_FN(COUNT, TYPE) \ + void \ + cons2_##COUNT##_##TYPE (TYPE *x, TYPE val0, TYPE val1) \ + { \ + UNROLL (COUNT) \ + for (int i = 0; i < COUNT * 2; i += 2) \ + { \ + x[i + 0] = val0; \ + x[i + 1] = val1; \ + } \ + } + +#define CONS4_FN(COUNT, TYPE) \ + void \ + cons4_##COUNT##_##TYPE (TYPE *x, TYPE val0, TYPE val1, \ + TYPE val2, TYPE val3) \ + { \ + UNROLL (COUNT) \ + for (int i = 0; i < COUNT * 4; i += 4) \ + { \ + x[i + 0] = val0; \ + x[i + 1] = val1; \ + x[i + 2] = val2; \ + x[i + 3] = val3; \ + } \ + } + +#endif /* __XTHEADMEMPAIR_HELPER_H */