From patchwork Fri Feb 24 05:51:17 2023 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: 65563 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 EEBCC385020A for ; Fri, 24 Feb 2023 05:52:01 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by sourceware.org (Postfix) with ESMTPS id 4BC17385842B for ; Fri, 24 Feb 2023 05:51:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4BC17385842B 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-wr1-x429.google.com with SMTP id 6so12376803wrb.11 for ; Thu, 23 Feb 2023 21:51:35 -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=47PGquQnSt5Sz2gp8dl5/XUjYlD5lSJB9f8vlAUtz8o=; b=CT6TIStmJdldffczFV6TEzGSFFK3ftGix7uuUp1W2C9sVHmjustjMqvzqtjuD3RBIY /N7c1U07IlRha+9cyesSFw1ZzS9JQqDLp2HLOLvQWxUipZ/QdmY3oZREQI8lczYT3Vt8 IuBcdu2SUnmY1RHk8hZ6em/Fyh5ZoC1UFKBc3pQWyOXq38xs60GzfXiRtyg3OtObdsqa tr7DI1klGdC9qRhUQPKqlfB+MU3ZW4B7HR2JJWq5P10HavGe0yBeZuvYL+tBNfNnwveD ZfNOoHH5A2m37meD1ebueYUTvm8E6IwjCvX9GSRyv6xFmrfvIcyctVthNjPFQOdzGAJj qI1g== 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=47PGquQnSt5Sz2gp8dl5/XUjYlD5lSJB9f8vlAUtz8o=; b=VIgUhmkn1b5nx6erSSGOo176kplWLfQwZM9PWMnZJBendF1hvhlYXwbm5ydSNvgkUU gvPfc3HM5nx+ju9EMqahyrZrjOSTUZqYj/p8R+WCj+zmvsi0njMPXo2XCLavcuUWleV6 2GBKPxzjkioaKeFwlbgiak+tyQRE30s5LcBhdZFdxpASUwF1us9IipU6KfwrOx99UJ/U P9779fQ2gawsMTAFL0Y36+/kvWGLtkFqf2JBPf/CVFkJoh/haXrN6qv5ZTSQoh84PuZS RQpo+rbohhYjhLe0tlGe5Tjh1aB4JJkP5PD1Q1H0Zud2+Zkchgi/24SAnW4A6eFwgX3h X0Vg== X-Gm-Message-State: AO0yUKW2wdvMbks6gxRZRbjBlYUKRbLWOR/SJQSzBSJDi3QiWg4KlAiY hanitiEInR/1fnw6BlO1hH0Yo/dSX63d0NuT X-Google-Smtp-Source: AK7set+t5fviiZ6ExUfdK3eMa0n63AA429ClBzfhp/HyA91j7yaAjGRw8G1B6mAjzof9pKXThw77ew== X-Received: by 2002:a5d:628f:0:b0:2c7:1c75:367a with SMTP id k15-20020a5d628f000000b002c71c75367amr1008655wru.37.1677217893212; Thu, 23 Feb 2023 21:51:33 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:32 -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 v3 01/11] riscv: Add basic XThead* vendor extension support Date: Fri, 24 Feb 2023 06:51:17 +0100 Message-Id: <20230224055127.2500953-2-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 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. (MASK_XTHEADBB): New. (MASK_XTHEADBS): New. (MASK_XTHEADCMO): New. (MASK_XTHEADCONDMOV): New. (MASK_XTHEADFMEMIDX): New. (MASK_XTHEADFMV): New. (MASK_XTHEADINT): New. (MASK_XTHEADMAC): New. (MASK_XTHEADMEMIDX): New. (MASK_XTHEADMEMPAIR): New. (MASK_XTHEADSYNC): New. (TARGET_XTHEADBA): New. (TARGET_XTHEADBB): New. (TARGET_XTHEADBS): New. (TARGET_XTHEADCMO): New. (TARGET_XTHEADCONDMOV): New. (TARGET_XTHEADFMEMIDX): New. (TARGET_XTHEADFMV): New. (TARGET_XTHEADINT): New. (TARGET_XTHEADMAC): New. (TARGET_XTHEADMEMIDX): New. (TARGET_XTHEADMEMPAIR): 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 ebc1ed7d7e4..ef221be1eb1 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} }; @@ -1248,6 +1261,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 ff398c0a2ae..cf0cd669be4 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 95535235354..ff1dd4ddd4f 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -235,6 +235,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 Fri Feb 24 05:51:18 2023 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: 65562 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 DBE1D384DD0A for ; Fri, 24 Feb 2023 05:52:00 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id 9E86D385843D for ; Fri, 24 Feb 2023 05:51:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9E86D385843D 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-wr1-x434.google.com with SMTP id l25so12374875wrb.3 for ; Thu, 23 Feb 2023 21:51:36 -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=xjushq5tTS5XKtNK3xf+e9l3IJCS2bVzXnngiaSnC/M=; b=XlpMgBw/ciFiBtZQwjGkzcuorcxCNCo6A8TdMiCt9tvHOqNsQa3LtiKnGEj1PM2vnF zTq6TpFeDnI96xIEQF9KuQILDumtohXOpUbdIPui6BZIEkp0iLXkYoiLpaDdujhp27vR cJBe1jjwFlbIHiFXc1mrLgRhO2KJbJ5jE58zvoT8FNCLpfJfj0Nr2Mgo9Pyw8oogmuqH EaOrRr4QXNh+/QYx6tiMZDsoTJHBM/I/Hq1J3xo9gWYkpS4b6J4d/qd8QJNatChH80in pG03rp+2jNDLKtPW7g9Vx1c6qtciD/uZANklk1sHcAgo2aGD1lzvNLdqo50QPRCFUu7d XqEg== 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=xjushq5tTS5XKtNK3xf+e9l3IJCS2bVzXnngiaSnC/M=; b=pnWx7vRHr5iSOv6die3JBTi2jlPTx2Q2wCx5VjL3LO6STcdZr2srn0bh4ieVEM2NSy St7HFXmdnDBnc8BGj+XiOQjLoFb5q4Xfvyn8DVO/stpew0UXYKTE5rx0c/5uF18yxSPl UDsg0CBha3Wyj29BU9O65m7JgeaOVRAb5Qlg6oOZzUxTDSK/TUyIMj6gyXeaYcLsN4Fh yqTqxdTCjGExaSBYJUKN7WLsXgDtBILueCJZUOoIQApXTXqN98lxqMJ5PK/VPjM/G34h +NgwOYjnE/QVbOPrwmEtUrhxepngkrc3J1JPLvUz1GkHdIhEWXRel58wPjECLWnocp3h 8Odg== X-Gm-Message-State: AO0yUKV+exZFOQGR5vHlerSUYFMNy3WuyxCSEP/BQjjjSM3Hpr8YkLg1 oHhx4LLvMiLvnmztOcth7TMaiVANXvUtmcRQ X-Google-Smtp-Source: AK7set+dLCOX14/PxEvAjU0gDvuvTjtxgIGjRdyhwaRohiAPy2JKuOO6/kMrxtxTNMZm6IChh8sTGw== X-Received: by 2002:adf:fc12:0:b0:2c3:e20b:82aa with SMTP id i18-20020adffc12000000b002c3e20b82aamr13571771wrr.22.1677217894843; Thu, 23 Feb 2023 21:51:34 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:34 -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 v3 02/11] riscv: riscv-cores.def: Add T-Head XuanTie C906 Date: Fri, 24 Feb 2023 06:51:18 +0100 Message-Id: <20230224055127.2500953-3-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-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_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 2a834cae21d..7d87ab7ce28 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 Fri Feb 24 05:51:19 2023 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: 65567 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 A6F073881D06 for ; Fri, 24 Feb 2023 05:52:40 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id 62D563858284 for ; Fri, 24 Feb 2023 05:51:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 62D563858284 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-wr1-x435.google.com with SMTP id j2so12598894wrh.9 for ; Thu, 23 Feb 2023 21:51:37 -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=mLY2KBcxNirQKo1ZMJ0EbmdYwsXhqkpZtLZaeqQmVFQ=; b=FtQOgZ/fAnSliqEEHfmc5fvdiELFHPRvbBTrEP054oUsXQaA8Jm12Rm4SA57L1oA0u xv5E8m0QdkphAfPNDbbFB6vO04OMqVHU7+R0dzJscljXI/n7sJx6ZfX5tOOHUzVGxyW8 F1rCwEsECUXFV8f60zx0kdgfj7ReYbaUjG9TdCD7xtLJ6IumeL9lV7XRCjN/FYZyUSHz uGM/bAPrskfpGc/Rf+ym/Gtqq0wdmCdzawYgUmOgET3E2tnQ9kS8wHFcXV5Wr/gszzAp Hy4BiJ7jBCfCG3fhlklUmc6PTLwbNf82ihuPVFyXT/VhoZrcZr0Hq/Hgy3x6hvaU9m3B VzQw== 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=mLY2KBcxNirQKo1ZMJ0EbmdYwsXhqkpZtLZaeqQmVFQ=; b=TMvvUTX6glekuV0BobvWG5uYh97wp3hBkaB/zVogVtavaQ+G0coOVJsCtRnVbJvRA/ snUKSop0NVrUr7UlJLeIjjtwmRnRcIZMQEIC+kbUCIW3E8d7TaRJW1rGBVOxLrVwSUvV /LEAZvGbez0VkbM/mq5dUs2e6ejZvrXylj1zPPrf1BH9VbnoGKqvjuzzIcorxU5DP/mN 8iEXcXQrPp6TyMwyTvJ22Rckv1FHKEZ3Wur9ZGgITa8t0pbJsSgy+eGhcUh57FIoSFwa iuGrOOtfEUbzN32js9RdJlyPwcFZWIztLvWasjVxjXtMUKmaQiPzUsOXD7Ioej6uhckC s8fg== X-Gm-Message-State: AO0yUKXLL43zLNAxxEgEhu6tT5RHA2BCi+Ytr4LsPkNRiOCmKJEj64pq v4XfiKQ/7jHyVzemCc14kRa7/xVlv8UTx3L7 X-Google-Smtp-Source: AK7set+98D9UdN3gtwP6ehU/wo+BnKf+8xNJnyZbwBGY+LNeDgJ6ccTbRsu8JfIzGRHohiOYhNIrZw== X-Received: by 2002:a5d:51ca:0:b0:2c7:1159:ea43 with SMTP id n10-20020a5d51ca000000b002c71159ea43mr4031389wrv.51.1677217896430; Thu, 23 Feb 2023 21:51:36 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:35 -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 v3 03/11] riscv: thead: Add support for the XTheadBa ISA extension Date: Fri, 24 Feb 2023 06:51:19 +0100 Message-Id: <20230224055127.2500953-4-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 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. Changes in v3: - Fix operand order for th.addsl. 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 05924e9bbf1..d6c2265e9d4 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3093,4 +3093,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..158e9124c3a --- /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,%3,%1,%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 Fri Feb 24 05:51:20 2023 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: 65561 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 58140384FB7A for ; Fri, 24 Feb 2023 05:51:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id 99717385B501 for ; Fri, 24 Feb 2023 05:51:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 99717385B501 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-wr1-x42c.google.com with SMTP id j2so12598934wrh.9 for ; Thu, 23 Feb 2023 21:51:39 -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=GYXOlOd7Q7luwkWUh38lFwuKiDMWoPJh8wz/t8z+iYE=; b=GcfvF0N7tu20YHtZ+8ya67SFTPa84xMTWqiZWFo8lxeNrbsICQYdGt9zzRA7HpqniS 863tUV2tY2W+RPn/Bk8GDpn0FqSyTh4OHz+a1iXcK6IzaNu+Gzd3o42ghSl3BbFOQL2m dTPlbb2nZRU+7tG+dq7ftLNDGGGmL/kHZpuYd6Ic5yRQuDLQ1KGatcch+imC8cUFPbo4 Xdx6/NedxKN5wc73+NH2ETCMvG/G2LjqWlgmmvJpthCRiANLilIlCWnG9rzFmhZF9UvN 3qgD15MdNoHPyt4UgGs+8JSrQ77ZNZVpAmi11KO3aPdM/6V1nMTnGiX6dWaGz0TFbrbN lm/w== 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=GYXOlOd7Q7luwkWUh38lFwuKiDMWoPJh8wz/t8z+iYE=; b=VAFpXUR7U5hW/N4uCyTTlCqXmzBMIz++afCib8rsppg2XRYDhPm0hhDJXOsp1rwc/4 gLGQahxe0IVBr3Vbigy4DyLTlQuPuiWHAl1krD0spuoGUo70SHaRWdqTvBNN+AMoZElb 7H0VoiZsvZzgZaE/TuZl/GcLiDVJbcdtiJdGqep+O/AO5dDaVHxAur4FPX3Rzs1zVBzD fOsI0GkTmllpOgOlFpu4ydY58RqPyu0EnFQqgFF386ooTz1lOYtxYioDSEdXtT7OerZJ sxIQB5ZMBSpNKWW4NrZisEQeAu4Vet3BfHbuqz/G92Bfw8KHUUOZlDJexXWvegY327W1 sptA== X-Gm-Message-State: AO0yUKUEFtfSFGwZ9G5FIFw5VA+y2iZIttKyoitfGu5cdscXc02npsUX VIXRi4d+lRRaMCOcCg7CveScSZIyYp3gizqg X-Google-Smtp-Source: AK7set//MFFTFp1/YRQaULD2vq7os1BQej0MrJXaKckwCL+y1Tg5nU+sIT1d6XbpJ8M0WppQNCAD+A== X-Received: by 2002:a05:6000:170a:b0:2c5:4c9d:2dab with SMTP id n10-20020a056000170a00b002c54c9d2dabmr10899588wrc.10.1677217898020; Thu, 23 Feb 2023 21:51:38 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:37 -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 v3 04/11] riscv: thead: Add support for the XTheadBs ISA extension Date: Fri, 24 Feb 2023 06:51:20 +0100 Message-Id: <20230224055127.2500953-5-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 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 f11b7949a49..e35bc0a745b 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 158e9124c3a..2c684885850 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,%3,%1,%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 Fri Feb 24 05:51:21 2023 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: 65565 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 101E53850202 for ; Fri, 24 Feb 2023 05:52:36 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id 65E0838515DD for ; Fri, 24 Feb 2023 05:51:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 65E0838515DD 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-wr1-x42b.google.com with SMTP id bw19so2145659wrb.13 for ; Thu, 23 Feb 2023 21:51:41 -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=3VX4pVVhHchcWFFSO1SlLA3pPQUaI3q+1GiHbyTnfFM=; b=Bx0VIEpNwzDvWC6ea0lWy3SxwLubtdj0eiSATDPao9CNlowZb8W12YNv6WareZ9h9r QGaltQ3HN17s6H80MQZ2fsulQrtqAS8F+p50Datq4nIg8Cy7qnx97E/KSKIxIpwlT89s n8J2lJi++PTsSrTmltETLvms/EdWuReJGZlxPMcyLTkwSmpFchopirfGnRBhIbT7T0ZI JJmBgfHA79cGDDG8PDX/hVBapRLlJ5CS0KcN1hMTgVrulTeovcIvfcxXz+b/K5XA57m+ KiZKiPhbZWxLqFbKR118NhpfTBdCIrQI3ATOUwLJ2KvsXVUY22efIDHTj7I1LMlcd6RP LfpQ== 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=3VX4pVVhHchcWFFSO1SlLA3pPQUaI3q+1GiHbyTnfFM=; b=hKgtocDlA1YBnULWjR/pm0v+oXPLdjnw24PyWmO/nZxIGfPO3t1WeIEbeyl1IDA4IE uDZD7Pecu1X6/KYQIgSqiO1gFaPKj+0HmStETwRHdSX4n9fhzHQMAUpol1ZsIuH+p466 tUBRiSvZSIk/BJPiOkCnwQ8cJEVSehURNE8whsfadJlOJszcWazFYmEw0P/R45o8dIQ0 ndF+ZC0MRnrQCNuBDyuBBqYVRSYs/r6NQ4lTwepcESD9AVpj7gjicn8VXqpuJYxrJ8nW d0xQq4qH/WpfYAJ6xgSB025/XSeEDOoPzZG9vIiRG7YUYFBqMmjnGaDQqcJsR7ptwSvd 4XKA== X-Gm-Message-State: AO0yUKWx4LOb6Eg6MuwQz49Oko78nDv0m/zBOcBuukng0qE52FuZOvc0 420W/dbK2A7QMtuQmjd4dtERAbajlh+ueFzt X-Google-Smtp-Source: AK7set87O7ojZoSr6uPHf0Vg2ukU9jjcGzoR7mCidF5ZFHq8gjGtTHnJLnJvcGzBhFZx92WjnK3ylg== X-Received: by 2002:adf:f28e:0:b0:2c7:d9a:dd57 with SMTP id k14-20020adff28e000000b002c70d9add57mr5551818wro.25.1677217899597; Thu, 23 Feb 2023 21:51:39 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:38 -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 v3 05/11] riscv: thead: Add support for the XTheadBb ISA extension Date: Fri, 24 Feb 2023 06:51:21 +0100 Message-Id: <20230224055127.2500953-6-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 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 14d18edbe62..ca0c98ee686 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 e35bc0a745b..7613bae8024 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 d6c2265e9d4..fc8ce9f5226 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3087,6 +3087,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 2c684885850..79cdcbb553f 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 Fri Feb 24 05:51:22 2023 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: 65566 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 0A11A388981D for ; Fri, 24 Feb 2023 05:52:40 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by sourceware.org (Postfix) with ESMTPS id D9DDD3850840 for ; Fri, 24 Feb 2023 05:51:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D9DDD3850840 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-wr1-x432.google.com with SMTP id t15so12886978wrz.7 for ; Thu, 23 Feb 2023 21:51:42 -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=neGqU2ePHguCX2jZ366/MECOKhalCS73CIZ1khVrUpI=; b=FKaT6bnoEDh1ZsZF6biL9H/xLsHav7rgX29JuUHVXRjrG5TFSn+KGPsWngLRghWb9T HDc7eOQqkS643PNa+AwVeEQt8qCBub5D00CI1JAxUJt81kGlGmeuuns6THn3qsPNpr3U LEXNkW2iWXO7bzwai3VShamcrEbP+rUVR4WdCauBPW4WHhzFkoIofhgFzE5qmlNeMmfn oNAFo0HfLiQUzjeehWMKu7dMCEJ7BCPIHzBH8P4HZkB/upkHpK8Gpuv23efDa6RuKNDz UnalS8SkJTX7RqkwDHefqI1LL7BS+BnqlMWEr+zGSlM+5l7cBBtTfFkqYHMXGHVCO9P6 sSfA== 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=neGqU2ePHguCX2jZ366/MECOKhalCS73CIZ1khVrUpI=; b=cpe8cDEG47NtpPXvabiGgHtr2kj2yn2gFieeRA0JJPJExrNPcbnstK/zpXlPcW1qYb CKoLpcix7WgUOHdQgYS+o1H5ikGRK+f3axzn8+ihYd47t+lWJEe7rc6PWalpMUOZnpnB aVdcLDca/DKySEJ8j2FysG+k5FOEu7q0/NWhz77oOv9P7qoPZOZbKANtGnIdhGkIvVqY CrWE0DNYmD8mszX6ZnodJO1mKsfuM2pnWHwkwDz14FgwY6mUvoP8/q1+kJ/ExG8BsJKV 4MgiOzfAdk9K2XGJ2fVzXRrsfg/B2b6WNmmHp1QNZmuRcmEbuGYwQOtJpL5/FktU2C0h 2EJQ== X-Gm-Message-State: AO0yUKW2rgU//w/N0PhtfrmQHx5GFX3a/qN8rKqwGV3zBPje6RHqNcW5 UmK1VOIaarIeTQT+KDbeae5iwd1O7TQ/PPIF X-Google-Smtp-Source: AK7set85/WvVv08TxVJawCZkOXbBstGIHgval8cgScJShbxwNIL1aqjHnciiutHdjJd4AAHS0YXrTg== X-Received: by 2002:a5d:58c1:0:b0:2c5:52ef:3ff8 with SMTP id o1-20020a5d58c1000000b002c552ef3ff8mr13409398wrf.31.1677217901190; Thu, 23 Feb 2023 21:51:41 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:40 -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 v3 06/11] riscv: thead: Add support for the XTheadCondMov ISA extensions Date: Fri, 24 Feb 2023 06:51:22 +0100 Message-Id: <20230224055127.2500953-7-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 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 5b70ab20758..9b767038452 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 37c634eca1d..5cf4fafd662 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 7613bae8024..a60ab2c7fad 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 fc8ce9f5226..5562e5621fa 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 @@ -335,7 +336,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,viminmax, vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov, @@ -2308,17 +2309,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 79cdcbb553f..ae5a65e9a7e 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 Fri Feb 24 05:51:23 2023 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: 65564 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 7EBBE383EC75 for ; Fri, 24 Feb 2023 05:52:33 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 721F03850211 for ; Fri, 24 Feb 2023 05:51:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 721F03850211 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-wm1-x332.google.com with SMTP id t25-20020a1c7719000000b003eb052cc5ccso881081wmi.4 for ; Thu, 23 Feb 2023 21:51:44 -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=Wi4nrN3+eIenkmP/IJDG3CMc8Fo7c5rhuKMVXtZVN8c=; b=iiC4AryuvD0Xz9GHRYy7llSg5g4PMrFowclxWMUI9JD3AOuPk/cWYb1QnCbPiZlD4k u79gKxY51LPMqJ8mDj6+Aig2gs3l5xHyrmuRhj/bmyWGNzFdcQz92CXDayRdBXSCaLVL QS0W4fs3HdvIaXV53lusve79KZx4ZvC9Sc0ZbIASoA2PiK6d/9uS5x8bfa+6bIXBUFOW fRe80HK3JyA47YB9MFGLteZ6FoKMP6xb2MlkGSIYb8mxhMnkrTDZ4JJBqoZKzq85ayxW pJNOGhjucgNhx00UqNIT+qabV0PG2KUS1K41+SbaCOINOFZHI/u5qqkyrsSNHyvoxf9U 7SpA== 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=Wi4nrN3+eIenkmP/IJDG3CMc8Fo7c5rhuKMVXtZVN8c=; b=nktUAisCoctZ794XXz62E9+3YzxuCY7zmOJBNMezARWEbmvQ7i3GPhg2jgRgrLWeNx M7XJx+mGq0g1VexV698M2zVK1kisAgCFN6B1WuPeQN3PXnoLoM+xPdz9x3EUDUwWroCD njJvzgyz7DsMkiLxZDZXVWMkAmi09tlF3gSKHb3bQ29ZGJlm8sw+J0bwlONwfDOV8I3U eJ/nhxc5amJ1L6udk+c1fYbR8u3kaoAGdCRHn84LA0BpKjU+e0FGI/ebPhshbtWNvr9W LG0fgaUVdC50llEAKhrgpFSOgfgajLaItaUVUx6en2H9mgu45LbOR+NtVX04YIpUrI0t Hp9Q== X-Gm-Message-State: AO0yUKXYuYU5Zrx66Y0IHA1MxSSk0236UsW2FDBA/V0Z1ccO2f4HCi3e N3dr59BVo2GQw+lKwWSYPFpR2xeLiIMu3dky X-Google-Smtp-Source: AK7set+JzXhg5i406WxXIgG0xBjCyJf2OymNuSx8q6VDybgrJ+2Q64gta9/RkkCNBIH7RkvDE1Ze1g== X-Received: by 2002:a05:600c:329d:b0:3eb:1068:533c with SMTP id t29-20020a05600c329d00b003eb1068533cmr667732wmp.25.1677217902594; Thu, 23 Feb 2023 21:51:42 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51: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 v3 07/11] riscv: thead: Add support for the XTheadMac ISA extension Date: Fri, 24 Feb 2023 06:51:23 +0100 Message-Id: <20230224055127.2500953-8-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 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 5562e5621fa..112c93f733e 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3106,6 +3106,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 ae5a65e9a7e..f616035e5a5 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 Fri Feb 24 05:51:24 2023 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: 65569 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 1FAF33893679 for ; Fri, 24 Feb 2023 05:53:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by sourceware.org (Postfix) with ESMTPS id 48ABF384FB54 for ; Fri, 24 Feb 2023 05:51:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 48ABF384FB54 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-wr1-x429.google.com with SMTP id l1so12493873wry.10 for ; Thu, 23 Feb 2023 21:51: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=tNGsfRbOLlOh+8fQKg5MADitEsEILqXjwWnweTGrpA4=; b=ePaoA+rvXeiGmGoSruIir5GKNtdw6+73Zas7O7YozbamrvGchllpqRmZR+lU7c9TBE YC8xa91CQvsvwnvLrHAMZmH9NLhSWa0PpjaYWmewUWvzN3DS/c5KR1ILTJtEh/X6cITL 1VCeOgXY0LDhSPWiVWFtY8m0pb0YGLiLj7X5WcrmKtLT7MqHseWYKpXWrU6VyuWT3aqV ISnGNgIrqdkGyALs4KLphH+A2IC34ZlGY6PsgM/AY7SbRdzLOMUcRrkHS1PJySnDBoBT BeqpxfeoNhtSl3MvsFCHEcoOViSaaE8n0yAXmNOc1xFFs0FHmEpX7HsKXayC35yMh8gt dscQ== 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=tNGsfRbOLlOh+8fQKg5MADitEsEILqXjwWnweTGrpA4=; b=AwYTF9P+8tf7VHXrmF2ioWk/6fN1hO8tZZ+nA9a+SEiiJlikeqcvFuraMTa8qUJ/L3 O1xad683RpcVeCc28ooPcJVBO5OxVAwN0lrr7BEzQuyZTa2j8nsAfXMgCii3VaSA0PVT 0ZqN4FaucqMbP/UvQ3sEbg63e2R2CllWm20n1p4giINOOf4gT890FvHqu6O/nOD6/Uow EQvlQtbeI22QwO21rO2LHWO0KSFfB+Y3ACmRI1CkBaWQAZ6ixwdSh50yWxkSH3gmdo2y mKuP/nHV8rbVeLsgeW5PUigaGUwilU2h04Xd7CB7K284ZnxoQYPpTCGbPmjZSg6uo5dO 6hVw== X-Gm-Message-State: AO0yUKWyImB83CiiBiP4c0h5+V032LXMB7NW+5//ECLcL2OgVcngoVQH MBU/zVCxjZo+Uv/MKlE2m3HpLJem2e2teY8D X-Google-Smtp-Source: AK7set/pakKqK4Smi2hspd2K/7IU48B3rWGWsfylVrUhfhmYy8rv3G2xxqPTj2kcZGi6NwokluHwkg== X-Received: by 2002:adf:fc43:0:b0:2c7:15b6:15b8 with SMTP id e3-20020adffc43000000b002c715b615b8mr3229773wrs.10.1677217904215; Thu, 23 Feb 2023 21:51: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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:43 -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 v3 08/11] riscv: thead: Add support for the XTheadFmv ISA extension Date: Fri, 24 Feb 2023 06:51:24 +0100 Message-Id: <20230224055127.2500953-9-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 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 a051d466ae2..e49019d8fa9 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -166,3 +166,11 @@ (define_memory_constraint "Wdm" "Vector duplicate memory operand" (and (match_code "mem") (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 a60ab2c7fad..48f2cb399ae 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)); @@ -5802,7 +5820,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 112c93f733e..61f175bb62b 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 @@ -1856,16 +1860,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 f616035e5a5..6ec3613071f 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 Fri Feb 24 05:51:25 2023 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: 65570 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 8564B383F978 for ; Fri, 24 Feb 2023 05:53:37 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by sourceware.org (Postfix) with ESMTPS id 05DE0385B51F for ; Fri, 24 Feb 2023 05:51:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 05DE0385B51F 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-wr1-x431.google.com with SMTP id c12so12781364wrw.1 for ; Thu, 23 Feb 2023 21:51: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=YEuTMuCb/CjW0QYE3hxnNAy8qTY++T4lHkDGNYSdRtY=; b=fBXQmch0lhBvGAgv4v4T1Tnb6fu/Z1SIycvAPtwWtGEzXeVYjniLgJeSBtNkjuEAxu b1Gq4NCCW9M/rjSI0WK71Pd9QTw+WnuInyYLlyGtN5XY00qIIxhuzL1oSHhyxFvft1JV DVk2I5QuljSfayE6SJKDn10kdk+G1RbDRQpDAQgdoLYy6autu+iMqoGuOo7YeivohNKJ JsgMAyylN8zKhhPcJqkBK6SkZCFH/i3MNbkLyE9IX1d/4esi7esB8KX4A2kqk9ot0ynz Gfdpd2f+Xu92VluKD4xbAcpSdvHG9jm8Mm/KqrdmoFUZcKjesSGZWhmCOT07poHmz0tP +dlA== 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=YEuTMuCb/CjW0QYE3hxnNAy8qTY++T4lHkDGNYSdRtY=; b=QVZKgT0g2ON1pFqfwNRF1l1ov7EB1yGU/jOLrk2ueX2cDYmgXAvgiBN38dCSgAU94O L0JlFTPeiXKzrR+7wvKudtSSOABzvb+GEegzmwf7A7N8jqp80K1jG1IiVfeVQAmti2gK cLXuLzsZXrbEB4uDBdtQ9D7WZLFVbKBpetGOWmL0sgbW/CdxvRCYcaucS7Ek5O/JC/yg YpL6aB+dcr+9wYHo04Rfg5nqRzTVpkU6fImXGLM5OsPgtoQ1hHwDTIgwZcl9Howzz4u+ x99dZ9//8qGfRtjSxZi11FHrbYWJvNbibhnMbShD9sz7x3/T99TwNcfexcbCxDWPqZmx Fq6A== X-Gm-Message-State: AO0yUKU+ak3dWEMbEJeYUH0D/tbXMjd9WtuH50XWM9kryqzMLPvvrYyP s6K3cgoEkwpfe7FJbb0RzPat8Fy53/+yPqwZ X-Google-Smtp-Source: AK7set/Z6gfA7rjS/L5yCDrGCs3obWt47haFaQ21lczHAiMN50w7i18sscIBjEhQDZOqyPgwHqug9A== X-Received: by 2002:a5d:4692:0:b0:2c7:16c3:1756 with SMTP id u18-20020a5d4692000000b002c716c31756mr2848305wrq.61.1677217905896; Thu, 23 Feb 2023 21:51:45 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51: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 v3 09/11] riscv: thead: Add support for the XTheadMemPair ISA extension Date: Fri, 24 Feb 2023 06:51:25 +0100 Message-Id: <20230224055127.2500953-10-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 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: Christoph Müllner The XTheadMemPair ISA extension allows to pair two loads or stores: * th.ldd (2x LD) * th.lwd (2x LW) * th.lwud (2x LWU) * th.sdd (2x SD) * th.swd (2x SW) The displacement of these instructions is quite limited: * Displacement := imm2 << shamt * imm2 is a 2-bit unsigned value {0..3} * shamt is 4 for th.ldd/th.sdd and 3 otherwise But even with this small displacement we can identify many candidates. The merge of the two loads/stores is realized in form of peephole2 passes that support instruction reordering. The CFA expansion (save/restore registers on/from stack) is not processed by the peephole2 pass and, therefore, needs special-treatment. Many ideas of this patch are inspired by similar/equal approaches in other backends. gcc/ChangeLog: * config/riscv/peephole.md: New peephole passes for XTheadMemPair. * config/riscv/riscv-protos.h (thead_mempair_operands_p): New prototype. (thead_mempair_order_operands): Likewise. (thead_mempair_output_move): Likewise. * config/riscv/riscv.cc (extract_base_offset_in_addr): New function. (riscv_split_plus): New function. (thead_mempair_output_move): New function. (thead_mempair_check_consecutive_mems): New function. (thead_mempair_operand_p): New function. (thead_mempair_load_overlap_p): New function. (thead_mempair_operands_p): New function. (thead_mempair_order_operands): New function. (riscv_save_reg): Moved code. (th_mempair_save_reg): New function. (riscv_restore_reg): Moved code. (th_mempair_restore_reg): New function. (riscv_for_each_saved_reg): Add code to handle mempair instructions. * config/riscv/thead.md (*th_mempair_load_2): New pattern. (*th_mempair_store_2): Likewise. (*th_mempair_load_extendsidi2): Likewise. (*th_mempair_load_zero_extendsidi2): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadmempair-1.c: New test. * gcc.target/riscv/xtheadmempair-2.c: New test. * gcc.target/riscv/xtheadmempair-3.c: New test. Changes in v3: - Don't emit instructions during peephole2, but emit parallel INSNs - Add proper checks for the INSN patterns to avoid ICEs or illegal instructions reported by the assembler - Don't insert any `add` instructions - Rework the constraint handling - Simplify the output function - Restructure and simplify CFA processing - Add debug notes to CFA instructions - Emit parallel INSNs in the CFA code (same as peephole2) - Drop tests that target reordering - Drop tests that are irrelevant (e.g. unrolled loops) - Add tests for all possible displacements and all instructions - Add tests for CFA Signed-off-by: Christoph Müllner --- gcc/config/riscv/peephole.md | 56 +++ gcc/config/riscv/riscv-protos.h | 6 + gcc/config/riscv/riscv.cc | 450 ++++++++++++++++-- gcc/config/riscv/thead.md | 52 ++ .../gcc.target/riscv/xtheadmempair-1.c | 98 ++++ .../gcc.target/riscv/xtheadmempair-2.c | 84 ++++ .../gcc.target/riscv/xtheadmempair-3.c | 29 ++ 7 files changed, 746 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index 0ef0c04410b..ea696f3116c 100644 --- a/gcc/config/riscv/peephole.md +++ b/gcc/config/riscv/peephole.md @@ -38,3 +38,59 @@ (define_peephole2 { operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5])); }) + +;; XTheadMemPair: merge two SI or DI loads +(define_peephole2 + [(set (match_operand:GPR 0 "register_operand" "") + (match_operand:GPR 1 "memory_operand" "")) + (set (match_operand:GPR 2 "register_operand" "") + (match_operand:GPR 3 "memory_operand" ""))] + "TARGET_XTHEADMEMPAIR + && thead_mempair_operands_p (operands, true, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + thead_mempair_order_operands (operands, true, mode); +}) + +;; XTheadMemPair: merge two SI or DI stores +(define_peephole2 + [(set (match_operand:GPR 0 "memory_operand" "") + (match_operand:GPR 1 "register_operand" "")) + (set (match_operand:GPR 2 "memory_operand" "") + (match_operand:GPR 3 "register_operand" ""))] + "TARGET_XTHEADMEMPAIR + && thead_mempair_operands_p (operands, false, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + thead_mempair_order_operands (operands, false, mode); +}) + +;; XTheadMemPair: merge two SI loads with sign-extension +(define_peephole2 + [(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" "")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && thead_mempair_operands_p (operands, true, SImode)" + [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 1))) + (set (match_dup 2) (sign_extend:DI (match_dup 3)))])] +{ + thead_mempair_order_operands (operands, true, SImode); +}) + +;; XTheadMemPair: merge two SI loads with zero-extension +(define_peephole2 + [(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" "")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT + && thead_mempair_operands_p (operands, true, SImode)" + [(parallel [(set (match_dup 0) (zero_extend:DI (match_dup 1))) + (set (match_dup 2) (zero_extend:DI (match_dup 3)))])] +{ + thead_mempair_order_operands (operands, true, SImode); +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 5cf4fafd662..1b7ba02726d 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -54,7 +54,13 @@ 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 thead_mempair_operands_p (rtx[4], bool, machine_mode); +extern void thead_mempair_order_operands (rtx[4], bool, machine_mode); + #ifdef RTX_CODE +extern const char *thead_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE); + 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 48f2cb399ae..33854393bd2 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2943,6 +2943,332 @@ 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. */ + +static 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; + } +} + +/* Output a mempair instruction with the provided OPERANDS. + LOAD_P is true if a we have a pair of loads (stores otherwise). + MODE is the access mode (DI or SI). + CODE is the extension code (UNKNOWN, SIGN_EXTEND or ZERO_EXTEND). + This instruction does not handle invalid inputs gracefully, + but is full of assertions to ensure that only valid instructions + are emitted. */ + +const char * +thead_mempair_output_move (rtx operands[4], bool load_p, + machine_mode mode, RTX_CODE code) +{ + rtx reg1, reg2, mem1, mem2, base1, base2; + HOST_WIDE_INT offset1, offset2; + rtx output_operands[5]; + const char* format; + + gcc_assert (mode == SImode || mode == DImode); + + /* Paired 64-bit access instructions have a fixed shift amount of 4. + Paired 32-bit access instructions have a fixed shift amount of 3. */ + unsigned shamt = (mode == DImode) ? 4 : 3; + + if (load_p) + { + reg1 = copy_rtx (operands[0]); + reg2 = copy_rtx (operands[2]); + mem1 = copy_rtx (operands[1]); + mem2 = copy_rtx (operands[3]); + + if (mode == SImode) + if (code == ZERO_EXTEND) + format = "th.lwud\t%0, %1, (%2), %3, %4"; + else //SIGN_EXTEND or UNKNOWN + format = "th.lwd\t%0, %1, (%2), %3, %4"; + else + format = "th.ldd\t%0, %1, (%2), %3, %4"; + } + else + { + reg1 = copy_rtx (operands[1]); + reg2 = copy_rtx (operands[3]); + mem1 = copy_rtx (operands[0]); + mem2 = copy_rtx (operands[2]); + + if (mode == SImode) + format = "th.swd\t%z0, %z1, (%2), %3, %4"; + else + format = "th.sdd\t%z0, %z1, (%2), %3, %4"; + } + + riscv_split_plus (XEXP (mem1, 0), &base1, &offset1); + riscv_split_plus (XEXP (mem2, 0), &base2, &offset2); + gcc_assert (rtx_equal_p (base1, base2)); + auto size1 = MEM_SIZE (mem1); + auto size2 = MEM_SIZE (mem2); + gcc_assert (known_eq (size1, size2)); + gcc_assert (known_eq (offset1 + size1, offset2)); + + HOST_WIDE_INT imm2 = offset1 >> shamt; + + /* Make sure all mempair instruction constraints are met. */ + gcc_assert (imm2 >= 0 && imm2 < 4); + gcc_assert ((imm2 << shamt) == offset1); + gcc_assert (REG_P (reg1)); + gcc_assert (REG_P (reg2)); + gcc_assert (REG_P (base1)); + if (load_p) + { + gcc_assert (REGNO (reg1) != REGNO (reg2)); + gcc_assert (REGNO (reg1) != REGNO (base1)); + gcc_assert (REGNO (reg2) != REGNO (base1)); + } + + /* Output the mempair instruction. */ + 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, imm2); + output_operands[4] = gen_rtx_CONST_INT (mode, shamt); + output_asm_insn (format, output_operands); + + return ""; +} + +/* Analyse if a pair of loads/stores MEM1 and MEM2 with given MODE + are consecutive so they can be merged into a mempair instruction. + RESERVED will be set to true, if a reversal of the accesses is + required (false otherwise). Returns true if the accesses can be + merged (even if reversing is necessary) and false if not. */ + +static bool +thead_mempair_check_consecutive_mems (machine_mode mode, rtx *mem1, rtx *mem2, + bool *reversed) +{ + rtx base1, base2, offset1, offset2; + extract_base_offset_in_addr (*mem1, &base1, &offset1); + extract_base_offset_in_addr (*mem2, &base2, &offset2); + + /* Make sure both mems are in base+offset form. */ + if (!base1 || !base2) + return false; + + /* If both mems use the same base register, just check the offsets. */ + if (rtx_equal_p (base1, base2)) + { + auto size = GET_MODE_SIZE (mode); + + if (known_eq (UINTVAL (offset1) + size, UINTVAL (offset2))) + { + *reversed = false; + return true; + } + + if (known_eq (UINTVAL (offset2) + size, UINTVAL (offset1))) + { + *reversed = true; + return true; + } + + return false; + } + + return false; +} + +/* Check if the given MEM can be used to define the address of a mempair + instruction. */ + +static bool +thead_mempair_operand_p (rtx mem, machine_mode mode) +{ + if (!MEM_SIZE_KNOWN_P (mem)) + return false; + + /* Only DI or SI mempair instructions exist. */ + auto mem_sz = MEM_SIZE (mem); + auto mode_sz = GET_MODE_SIZE (mode); + if (!known_eq (mem_sz, mode_sz)) + return false; + + /* Paired 64-bit access instructions have a fixed shift amount of 4. + Paired 32-bit access instructions have a fixed shift amount of 3. */ + machine_mode mem_mode = GET_MODE (mem); + unsigned shamt = (mem_mode == DImode) ? 4 : 3; + + rtx base; + HOST_WIDE_INT offset; + riscv_split_plus (XEXP (mem, 0), &base, &offset); + HOST_WIDE_INT imm2 = offset >> shamt; + + if (imm2 < 0 || imm2 >= 4) + return false; + + if ((imm2 << shamt) != offset) + return false; + + return true; +} + +static bool +thead_mempair_load_overlap_p (rtx reg1, rtx reg2, rtx mem) +{ + if (REGNO (reg1) == REGNO (reg2)) + return true; + + if (reg_overlap_mentioned_p (reg1, mem)) + return true; + + rtx base; + HOST_WIDE_INT offset; + riscv_split_plus (XEXP (mem, 0), &base, &offset); + + if (!REG_P (base)) + return true; + + if (REG_P (base)) + { + if (REGNO (base) == REGNO (reg1) + || REGNO (base) == REGNO (reg2)) + return true; + } + + return false; +} + +/* Given OPERANDS of consecutive load/store, check if we can merge + them into load-pair or store-pair instructions. + LOAD is true if they are load instructions. + MODE is the mode of memory operation. */ + +bool +thead_mempair_operands_p (rtx operands[4], bool load_p, + machine_mode mode) +{ + rtx mem_1, mem_2, reg_1, reg_2; + + if (load_p) + { + reg_1 = operands[0]; + mem_1 = operands[1]; + reg_2 = operands[2]; + mem_2 = operands[3]; + if (!REG_P (reg_1) || !REG_P (reg_2)) + return false; + if (thead_mempair_load_overlap_p (reg_1, reg_2, mem_1)) + return false; + if (thead_mempair_load_overlap_p (reg_1, reg_2, mem_2)) + return false; + } + else + { + mem_1 = operands[0]; + reg_1 = operands[1]; + mem_2 = operands[2]; + reg_2 = operands[3]; + } + + /* Check if the registers are GP registers. */ + if (!REG_P (reg_1) || !GP_REG_P (REGNO (reg_1)) + || !REG_P (reg_2) || !GP_REG_P (REGNO (reg_2))) + return false; + + /* The mems cannot be volatile. */ + if (!MEM_P (mem_1) || !MEM_P (mem_2)) + return false; + if (MEM_VOLATILE_P (mem_1) || MEM_VOLATILE_P (mem_2)) + return false; + + /* If we have slow unaligned access, we only accept aligned memory. */ + if (riscv_slow_unaligned_access_p + && known_lt (MEM_ALIGN (mem_1), GET_MODE_SIZE (mode) * BITS_PER_UNIT)) + return false; + + /* Check if the addresses are in the form of [base+offset]. */ + bool reversed = false; + if (!thead_mempair_check_consecutive_mems (mode, &mem_1, &mem_2, &reversed)) + return false; + + /* The first memory accesses must be a mempair operand. */ + if ((!reversed && !thead_mempair_operand_p (mem_1, mode)) + || (reversed && !thead_mempair_operand_p (mem_2, mode))) + return false; + + /* The operands must be of the same size. */ + gcc_assert (known_eq (GET_MODE_SIZE (GET_MODE (mem_1)), + GET_MODE_SIZE (GET_MODE (mem_2)))); + + return true; +} + +/* Given OPERANDS of consecutive load/store that can be merged, + swap them if they are not in ascending order. + Return true if swap was performed. */ +void +thead_mempair_order_operands (rtx operands[4], bool load_p, machine_mode mode) +{ + int mem_op = load_p ? 1 : 0; + bool reversed = false; + if (!thead_mempair_check_consecutive_mems (mode, + operands + mem_op, + operands + mem_op + 2, + &reversed)) + gcc_unreachable (); + + if (reversed) + { + /* Irrespective of whether this is a load or a store, + we do the same swap. */ + std::swap (operands[0], operands[2]); + std::swap (operands[1], operands[3]); + } +} + const char * riscv_output_return () { @@ -4963,6 +5289,61 @@ 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)); +} + +/* Save register 2x REG to MEM. Make the instruction frame-related. */ + +static void +th_mempair_save_reg (rtx operands[4]) +{ + rtx set1 = gen_rtx_SET (operands[0], operands[1]); + rtx set2 = gen_rtx_SET (operands[2], operands[3]); + rtx insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set1, set2))); + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set1)); + add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set2)); +} + +/* 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; +} + +/* Restore register 2x REG from MEM. Make the instruction frame-related. */ + +static void +th_mempair_restore_reg (rtx operands[4]) +{ + rtx set1 = gen_rtx_SET (operands[0], operands[1]); + rtx set2 = gen_rtx_SET (operands[2], operands[3]); + rtx insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set1, set2))); + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_RESTORE, operands[0]); + add_reg_note (insn, REG_CFA_RESTORE, operands[2]); +} + /* 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); @@ -5057,6 +5438,46 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, && riscv_is_eh_return_data_register (regno)) continue; + if (TARGET_XTHEADMEMPAIR) + { + /* Get the next reg/offset pair. */ + HOST_WIDE_INT offset2 = offset; + unsigned int regno2 = riscv_next_saved_reg (regno, limit, &offset2); + + /* Prepare the operands for a mempair instruction. */ + bool load_p = (fn == riscv_restore_reg); + int reg_op = load_p ? 0 : 1; + int mem_op = load_p ? 1 : 0; + rtx operands[4]; + operands[reg_op] = gen_rtx_REG (word_mode, regno); + rtx mem1 = plus_constant (word_mode, stack_pointer_rtx, offset); + mem1 = gen_frame_mem (word_mode, mem1); + operands[mem_op] = mem1; + operands[2 + reg_op] = gen_rtx_REG (word_mode, regno2); + rtx mem2 = plus_constant (word_mode, stack_pointer_rtx, offset2); + mem2 = gen_frame_mem (word_mode, mem2); + operands[2 + mem_op] = mem2; + + /* Validate everything before emitting a mempair instruction. */ + if (regno2 != INVALID_REGNUM + && !cfun->machine->reg_is_wrapped_separately[regno2] + && !(epilogue && !maybe_eh_return + && riscv_is_eh_return_data_register (regno2)) + && thead_mempair_operands_p (operands, load_p, word_mode)) + { + thead_mempair_order_operands (operands, load_p, word_mode); + + if (load_p) + th_mempair_restore_reg (operands); + else + th_mempair_save_reg (operands); + + offset = offset2; + regno = regno2; + continue; + } + } + riscv_save_restore_reg (word_mode, regno, offset, fn); } @@ -5075,35 +5496,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 6ec3613071f..cbfe51cbd85 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -297,3 +297,55 @@ (define_insn "*th_sextw_msubhisi4" [(set_attr "type" "imul") (set_attr "mode" "SI")] ) + +;; XTheadMemPair + +;; MEMPAIR load 64/32 bit +(define_insn "*th_mempair_load_2" + [(set (match_operand:GPR 0 "register_operand" "=r") + (match_operand:GPR 1 "memory_operand" "m")) + (set (match_operand:GPR 2 "register_operand" "=r") + (match_operand:GPR 3 "memory_operand" "m"))] + "TARGET_XTHEADMEMPAIR && reload_completed + && thead_mempair_operands_p (operands, true, mode)" + { return thead_mempair_output_move (operands, true, mode, UNKNOWN); } + [(set_attr "move_type" "load") + (set_attr "mode" "")]) + +;; MEMPAIR store 64/32 bit +(define_insn "*th_mempair_store_2" + [(set (match_operand:GPR 0 "memory_operand" "=m") + (match_operand:GPR 1 "register_operand" "r")) + (set (match_operand:GPR 2 "memory_operand" "=m") + (match_operand:GPR 3 "register_operand" "r"))] + "TARGET_XTHEADMEMPAIR && reload_completed + && thead_mempair_operands_p (operands, false, mode)" + { return thead_mempair_output_move (operands, false, mode, UNKNOWN); } + [(set_attr "move_type" "store") + (set_attr "mode" "")]) + +;; MEMPAIR load DI extended signed SI +(define_insn "*th_mempair_load_extendsidi2" + [(set (match_operand 0 "register_operand" "=r") + (sign_extend:DI (match_operand 1 "memory_operand" "m"))) + (set (match_operand 2 "register_operand" "=r") + (sign_extend:DI (match_operand 3 "memory_operand" "m")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT && reload_completed + && thead_mempair_operands_p (operands, true, SImode)" + { return thead_mempair_output_move (operands, true, SImode, SIGN_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "DI") + (set_attr "length" "8")]) + +;; MEMPAIR load DI extended unsigned SI +(define_insn "*th_mempair_load_zero_extendsidi2" + [(set (match_operand 0 "register_operand" "=r") + (zero_extend:DI (match_operand 1 "memory_operand" "m"))) + (set (match_operand 2 "register_operand" "=r") + (zero_extend:DI (match_operand 3 "memory_operand" "m")))] + "TARGET_XTHEADMEMPAIR && TARGET_64BIT && reload_completed + && thead_mempair_operands_p (operands, true, SImode)" + { return thead_mempair_output_move (operands, true, SImode, ZERO_EXTEND); } + [(set_attr "move_type" "load") + (set_attr "mode" "DI") + (set_attr "length" "8")]) 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..c324555fd35 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-1.c @@ -0,0 +1,98 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */ +/* { 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 +typedef uint32_t xlen_t; +#else +typedef uint64_t xlen_t; +#endif + +void foof (xlen_t*, xlen_t, xlen_t); +void foor (xlen_t*, xlen_t, xlen_t); +void foowu (uint32_t*, uint64_t, uint64_t); +void foows (int32_t*, int64_t, int64_t); + +#define LxD_TEST(f, T, i1, i2) \ +void \ +f ## i1 ## i2(T *arr) \ +{ \ + foo ## f(arr, arr[i1], arr[i2]); \ +} + +// works +LxD_TEST(f, xlen_t, 0, 1) +// does not work (can't merge with unaligned offset) +LxD_TEST(f, xlen_t, 1, 2) +// works +LxD_TEST(f, xlen_t, 2, 3) +// does not work (can't merge with unaligned offset) +LxD_TEST(f, xlen_t, 3, 4) +// works +LxD_TEST(f, xlen_t, 4, 5) +// does not work (can't merge with unaligned offset) +LxD_TEST(f, xlen_t, 5, 6) +// works +LxD_TEST(f, xlen_t, 6, 7) +// does not work (can't merge with unaligned offset) +LxD_TEST(f, xlen_t, 7, 8) +// does not work (out of range) +LxD_TEST(f, xlen_t, 8, 9) + +// works with reordering +LxD_TEST(r, xlen_t, 1, 0) +// does not work (can't merge with unaligned offset) +LxD_TEST(r, xlen_t, 2, 1) +// works with reordering +LxD_TEST(r, xlen_t, 3, 2) +// does not work (can't merge with unaligned offset) +LxD_TEST(r, xlen_t, 4, 3) +// works with reordering +LxD_TEST(r, xlen_t, 5, 4) +// does not work (can't merge with unaligned offset) +LxD_TEST(r, xlen_t, 6, 5) +// works with reordering +LxD_TEST(r, xlen_t, 7, 6) +// does not work (can't merge with unaligned offset) +LxD_TEST(r, xlen_t, 8, 7) +// does not work (out of range) +LxD_TEST(r, xlen_t, 9, 8) + +#if __riscv_xlen != 32 +// works +LxD_TEST(wu, uint32_t, 0, 1) +LxD_TEST(ws, int32_t, 0, 1) +// does not work (can't merge with unaligned offset) +LxD_TEST(wu, uint32_t, 1, 2) +LxD_TEST(ws, int32_t, 1, 2) +// works +LxD_TEST(wu, uint32_t, 2, 3) +LxD_TEST(ws, int32_t, 2, 3) +// does not work (can't merge with unaligned offset) +LxD_TEST(wu, uint32_t, 3, 4) +LxD_TEST(ws, int32_t, 3, 4) +// works +LxD_TEST(wu, uint32_t, 4, 5) +LxD_TEST(ws, int32_t, 4, 5) +// does not work (can't merge with unaligned offset) +LxD_TEST(wu, uint32_t, 5, 6) +LxD_TEST(ws, int32_t, 5, 6) +// works +LxD_TEST(wu, uint32_t, 6, 7) +LxD_TEST(ws, int32_t, 6, 7) +// does not work (can't merge with unaligned offset) +LxD_TEST(wu, uint32_t, 7, 8) +LxD_TEST(ws, int32_t, 7, 8) +// does not work (out of range) +LxD_TEST(wu, uint32_t, 8, 9) +LxD_TEST(ws, int32_t, 8, 9) +#endif + +/* { dg-final { scan-assembler-times "th.ldd\t" 8 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.luwd\t" 4 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.lwd\t" 4 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "th.lwd\t" 8 { 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..ed639709196 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-2.c @@ -0,0 +1,84 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */ +/* { 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 +typedef uint32_t xlen_t; +#else +typedef uint64_t xlen_t; +#endif + +#define SxD_TEST(f, T, i1, i2) \ +void \ +f ## i1 ## i2(T *arr, T x, T y) \ +{ \ + arr[i1] = x; \ + arr[i2] = y; \ +} + +// works +SxD_TEST(f, xlen_t, 0, 1) +// does not work (can't merge with unaligned offset) +SxD_TEST(f, xlen_t, 1, 2) +// works +SxD_TEST(f, xlen_t, 2, 3) +// does not work (can't merge with unaligned offset) +SxD_TEST(f, xlen_t, 3, 4) +// works +SxD_TEST(f, xlen_t, 4, 5) +// does not work (can't merge with unaligned offset) +SxD_TEST(f, xlen_t, 5, 6) +// works +SxD_TEST(f, xlen_t, 6, 7) +// does not work (can't merge with unaligned offset) +SxD_TEST(f, xlen_t, 7, 8) +// does not work (out of range) +SxD_TEST(f, xlen_t, 8, 9) + +// works with reordering +SxD_TEST(r, xlen_t, 1, 0) +// does not work (can't merge with unaligned offset) +SxD_TEST(r, xlen_t, 2, 1) +// works with reordering +SxD_TEST(r, xlen_t, 3, 2) +// does not work (can't merge with unaligned offset) +SxD_TEST(r, xlen_t, 4, 3) +// works with reordering +SxD_TEST(r, xlen_t, 5, 4) +// does not work (can't merge with unaligned offset) +SxD_TEST(r, xlen_t, 6, 5) +// works with reordering +SxD_TEST(r, xlen_t, 7, 6) +// does not work (can't merge with unaligned offset) +SxD_TEST(r, xlen_t, 8, 7) +// does not work (out of range) +SxD_TEST(r, xlen_t, 9, 8) + +#if __riscv_xlen != 32 +// works +SxD_TEST(w, uint32_t, 0, 1) +// does not work (can't merge with unaligned offset) +SxD_TEST(w, uint32_t, 1, 2) +// works +SxD_TEST(w, uint32_t, 2, 3) +// does not work (can't merge with unaligned offset) +SxD_TEST(w, uint32_t, 3, 4) +// works +SxD_TEST(w, uint32_t, 4, 5) +// does not work (can't merge with unaligned offset) +SxD_TEST(w, uint32_t, 5, 6) +// works +SxD_TEST(w, uint32_t, 6, 7) +// does not work (can't merge with unaligned offset) +SxD_TEST(w, uint32_t, 7, 8) +// does not work (out of range) +SxD_TEST(w, uint32_t, 8, 9) +#endif + +/* { dg-final { scan-assembler-times "th.sdd\t" 8 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 4 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "th.swd\t" 8 { 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..5dec702819a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */ +/* { 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 +typedef uint32_t xlen_t; +#else +typedef uint64_t xlen_t; +#endif + +void foo (xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t); +void bar (xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t, xlen_t); + +void baz (xlen_t a, xlen_t b, xlen_t c, xlen_t d, xlen_t e, xlen_t f, xlen_t g, xlen_t h) +{ + foo (a, b, c, d, e, f, g, h); + /* RV64: We don't use 0(sp), therefore we can only get 3 mempairs. */ + /* RV32: We don't use 0(sp)-8(sp), therefore we can only get 2 mempairs. */ + bar (a, b, c, d, e, f, g, h); +} + +/* { dg-final { scan-assembler-times "th.ldd\t" 3 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.sdd\t" 3 { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-times "th.lwd\t" 2 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "th.swd\t" 2 { target { rv32 } } } } */ From patchwork Fri Feb 24 05:51:26 2023 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: 65571 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 B63F8381A89D for ; Fri, 24 Feb 2023 05:53:48 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by sourceware.org (Postfix) with ESMTPS id DA3983850841 for ; Fri, 24 Feb 2023 05:51:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DA3983850841 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-wr1-x432.google.com with SMTP id l1so12493960wry.10 for ; Thu, 23 Feb 2023 21:51: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=fwluFhQrUAshxS1yBZ9CzlCPaX39YDi02D7pQcnDpTA=; b=URKspYvlCqQdAkZczEQpDV/h/OvfYdNkfwaqh940EoWDhw1UVL9wnxvrdtUqnxlVtQ HLw/aE5K9Jx+ywO+CD5TMlst34WDSkSC16pUtQrPg69ojIU5Lh622MKEsKGsTUGitL5n vp+Tcld34y93L5vhxUaxReGSL2zFJSZV+lUAlVJW1tk2NmMIVgY7V4EVqDo9OkjrXesW uNNkXP623Q9xCkEIGqaubF2FaJu8G7R6anhAdWnRgu9X/J0122oYSYUcBj6J2k+OT4xI 83/5EdeTCy8sNilXWum6yG4Vc5IHuygw47gektuMy/H2gAP3iezxSdxsqhY0KSpdqTAK EbXQ== 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=fwluFhQrUAshxS1yBZ9CzlCPaX39YDi02D7pQcnDpTA=; b=6e2jT+RLcJt5S8uk0GHhehsQzFY3K4sXouLWUL1f4dp3UqbbXs+4WWirtn3ZDkrKrn 6zzBr8irbFKOTRQJNN5TpPckKGU/lTqswZ2opJ17S+gJDV0bpAuLJUU+s66tNvVI90mC VyqMXNKicxbeMI2DD7rHZGDDfJCKXJUDF+SYDp9vguz7YiAwAQT+BzD6mRiuhwZ8VzWQ k4D53FzoZqGQSN+ltTnA2Cmqt0YLgfPxPqSltGqpAN+mHhb7V14GXUKHiYlbrTU2zk8X lRfn0OsllAZf26Uxsp7jHrYkv9zijvraTqGcShQPZys2UG7v5uEtBRc39EN1RVN+aAjA yx/g== X-Gm-Message-State: AO0yUKVyJiu52cg8XtWlUGo/Ff7zLN44m64+LZV43PVDU3/GL4YiU9fe OUkmG+z6XbUwp4Al28gAl85/37bNVRHGJgDd X-Google-Smtp-Source: AK7set953dk7CFOE6UwaJyEGpFPFWF54fh0hrr8g7d71LD/nZruBbFSzCj/iCfA496v/UlQL2WEcbg== X-Received: by 2002:adf:ce0b:0:b0:2c6:e827:21c1 with SMTP id p11-20020adfce0b000000b002c6e82721c1mr10993982wrn.50.1677217907795; Thu, 23 Feb 2023 21:51: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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51: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: "moiz.hussain" , =?utf-8?q?Christoph_M=C3=BCl?= =?utf-8?q?lner?= Subject: [PATCH v3 10/11] riscv: thead: Add support for the XTheadMemIdx ISA extension Date: Fri, 24 Feb 2023 06:51:26 +0100 Message-Id: <20230224055127.2500953-11-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 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 XTheadMemIdx ISA extension provides a additional addressing modes to load and store instructions: * increment after * increment before * register indexed gcc/ChangeLog: * config/riscv/constraints.md (Qmb): New constraint. (Qma): Likewise. (Qmr): Likewise. (Qmu): Likewise. * config/riscv/riscv-opts.h (HAVE_POST_MODIFY_DISP): New macro. (HAVE_PRE_MODIFY_DISP): Likewise. * config/riscv/riscv-protos.h (riscv_classify_address_index): New prototype. (riscv_classify_address_modify): Likewise. (riscv_output_move_index): Likewise. (riscv_output_move_modify): Likewise. (riscv_legitimize_address_index_p): Likewise. (riscv_legitimize_address_modify_p): Likewise. * config/riscv/riscv.cc (enum riscv_address_type): Add new addressing modes. (struct riscv_address_info): New field 'shift'. (riscv_classify_address): Add support for XTheadMemIdx. (riscv_classify_address_index): New function. (riscv_classify_address_modify): New function. (AM_IMM): New helper macro. (AM_OFFSET): New helper macro. (riscv_legitimize_address_modify_p): New function. (riscv_output_move_modify): New function. (riscv_legitimize_address_index_p): New function. (riscv_output_move_index): New function. (riscv_legitimize_address): Add support for XTheadMemIdx. (riscv_rtx_costs): Adjust for XTheadMemIdx. (riscv_output_move): Generalize to support XTheadMemIdx. (riscv_print_operand_address): Add support for XTheadMemIdx. * config/riscv/riscv.h (INDEX_REG_CLASS): Adjust for XTheadMemIdx. (REGNO_OK_FOR_INDEX_P): Adjust for XTheadMemIdx. * config/riscv/riscv.md (*zero_extendhi2): Adjust pattern for XTheadMemIdx. (*zero_extendhi2_internal): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadmemidx-ldi-sdi.c: New test. * gcc.target/riscv/xtheadmemidx-ldr-str-32.c: New test. * gcc.target/riscv/xtheadmemidx-ldr-str-64.c: New test. * gcc.target/riscv/xtheadmemidx-macros.h: New test. Signed-off-by: M. Moiz Hussain Signed-off-by: Christoph Müllner --- gcc/config/riscv/constraints.md | 28 ++ gcc/config/riscv/riscv-opts.h | 3 + gcc/config/riscv/riscv-protos.h | 18 + gcc/config/riscv/riscv.cc | 438 ++++++++++++++++-- gcc/config/riscv/riscv.h | 8 +- gcc/config/riscv/riscv.md | 78 +++- .../gcc.target/riscv/xtheadmemidx-ldi-sdi.c | 72 +++ .../riscv/xtheadmemidx-ldr-str-32.c | 23 + .../riscv/xtheadmemidx-ldr-str-64.c | 53 +++ .../gcc.target/riscv/xtheadmemidx-macros.h | 110 +++++ 10 files changed, 772 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldi-sdi.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-32.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-64.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-macros.h diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index e49019d8fa9..a007cf0b4f5 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -174,3 +174,31 @@ (define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS : NO_REGS" (define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS : NO_REGS" "An integer register for XTheadFmv.") + +(define_memory_constraint "Qmb" + "@internal + An address valid for LDIB/LDIA and STIB/STIA instructions." + (and (match_code "mem") + (match_test "riscv_legitimize_address_modify_p ( + XEXP (op, 0), GET_MODE (op), false)"))) + +(define_memory_constraint "Qma" + "@internal + An address valid for LDIA and STIA instructions." + (and (match_code "mem") + (match_test "riscv_legitimize_address_modify_p ( + XEXP (op, 0), GET_MODE (op), true)"))) + +(define_memory_constraint "Qmr" + "@internal + An address valid for LDR and STR instructions." + (and (match_code "mem") + (match_test "riscv_legitimize_address_index_p ( + XEXP (op, 0), GET_MODE (op), false)"))) + +(define_memory_constraint "Qmu" + "@internal + An address valid for LDUR and STUR instructions." + (and (match_code "mem") + (match_test "riscv_legitimize_address_index_p ( + XEXP (op, 0), GET_MODE (op), true)"))) diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index cf0cd669be4..5cd3f7673f0 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -215,4 +215,7 @@ enum stack_protector_guard { #define TARGET_XTHEADMEMPAIR ((riscv_xthead_subext & MASK_XTHEADMEMPAIR) != 0) #define TARGET_XTHEADSYNC ((riscv_xthead_subext & MASK_XTHEADSYNC) != 0) +#define HAVE_POST_MODIFY_DISP TARGET_XTHEADMEMIDX +#define HAVE_PRE_MODIFY_DISP TARGET_XTHEADMEMIDX + #endif /* ! GCC_RISCV_OPTS_H */ diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 1b7ba02726d..019a0e08285 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -65,6 +65,24 @@ 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); #endif + +extern bool +riscv_classify_address_index (struct riscv_address_info *info, rtx x, + machine_mode mode, bool strict_p); +extern bool +riscv_classify_address_modify (struct riscv_address_info *info, rtx x, + machine_mode mode, bool strict_p); + +extern const char * +riscv_output_move_index (rtx x, machine_mode mode, bool ldr); +extern const char * +riscv_output_move_modify (rtx x, machine_mode mode, bool ldi); + +extern bool +riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex); +extern bool +riscv_legitimize_address_modify_p (rtx x, machine_mode mode, bool post); + 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); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 33854393bd2..2980dbd69f9 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -83,6 +83,19 @@ along with GCC; see the file COPYING3. If not see /* Classifies an address. + ADDRESS_REG_REG + A base register indexed by (optionally scaled) register. + + ADDRESS_REG_UREG + A base register indexed by (optionally scaled) zero-extended register. + + ADDRESS_REG_WB + A base register indexed by immediate offset with writeback. + + ADDRESS_REG + A natural register + offset address. The register satisfies + riscv_valid_base_register_p and the offset is a const_arith_operand. + ADDRESS_REG A natural register + offset address. The register satisfies riscv_valid_base_register_p and the offset is a const_arith_operand. @@ -97,6 +110,9 @@ along with GCC; see the file COPYING3. If not see ADDRESS_SYMBOLIC: A constant symbolic address. */ enum riscv_address_type { + ADDRESS_REG_REG, + ADDRESS_REG_UREG, + ADDRESS_REG_WB, ADDRESS_REG, ADDRESS_LO_SUM, ADDRESS_CONST_INT, @@ -201,6 +217,7 @@ struct riscv_address_info { rtx reg; rtx offset; enum riscv_symbol_type symbol_type; + int shift; }; /* One stage in a constant building sequence. These sequences have @@ -1025,12 +1042,31 @@ riscv_classify_address (struct riscv_address_info *info, rtx x, if (riscv_v_ext_vector_mode_p (mode)) return false; + if (riscv_valid_base_register_p (XEXP (x, 0), mode, strict_p) + && riscv_classify_address_index (info, XEXP (x, 1), mode, strict_p)) + { + info->reg = XEXP (x, 0); + return true; + } + else if (riscv_valid_base_register_p (XEXP (x, 1), mode, strict_p) + && riscv_classify_address_index (info, XEXP (x, 0), + mode, strict_p)) + { + info->reg = XEXP (x, 1); + return true; + } + info->type = ADDRESS_REG; info->reg = XEXP (x, 0); info->offset = XEXP (x, 1); return (riscv_valid_base_register_p (info->reg, mode, strict_p) && riscv_valid_offset_p (info->offset, mode)); + case POST_MODIFY: + case PRE_MODIFY: + + return riscv_classify_address_modify (info, x, mode, strict_p); + case LO_SUM: /* RVV load/store disallow LO_SUM. */ if (riscv_v_ext_vector_mode_p (mode)) @@ -1269,6 +1305,263 @@ riscv_emit_move (rtx dest, rtx src) : emit_move_insn_1 (dest, src)); } +/* Return true if address offset is a valid index. If it is, fill in INFO + appropriately. STRICT_P is true if REG_OK_STRICT is in effect. */ + +bool +riscv_classify_address_index (struct riscv_address_info *info, rtx x, + machine_mode mode, bool strict_p) +{ + enum riscv_address_type type = ADDRESS_REG_REG;; + rtx index; + int shift = 0; + + if (!TARGET_XTHEADMEMIDX) + return false; + + if (!TARGET_64BIT && mode == DImode) + return false; + + if (SCALAR_FLOAT_MODE_P (mode)) + { + if (!TARGET_HARD_FLOAT) + return false; + if (GET_MODE_SIZE (mode).to_constant () == 2) + return false; + } + + /* (reg:P) */ + if ((REG_P (x) || GET_CODE (x) == SUBREG) + && GET_MODE (x) == Pmode) + { + index = x; + shift = 0; + } + /* (zero_extend:DI (reg:SI)) */ + else if (GET_CODE (x) == ZERO_EXTEND + && GET_MODE (x) == DImode + && GET_MODE (XEXP (x, 0)) == SImode) + { + type = ADDRESS_REG_UREG; + index = XEXP (x, 0); + shift = 0; + } + /* (mult:DI (zero_extend:DI (reg:SI)) (const_int scale)) */ + else if (GET_CODE (x) == MULT + && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && GET_MODE (XEXP (x, 0)) == DImode + && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode + && CONST_INT_P (XEXP (x, 1))) + { + type = ADDRESS_REG_UREG; + index = XEXP (XEXP (x, 0), 0); + shift = exact_log2 (INTVAL (XEXP (x, 1))); + } + /* (ashift:DI (zero_extend:DI (reg:SI)) (const_int shift)) */ + else if (GET_CODE (x) == ASHIFT + && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && GET_MODE (XEXP (x, 0)) == DImode + && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode + && CONST_INT_P (XEXP (x, 1))) + { + type = ADDRESS_REG_UREG; + index = XEXP (XEXP (x, 0), 0); + shift = INTVAL (XEXP (x, 1)); + } + /* (mult:P (reg:P) (const_int scale)) */ + else if (GET_CODE (x) == MULT + && GET_MODE (x) == Pmode + && GET_MODE (XEXP (x, 0)) == Pmode + && CONST_INT_P (XEXP (x, 1))) + { + index = XEXP (x, 0); + shift = exact_log2 (INTVAL (XEXP (x, 1))); + } + /* (ashift:P (reg:P) (const_int shift)) */ + else if (GET_CODE (x) == ASHIFT + && GET_MODE (x) == Pmode + && GET_MODE (XEXP (x, 0)) == Pmode + && CONST_INT_P (XEXP (x, 1))) + { + index = XEXP (x, 0); + shift = INTVAL (XEXP (x, 1)); + } + else + return false; + + if (shift != 0 && !IN_RANGE (shift, 1, 3)) + return false; + + if (!strict_p + && GET_CODE (index) == SUBREG + && contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (index))]) + index = SUBREG_REG (index); + + if (riscv_valid_base_register_p (index, mode, strict_p)) + { + info->type = type; + info->offset = index; + info->shift = shift; + return true; + } + return false; +} + +/* Return true if address is a valid modify. If it is, fill in INFO + appropriately. STRICT_P is true if REG_OK_STRICT is in effect. */ + +bool +riscv_classify_address_modify (struct riscv_address_info *info, rtx x, + machine_mode mode, bool strict_p) +{ + +#define AM_IMM(BIT) (1LL << (5 + (BIT))) +#define AM_OFFSET(VALUE, SHIFT) (\ + ((unsigned HOST_WIDE_INT) (VALUE) + AM_IMM (SHIFT)/2 < AM_IMM (SHIFT)) \ + && !((unsigned HOST_WIDE_INT) (VALUE) & ((1 << (SHIFT)) - 1)) \ + ? (SHIFT) + 1 \ + : 0) + + if (!TARGET_XTHEADMEMIDX) + return false; + + if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8)) + return false; + + if (!TARGET_64BIT && mode == DImode) + return false; + + if (GET_CODE (x) != POST_MODIFY + && GET_CODE (x) != PRE_MODIFY) + return false; + + info->type = ADDRESS_REG_WB; + info->reg = XEXP (x, 0); + + if (GET_CODE (XEXP (x, 1)) == PLUS + && CONST_INT_P (XEXP (XEXP (x, 1), 1)) + && rtx_equal_p (XEXP (XEXP (x, 1), 0), info->reg) + && riscv_valid_base_register_p (info->reg, mode, strict_p)) + { + info->offset = XEXP (XEXP (x, 1), 1); + int shift = AM_OFFSET (INTVAL (info->offset), 0); + if (!shift) + shift = AM_OFFSET (INTVAL (info->offset), 1); + if (!shift) + shift = AM_OFFSET (INTVAL (info->offset), 2); + if (!shift) + shift = AM_OFFSET (INTVAL (info->offset), 3); + if (shift) + { + info->shift = shift - 1; + return true; + } + } + return false; +} + +/* Return TRUE if X is a legitimate address modify. */ + +bool +riscv_legitimize_address_modify_p (rtx x, machine_mode mode, bool post) +{ + struct riscv_address_info addr; + return riscv_classify_address_modify (&addr, x, mode, false) + && (!post || GET_CODE (x) == POST_MODIFY); +} + +/* Return the LDIB/LDIA and STIB/STIA instructions. Assume + that X is MEM operand. */ + +const char * +riscv_output_move_modify (rtx x, machine_mode mode, bool ldi) +{ + static char buf[128] = {0}; + + int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()); + if (!IN_RANGE (index, 0, 3)) + return NULL; + + if (!riscv_legitimize_address_modify_p (x, mode, false)) + return NULL; + + bool post = riscv_legitimize_address_modify_p (x, mode, true); + + const char *const insn[][4] = { + { + "th.sbi%s\t%%z1,%%0", + "th.shi%s\t%%z1,%%0", + "th.swi%s\t%%z1,%%0", + "th.sdi%s\t%%z1,%%0" + }, + { + "th.lbui%s\t%%0,%%1", + "th.lhui%s\t%%0,%%1", + "th.lwi%s\t%%0,%%1", + "th.ldi%s\t%%0,%%1" + } + }; + + snprintf (buf, sizeof (buf), insn[ldi][index], post ? "a" : "b"); + return buf; +} + +bool +riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex) +{ + struct riscv_address_info addr; + rtx op0, op1; + + if (GET_CODE (x) != PLUS) + return false; + + op0 = XEXP (x, 0); + op1 = XEXP (x, 1); + + return ((riscv_valid_base_register_p (op0, mode, false) + && riscv_classify_address_index (&addr, op1, mode, false)) + || (riscv_valid_base_register_p (op1, mode, false) + && riscv_classify_address_index (&addr, op0, mode, false))) + && (!uindex || addr.type == ADDRESS_REG_UREG); +} + +/* Return the LDR or STR instructions. Assume + that X is MEM operand. */ + +const char * +riscv_output_move_index (rtx x, machine_mode mode, bool ldr) +{ + static char buf[128] = {0}; + + int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()); + if (!IN_RANGE (index, 0, 3)) + return NULL; + + if (!riscv_legitimize_address_index_p (x, mode, false)) + return NULL; + + bool uindex = riscv_legitimize_address_index_p (x, mode, true); + + const char *const insn[][4] = { + { + "th.s%srb\t%%z1,%%0", + "th.s%srh\t%%z1,%%0", + "th.s%srw\t%%z1,%%0", + "th.s%srd\t%%z1,%%0" + }, + { + "th.l%srbu\t%%0,%%1", + "th.l%srhu\t%%0,%%1", + "th.l%srw\t%%0,%%1", + "th.l%srd\t%%0,%%1" + } + }; + + snprintf (buf, sizeof (buf), insn[ldr][index], uindex ? "u" : ""); + + return buf; +} + /* Emit an instruction of the form (set TARGET SRC). */ static rtx @@ -1631,6 +1924,42 @@ riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, if (riscv_split_symbol (NULL, x, mode, &addr, FALSE)) return riscv_force_address (addr, mode); + /* Optimize BASE + OFFSET into BASE + INDEX. */ + if (TARGET_XTHEADMEMIDX + && GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)) + && INTVAL (XEXP (x, 1)) != 0 + && GET_CODE (XEXP (x, 0)) == PLUS) + { + rtx base = XEXP (x, 0); + rtx offset_rtx = XEXP (x, 1); + + rtx op0 = XEXP (base, 0); + rtx op1 = XEXP (base, 1); + /* Force any scaling into a temp for CSE. */ + op0 = force_reg (Pmode, op0); + op1 = force_reg (Pmode, op1); + + /* Let the pointer register be in op0. */ + if (REG_POINTER (op1)) + std::swap (op0, op1); + + unsigned regno = REGNO (op0); + + /* If the pointer is virtual or frame related, then we know that + virtual register instantiation or register elimination is going + to apply a second constant. We want the two constants folded + together easily. Therefore, emit as (OP0 + CONST) + OP1. */ + if ((regno >= FIRST_VIRTUAL_REGISTER + && regno <= LAST_VIRTUAL_POINTER_REGISTER) + || regno == FRAME_POINTER_REGNUM + || regno == ARG_POINTER_REGNUM) + { + base = expand_binop (Pmode, add_optab, op0, offset_rtx, + NULL_RTX, true, OPTAB_DIRECT); + return gen_rtx_PLUS (Pmode, base, op1); + } + } + /* Handle BASE + OFFSET. */ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0) @@ -2408,6 +2737,13 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; } + /* bit extraction pattern (xtheadmemidx, xtheadfmemidx). */ + if (outer_code == SET + && TARGET_XTHEADMEMIDX) + { + *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); + return true; + } gcc_fallthrough (); case SIGN_EXTRACT: if (TARGET_XTHEADBB && outer_code == SET @@ -2826,13 +3162,23 @@ riscv_output_move (rtx dest, rtx src) } if (src_code == MEM) - switch (width) - { - case 1: return "lbu\t%0,%1"; - case 2: return "lhu\t%0,%1"; - case 4: return "lw\t%0,%1"; - case 8: return "ld\t%0,%1"; - } + { + const char *insn = NULL; + insn = riscv_output_move_index (XEXP (src, 0), GET_MODE (src), true); + if (!insn) + insn = riscv_output_move_modify (XEXP (src, 0), + GET_MODE (src), true); + if (insn) + return insn; + + switch (width) + { + case 1: return "lbu\t%0,%1"; + case 2: return "lhu\t%0,%1"; + case 4: return "lw\t%0,%1"; + case 8: return "ld\t%0,%1"; + } + } if (src_code == CONST_INT) { @@ -2887,13 +3233,24 @@ riscv_output_move (rtx dest, rtx src) } } if (dest_code == MEM) - switch (width) - { - case 1: return "sb\t%z1,%0"; - case 2: return "sh\t%z1,%0"; - case 4: return "sw\t%z1,%0"; - case 8: return "sd\t%z1,%0"; - } + { + const char *insn = NULL; + insn = riscv_output_move_index (XEXP (dest, 0), + GET_MODE (dest), false); + if (!insn) + insn = riscv_output_move_modify (XEXP (dest, 0), + GET_MODE (dest), false); + if (insn) + return insn; + + switch (width) + { + case 1: return "sb\t%z1,%0"; + case 2: return "sh\t%z1,%0"; + case 4: return "sw\t%z1,%0"; + case 8: return "sd\t%z1,%0"; + } + } } if (src_code == REG && FP_REG_P (REGNO (src))) { @@ -2911,28 +3268,32 @@ riscv_output_move (rtx dest, rtx src) } if (dest_code == MEM) - switch (width) - { - case 2: - return "fsh\t%1,%0"; - case 4: - return "fsw\t%1,%0"; - case 8: - return "fsd\t%1,%0"; - } + { + switch (width) + { + case 2: + return "fsh\t%1,%0"; + case 4: + return "fsw\t%1,%0"; + case 8: + return "fsd\t%1,%0"; + } + } } if (dest_code == REG && FP_REG_P (REGNO (dest))) { if (src_code == MEM) - switch (width) - { - case 2: - return "flh\t%0,%1"; - case 4: - return "flw\t%0,%1"; - case 8: - return "fld\t%0,%1"; - } + { + switch (width) + { + case 2: + return "flh\t%0,%1"; + case 4: + return "flw\t%0,%1"; + case 8: + return "fld\t%0,%1"; + } + } } if (dest_code == REG && GP_REG_P (REGNO (dest)) && src_code == CONST_POLY_INT) { @@ -4881,6 +5242,19 @@ riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx case ADDRESS_SYMBOLIC: output_addr_const (file, riscv_strip_unspec_address (x)); return; + + case ADDRESS_REG_REG: + case ADDRESS_REG_UREG: + fprintf (file, "%s,%s,%u", reg_names[REGNO (addr.reg)], + reg_names[REGNO (addr.offset)], + addr.shift); + return; + + case ADDRESS_REG_WB: + fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)], + (long) INTVAL (addr.offset) >> addr.shift, + addr.shift); + return; } gcc_unreachable (); } diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 5bc7f2f467d..199bb30162e 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -535,7 +535,8 @@ enum reg_class factor or added to another register (as well as added to a displacement). */ -#define INDEX_REG_CLASS NO_REGS +#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX) ? \ + GR_REGS : NO_REGS) /* We generally want to put call-clobbered registers ahead of call-saved ones. (IRA expects this.) */ @@ -705,7 +706,10 @@ typedef struct { /* Addressing modes, and classification of registers for them. */ -#define REGNO_OK_FOR_INDEX_P(REGNO) 0 +#define REGNO_OK_FOR_INDEX_P(REGNO) \ + ((TARGET_XTHEADMEMIDX) ? \ + riscv_regno_mode_ok_for_base_p (REGNO, VOIDmode, 1) : 0) + #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 61f175bb62b..df31a1fffff 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1360,12 +1360,17 @@ (define_expand "zero_extendsidi2" "TARGET_64BIT") (define_insn_and_split "*zero_extendsidi2_internal" - [(set (match_operand:DI 0 "register_operand" "=r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" " r,m")))] - "TARGET_64BIT && !TARGET_ZBA" + (match_operand:SI 1 + "nonimmediate_operand" " r,Qmu,Qmr,Qma,Qmb,m")))] + "TARGET_64BIT && !(TARGET_ZBA || TARGET_ZBB)" "@ # + th.lurwu\t%0,%1 + th.lrwu\t%0,%1 + th.lwuia\t%0,%1 + th.lwuib\t%0,%1 lwu\t%0,%1" "&& reload_completed && REG_P (operands[1]) @@ -1375,7 +1380,7 @@ (define_insn_and_split "*zero_extendsidi2_internal" (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))] { operands[1] = gen_lowpart (DImode, operands[1]); } - [(set_attr "move_type" "shift_shift,load") + [(set_attr "move_type" "shift_shift,load,load,load,load,load") (set_attr "mode" "DI")]) (define_expand "zero_extendhi2" @@ -1384,13 +1389,18 @@ (define_expand "zero_extendhi2" (match_operand:HI 1 "nonimmediate_operand")))] "") -(define_insn_and_split "*zero_extendhi2" - [(set (match_operand:GPR 0 "register_operand" "=r,r") +(define_insn_and_split "*zero_extendhi2_internal" + [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r") (zero_extend:GPR - (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB" + (match_operand:HI 1 + "nonimmediate_operand" " r,Qmu,Qmr,Qma,Qmb,m")))] + "!(TARGET_ZBA || TARGET_ZBB)" "@ # + th.lurhu\t%0,%1 + th.lrhu\t%0,%1 + th.lhuia\t%0,%1 + th.lhuib\t%0,%1 lhu\t%0,%1" "&& reload_completed && REG_P (operands[1]) @@ -1401,20 +1411,25 @@ (define_insn_and_split "*zero_extendhi2" (lshiftrt:GPR (match_dup 0) (match_dup 2)))] { operands[1] = gen_lowpart (mode, operands[1]); - operands[2] = GEN_INT(GET_MODE_BITSIZE(mode) - 16); + operands[2] = GEN_INT (GET_MODE_BITSIZE (mode) - 16); } - [(set_attr "move_type" "shift_shift,load") + [(set_attr "move_type" "shift_shift,load,load,load,load,load") (set_attr "mode" "")]) (define_insn "zero_extendqi2" - [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r") (zero_extend:SUPERQI - (match_operand:QI 1 "nonimmediate_operand" " r,m")))] + (match_operand:QI 1 + "nonimmediate_operand" " r,Qmu,Qmr,Qma,Qmb,m")))] "" "@ andi\t%0,%1,0xff + th.lurbu\t%0,%1 + th.lrbu\t%0,%1 + th.lbuia\t%0,%1 + th.lbuib\t%0,%1 lbu\t%0,%1" - [(set_attr "move_type" "andi,load") + [(set_attr "move_type" "andi,load,load,load,load,load") (set_attr "mode" "")]) ;; @@ -1425,14 +1440,19 @@ (define_insn "zero_extendqi2" ;; .................... (define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" " r,m")))] + (match_operand:SI 1 + "nonimmediate_operand" " r,Qmu,Qmr,Qma,Qmb,m")))] "TARGET_64BIT" "@ sext.w\t%0,%1 + th.lurw\t%0,%1 + th.lrw\t%0,%1 + th.lwia\t%0,%1 + th.lwib\t%0,%1 lw\t%0,%1" - [(set_attr "move_type" "move,load") + [(set_attr "move_type" "move,load,load,load,load,load") (set_attr "mode" "DI")]) (define_expand "extend2" @@ -1441,12 +1461,17 @@ (define_expand "extend2" "") (define_insn_and_split "*extend2" - [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r") (sign_extend:SUPERQI - (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] + (match_operand:SHORT 1 + "nonimmediate_operand" " r,Qmu,Qmr,Qma,Qmb,m")))] "!TARGET_ZBB" "@ # + th.lur\t%0,%1 + th.lr\t%0,%1 + th.lia\t%0,%1 + th.lib\t%0,%1 l\t%0,%1" "&& reload_completed && REG_P (operands[1]) @@ -1459,7 +1484,7 @@ (define_insn_and_split "*extend2" operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode)); } - [(set_attr "move_type" "shift_shift,load") + [(set_attr "move_type" "shift_shift,load,load,load,load,load") (set_attr "mode" "SI")]) (define_insn "extendhfsf2" @@ -1507,7 +1532,8 @@ (define_insn "*movhf_hardfloat" && (register_operand (operands[0], HFmode) || reg_or_0_operand (operands[1], HFmode))" { return riscv_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "HF")]) (define_insn "*movhf_softfloat" @@ -1836,7 +1862,8 @@ (define_insn "*movsf_hardfloat" && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" { return riscv_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "SF")]) (define_insn "*movsf_softfloat" @@ -1860,7 +1887,6 @@ (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" @@ -1870,7 +1896,8 @@ (define_insn "*movdf_hardfloat_rv32" && (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,mtc,mfc,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" @@ -1880,7 +1907,8 @@ (define_insn "*movdf_hardfloat_rv64" && (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,mtc,mfc,move,load,store") + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) (define_insn "*movdf_softfloat" @@ -2187,7 +2215,7 @@ (define_split (and:GPR (match_operand:GPR 1 "register_operand") (match_operand:GPR 2 "p2m1_shift_operand"))) (clobber (match_operand:GPR 3 "register_operand"))] - "" + "!TARGET_XTHEADMEMIDX" [(set (match_dup 3) (ashift:GPR (match_dup 1) (match_dup 2))) (set (match_dup 0) diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldi-sdi.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldi-sdi.c new file mode 100644 index 00000000000..8d785e62416 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldi-sdi.c @@ -0,0 +1,72 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmemidx --save-temps -O2" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmemidx --save-temps -O2" { target { rv32 } } } */ + +#include "xtheadmemidx-macros.h" + +/* no special function attribute required */ +#define ATTR /* */ + +POST_LOAD(s_char, ATTR) +/* { dg-final { scan-assembler "th.lbia.*1,0" } } */ +PRE_LOAD(s_char, ATTR) +/* { dg-final { scan-assembler "th.lbib.*1,0" } } */ +POST_LOAD(char, ATTR) +/* { dg-final { scan-assembler "th.lbuia.*1,0" } } */ +PRE_LOAD(char, ATTR) +/* { dg-final { scan-assembler "th.lbuib.*1,0" } } */ +POST_LOAD(short, ATTR) +/* { dg-final { scan-assembler "th.lhia.*2,0" } } */ +PRE_LOAD(short, ATTR) +/* { dg-final { scan-assembler "th.lhib.*2,0" } } */ +POST_LOAD(u_short, ATTR) +/* { dg-final { scan-assembler "th.lhuia.*2,0" } } */ +PRE_LOAD(u_short, ATTR) +/* { dg-final { scan-assembler "th.lhuib.*2,0" } } */ + +POST_LOAD(int, ATTR) +/* { dg-final { scan-assembler "th.lwia.*4,0" } } */ +PRE_LOAD(int, ATTR) +/* { dg-final { scan-assembler "th.lwib.*4,0" } } */ +void int_post_load_lwuia (void* p) +{ + extern void fint2 (int*,u_ll); + u_int *q = (u_int*)p; + u_ll x = *q++; + fint2 (q, x); +} +/* { dg-final { scan-assembler "th.lwuia.*4,0" { target { rv64 } } } } */ +void int_pre_load_lwuib (void* p) +{ + extern void fint2 (int*,u_ll); + u_int *q = (u_int*)p; + u_ll x = *++q; + fint2 (q, x); +} +/* { dg-final { scan-assembler "th.lwuib.*4,0" { target { rv64 } } } } */ + +POST_LOAD(s_ll, ATTR) +/* { dg-final { scan-assembler "th.ldia.*8,0" { target { rv64 } } } } */ +PRE_LOAD(s_ll, ATTR) +/* { dg-final { scan-assembler "th.ldib.*8,0" { target { rv64 } } } } */ + +POST_STORE(char, ATTR) +/* { dg-final { scan-assembler "th.sbia.*1,0" } } */ +PRE_STORE(char, ATTR) +/* { dg-final { scan-assembler "th.sbib.*1,0" } } */ +POST_STORE(short, ATTR) +/* { dg-final { scan-assembler "th.shia.*2,0" } } */ +PRE_STORE(short, ATTR) +/* { dg-final { scan-assembler "th.shib.*2,0" } } */ +POST_STORE(int, ATTR) +/* { dg-final { scan-assembler "th.swia.*4,0" } } */ +PRE_STORE(int, ATTR) +/* { dg-final { scan-assembler "th.swib.*4,0" } } */ +POST_STORE(s_ll, ATTR) +/* { dg-final { scan-assembler "th.sdia.*8,0" { target { rv64 } } } } */ +PRE_STORE(s_ll, ATTR) +/* { dg-final { scan-assembler "th.sdib.*8,0" { target { rv64 } } } } */ + +/* { dg-final { scan-assembler-not "\taddi" { target { rv64 } } } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-32.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-32.c new file mode 100644 index 00000000000..6061eaf1d9a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-32.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */ + +#include "xtheadmemidx-macros.h" + +MV_LOAD_1_AND_2(s_int, s_char) +/* { dg-final { scan-assembler-times "th.lrb\t" 2 { target { rv32 } } } } */ +MV_LOAD_1_AND_2(s_int, u_char) +/* { dg-final { scan-assembler-times "th.lrbu\t" 2 { target { rv32 } } } } */ +MV_LOAD_1_AND_2(s_int, s_short) +/* { dg-final { scan-assembler-times "th.lrh\t" 2 { target { rv32 } } } } */ +MV_LOAD_1_AND_2(s_int, u_short) +/* { dg-final { scan-assembler-times "th.lrhu\t" 2 { target { rv32 } } } } */ +MV_LOAD_1_AND_2(s_int, s_int) +/* { dg-final { scan-assembler-times "th.lrw\t" 2 { target { rv32 } } } } */ + +MV_STORE_1(s_int, s_int, s_char) +/* { dg-final { scan-assembler-times "th.srb\t" 1 { target { rv32 } } } } */ +MV_STORE_1(s_int, s_int, s_short) +/* { dg-final { scan-assembler-times "th.srh\t" 1 { target { rv32 } } } } */ +MV_STORE_1(s_int, s_int, s_int) +/* { dg-final { scan-assembler-times "th.srw\t" 1 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-64.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-64.c new file mode 100644 index 00000000000..080d1853c83 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-ldr-str-64.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */ + +#include "xtheadmemidx-macros.h" + +MV_LOAD_1_AND_2(s_ll, s_char) +/* { dg-final { scan-assembler-times "th.lrb\t" 2 { target { rv64 } } } } */ +MV_LOAD_1_AND_2(s_ll, u_char) +/* { dg-final { scan-assembler-times "th.lrbu\t" 2 { target { rv64 } } } } */ +MV_LOAD_1_AND_2(s_ll, s_short) +/* { dg-final { scan-assembler-times "th.lrh\t" 2 { target { rv64 } } } } */ +MV_LOAD_1_AND_2(s_ll, u_short) +/* { dg-final { scan-assembler-times "th.lrhu\t" 2 { target { rv64 } } } } */ +MV_LOAD_1_AND_2(s_ll, s_int) +/* { dg-final { scan-assembler-times "th.lrw\t" 2 { target { rv64 } } } } */ +MV_LOAD_4(s_ll, s_int, u_int) +/* { dg-final { scan-assembler-times "th.lrwu\t" 1 { target { rv64 } } } } */ +MV_LOAD_1_AND_2(s_ll, s_ll) +/* { dg-final { scan-assembler-times "th.lrd\t" 2 { target { rv64 } } } } */ + +MV_STORE_1(s_ll, s_ll, s_char) +/* { dg-final { scan-assembler-times "th.srb\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, s_ll, s_short) +/* { dg-final { scan-assembler-times "th.srh\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, s_ll, s_int) +/* { dg-final { scan-assembler-times "th.srw\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, s_ll, s_ll) +/* { dg-final { scan-assembler-times "th.srd\t" 1 { target { rv64 } } } } */ + +MV_LOAD_3(s_ll, u_int, s_char) +/* { dg-final { scan-assembler-times "th.lurb\t" 1 { target { rv64 } } } } */ +MV_LOAD_3(s_ll, u_int, u_char) +/* { dg-final { scan-assembler-times "th.lurbu\t" 1 { target { rv64 } } } } */ +MV_LOAD_3(s_ll, u_int, s_short) +/* { dg-final { scan-assembler-times "th.lurh\t" 1 { target { rv64 } } } } */ +MV_LOAD_3(s_ll, u_int, u_short) +/* { dg-final { scan-assembler-times "th.lurhu\t" 1 { target { rv64 } } } } */ +MV_LOAD_3(s_ll, u_int, s_int) +/* { dg-final { scan-assembler-times "th.lurw\t" 1 { target { rv64 } } } } */ +MV_LOAD_4(s_ll, u_int, u_int) +/* { dg-final { scan-assembler-times "th.lurwu\t" 1 { target { rv64 } } } } */ +MV_LOAD_3(s_ll, u_int, u_ll) +/* { dg-final { scan-assembler-times "th.lurd\t" 1 { target { rv64 } } } } */ + +MV_STORE_1(s_ll, u_int, s_char) +/* { dg-final { scan-assembler-times "th.surb\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, u_int, s_short) +/* { dg-final { scan-assembler-times "th.surh\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, u_int, s_int) +/* { dg-final { scan-assembler-times "th.surw\t" 1 { target { rv64 } } } } */ +MV_STORE_1(s_ll, u_int, s_ll) +/* { dg-final { scan-assembler-times "th.surd\t" 1 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-macros.h b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-macros.h new file mode 100644 index 00000000000..848e4770964 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-macros.h @@ -0,0 +1,110 @@ +typedef unsigned char u_char; +typedef signed char s_char; +typedef unsigned short u_short; +typedef signed short s_short; +typedef unsigned int u_int; +typedef signed int s_int; +typedef unsigned int u_ll __attribute__((mode(DI))); +typedef signed int s_ll __attribute__((mode(DI))); + +#include "stdint.h" + +#define PRE_STORE(T, ATTR) \ + ATTR T * \ + T ## _pre_store (T *p, T v) \ + { \ + *++p = v; \ + return p; \ + } + +#define POST_STORE(T, ATTR) \ + ATTR T * \ + T ## _post_store (T *p, T v) \ + { \ + *p++ = v; \ + return p; \ + } + +#define POST_STORE_VEC(T, VT, OP, ATTR) \ + ATTR T * \ + VT ## _post_store (T * p, VT v) \ + { \ + OP (p, v); \ + p += sizeof (VT) / sizeof (T); \ + return p; \ + } + +#define PRE_LOAD(T, ATTR) \ + ATTR void \ + T ## _pre_load (T *p) \ + { \ + ATTR extern void f ## T (T*,T); \ + T x = *++p; \ + f ## T (p, x); \ + } + +#define POST_LOAD(T, ATTR) \ + ATTR void \ + T ## _post_load (T *p) \ + { \ + ATTR extern void f ## T (T*,T); \ + T x = *p++; \ + f ## T (p, x); \ + } + +#define POST_LOAD_VEC(T, VT, OP, ATTR) \ + ATTR void \ + VT ## _post_load (T * p) \ + { \ + ATTR extern void f ## T (T*,T); \ + VT x = OP (p, v); \ + p += sizeof (VT) / sizeof (T); \ + f ## T (p, x); \ + } + +#define MV_LOAD_1(RS2_TYPE, RET_TYPE) \ + RET_TYPE \ + mv_load_1_ ## RS2_TYPE ## _ ## RET_TYPE (RS2_TYPE *a, int b) \ + { \ + return a[b]; \ + } + +#define MV_LOAD_2(RS2_TYPE, RET_TYPE) \ + RET_TYPE \ + mv_load_2_ ## RS2_TYPE ## _ ## RET_TYPE ( \ + RS2_TYPE rs1, RS2_TYPE rs2, int a) \ + { \ + return (*((RET_TYPE*)(uintptr_t)(rs1 + (rs2 << a)))); \ + } + +#define MV_LOAD_3(RS2_TYPE, CONV_TYPE, RET_TYPE) \ + RET_TYPE \ + mv_load_3_ ## RS2_TYPE ## _ ## CONV_TYPE ## _ ## RET_TYPE ( \ + RS2_TYPE rs1, RS2_TYPE rs2, int a) \ + { \ + CONV_TYPE c = (CONV_TYPE) rs2; \ + return (*((RET_TYPE*)(uintptr_t)(rs1 + (c << a)))); \ + } + +#define MV_LOAD_4(RS2_TYPE, CONV_TYPE, TMP_RET_TYPE) \ + uintptr_t \ + mv_load_4_ ## RS2_TYPE ## _ ## CONV_TYPE ## _ ## TMP_RET_TYPE ( \ + RS2_TYPE rs1, RS2_TYPE rs2, int a) \ + { \ + CONV_TYPE c = (CONV_TYPE) rs2; \ + return (*((TMP_RET_TYPE*)(uintptr_t)(rs1 + (c << a)))); \ + } + +#define MV_STORE_1(RS2_TYPE, CONV_TYPE, STORE_TYPE) \ + void \ + mv_store_1_ ## RS2_TYPE ## _ ## CONV_TYPE ## _ ## STORE_TYPE ( \ + RS2_TYPE rs1, RS2_TYPE rs2, int a, int st_val) \ + { \ + CONV_TYPE c = (CONV_TYPE) rs2; \ + STORE_TYPE* addr = (STORE_TYPE*)(uintptr_t)(rs1 + (c << a)); \ + *addr = st_val; \ + } + +#define MV_LOAD_1_AND_2(RS2_TYPE, RET_TYPE) \ + MV_LOAD_1(RS2_TYPE, RET_TYPE) \ + MV_LOAD_2(RS2_TYPE, RET_TYPE) From patchwork Fri Feb 24 05:51:27 2023 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: 65568 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 8AC953896C1A for ; Fri, 24 Feb 2023 05:53:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id AA72F385B514 for ; Fri, 24 Feb 2023 05:51:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AA72F385B514 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-wr1-x42b.google.com with SMTP id bw19so2145894wrb.13 for ; Thu, 23 Feb 2023 21:51: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=ZXrvIxAS/0isWykuDtiY4lK5I+aXvifkXe6HGI7JlVM=; b=Unj4WULdjqcJ63Ph/UwtdBR92n1VJgoiZTzfnkJn+PtdI/aCkwIilP3bCj/vWzzhwo XiDUob4RFLQLRCr5lZg5eD5GHHPuUX18W8tafm1z0bZ+pnNwYOP3M+5AyxYlDyTLuFl/ w8dz0zMmbpYmh3vpbJPlZXbMpkxqvu6XQGy4D4JTCzuwO4sHEq/fBPRg3CXKKEobYgSZ T54JvFEnj7g5VuE1XVPh8EIqbEw8PvdLpCWwvzmbXlOW1T2d8xo1tIcSDQDoAO2zKlx7 YoFFMdjV24XIhAM0JrHF3FU4JLi9jKgeCBfYPOuKjdh1ZZ3kl3+LpE6MZMnOCnHdDuZ8 f77g== 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=ZXrvIxAS/0isWykuDtiY4lK5I+aXvifkXe6HGI7JlVM=; b=r2eE6yCOLhBP33Geep769aqiGr+yVzkRg4nn6n/w6Je30Q6oPUzxIX/KY+2sQWKxbv TZad04oQ0nPVcDzBppSy8eFBYdYFIJPzYsKnI5YOPliiWoaCmRzNICTBHkx1pb0HYYq0 eQeYbwSpbECELfscLdMz57DQl4zKH/62oaxsZCOv2J7VifMc171BZBKS9l/SAK2a5p07 gN8AwnjZMEmQKYbYmyW1ZGl8bX/1ew4GaB8Dqxu+QTt3eWx3gElzB0cP5DGmP8nZ0xrE m8bBX8ViqgkrvSdoGGNRtCmlVX49pQe8iRuyqBrzuzBJ9bQXPXklXuTJa7XPsMpr5Y2k YfRg== X-Gm-Message-State: AO0yUKUS/yzG8LYbGTbD18GhyrAhlQ3P6SkrqdcJMPVjza7ehnAEsC0c Y/h1HexuhMHgCEYONC+aEsOVKyMRG5fpKFm2 X-Google-Smtp-Source: AK7set/k7qWX+o+bZMu8Sv40DofqahegUp99/+4W2rduYquuivCAW9/iVpln+QOwvOf/USTkdBlV4g== X-Received: by 2002:a5d:6d8c:0:b0:2c7:e48:8ca3 with SMTP id l12-20020a5d6d8c000000b002c70e488ca3mr6260746wrs.0.1677217909790; Thu, 23 Feb 2023 21:51:49 -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 f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51: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: "moiz.hussain" , =?utf-8?q?Christoph_M=C3=BCl?= =?utf-8?q?lner?= Subject: [PATCH v3 11/11] riscv: thead: Add support for the XTheadFMemIdx ISA extension Date: Fri, 24 Feb 2023 06:51:27 +0100 Message-Id: <20230224055127.2500953-12-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 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 XTheadFMemIdx ISA extension provides register-indexed addressing modes to floating-point load and store instructions. gcc/ChangeLog: * config/riscv/constraints.md (Qmx): New constraint. * config/riscv/riscv-protos.h (riscv_output_move_index_float): New prototyp. * config/riscv/riscv.cc (riscv_classify_address_index): Adjust for XTheadFMemIdx. (riscv_classify_address_modify): Likewise. (riscv_output_move_index_float): New function. (riscv_rtx_costs): Adjust for XTheadFMemIdx. (riscv_split_64bit_move_p): Likewise. (riscv_output_move): Likewise. * config/riscv/riscv.h (INDEX_REG_CLASS): Likewise. (REGNO_OK_FOR_INDEX_P): Likewise. * config/riscv/riscv.md (*movsf_hardfloat): New pattern. (*movdf_hardfloat_rv32): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadfmemidx-fldr-fstr.c: New test. Signed-off-by: M. Moiz Hussain Signed-off-by: Christoph Müllner --- gcc/config/riscv/constraints.md | 7 ++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv.cc | 70 ++++++++++++++++++- gcc/config/riscv/riscv.h | 4 +- gcc/config/riscv/riscv.md | 28 ++++++++ .../riscv/xtheadfmemidx-fldr-fstr.c | 58 +++++++++++++++ 6 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index a007cf0b4f5..711268d05f6 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -202,3 +202,10 @@ (define_memory_constraint "Qmu" (and (match_code "mem") (match_test "riscv_legitimize_address_index_p ( XEXP (op, 0), GET_MODE (op), true)"))) + +(define_memory_constraint "Qmx" + "@internal + An address valid for GPR." + (and (match_code "mem") + (match_test "!riscv_legitimize_address_index_p ( + XEXP (op, 0), GET_MODE (op), false)"))) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 019a0e08285..ba53bf710d7 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -77,6 +77,8 @@ extern const char * riscv_output_move_index (rtx x, machine_mode mode, bool ldr); extern const char * riscv_output_move_modify (rtx x, machine_mode mode, bool ldi); +extern const char * +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr); extern bool riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 2980dbd69f9..caa30eed8d6 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1316,7 +1316,7 @@ riscv_classify_address_index (struct riscv_address_info *info, rtx x, rtx index; int shift = 0; - if (!TARGET_XTHEADMEMIDX) + if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) return false; if (!TARGET_64BIT && mode == DImode) @@ -1326,6 +1326,8 @@ riscv_classify_address_index (struct riscv_address_info *info, rtx x, { if (!TARGET_HARD_FLOAT) return false; + if (!(TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX)) + return false; if (GET_MODE_SIZE (mode).to_constant () == 2) return false; } @@ -1422,7 +1424,7 @@ riscv_classify_address_modify (struct riscv_address_info *info, rtx x, ? (SHIFT) + 1 \ : 0) - if (!TARGET_XTHEADMEMIDX) + if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) return false; if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8)) @@ -1562,6 +1564,42 @@ riscv_output_move_index (rtx x, machine_mode mode, bool ldr) return buf; } +const char * +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr) +{ + static char buf[128] = {0}; + + int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()); + if (!IN_RANGE (index, 2, 3)) + return NULL; + + if (!riscv_legitimize_address_index_p (x, mode, false)) + return NULL; + + bool uindex = riscv_legitimize_address_index_p (x, mode, true); + + /* Not using index, 0, 1, as they are not implemented + for xtheadfmemidx yet. */ + const char *const insn[][4] = { + { + "th.fs%srb\t%%z1,%%0", + "th.fs%srh\t%%z1,%%0", + "th.fs%srw\t%%z1,%%0", + "th.fs%srd\t%%z1,%%0" + }, + { + "th.fl%srb\t%%0,%%1", + "th.fl%srh\t%%0,%%1", + "th.fl%srw\t%%0,%%1", + "th.fl%srd\t%%0,%%1" + } + }; + + snprintf (buf, sizeof (buf), insn[ldr][index], uindex ? "u" : ""); + + return buf; +} + /* Emit an instruction of the form (set TARGET SRC). */ static rtx @@ -2739,7 +2777,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN } /* bit extraction pattern (xtheadmemidx, xtheadfmemidx). */ if (outer_code == SET - && TARGET_XTHEADMEMIDX) + && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) { *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; @@ -3071,6 +3109,20 @@ riscv_split_64bit_move_p (rtx dest, rtx src) if (TARGET_64BIT) return false; + if (TARGET_XTHEADFMEMIDX) + { + if (MEM_P (src) && SCALAR_FLOAT_MODE_P (GET_MODE (src)) + && riscv_legitimize_address_index_p (XEXP (src, 0), + GET_MODE (src), false) + && FP_REG_RTX_P (dest)) + return false; + if (MEM_P (dest) && SCALAR_FLOAT_MODE_P (GET_MODE (dest)) + && riscv_legitimize_address_index_p (XEXP (dest, 0), + GET_MODE (dest), false) + && FP_REG_RTX_P (src)) + return false; + } + /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case of zeroing an FPR with FCVT.D.W. */ if (TARGET_DOUBLE_FLOAT @@ -3269,6 +3321,12 @@ riscv_output_move (rtx dest, rtx src) if (dest_code == MEM) { + const char *insn = NULL; + insn = riscv_output_move_index_float (XEXP (dest, 0), + GET_MODE (dest), false); + if (insn) + return insn; + switch (width) { case 2: @@ -3284,6 +3342,12 @@ riscv_output_move (rtx dest, rtx src) { if (src_code == MEM) { + const char *insn = NULL; + insn = riscv_output_move_index_float (XEXP (src, 0), + GET_MODE (src), true); + if (insn) + return insn; + switch (width) { case 2: diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 199bb30162e..13764d60257 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -535,7 +535,7 @@ enum reg_class factor or added to another register (as well as added to a displacement). */ -#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX) ? \ +#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \ GR_REGS : NO_REGS) /* We generally want to put call-clobbered registers ahead of @@ -707,7 +707,7 @@ typedef struct { /* Addressing modes, and classification of registers for them. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ - ((TARGET_XTHEADMEMIDX) ? \ + ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \ riscv_regno_mode_ok_for_base_p (REGNO, VOIDmode, 1) : 0) #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index df31a1fffff..9d0207b8d6f 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1866,6 +1866,20 @@ (define_insn "*movsf_hardfloat" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "SF")]) +(define_insn "*movsf_hardfloat" + [(set (match_operand:SF 0 + "nonimmediate_operand" "=f,f,f,m,Qmx,*f,*r, *r,*r,*Qmx") + (match_operand:SF 1 + "move_operand" " f,G,m,f,G,*r,*f,*G*r,*Qmx,*r"))] + "!TARGET_64BIT + && TARGET_XTHEADFMEMIDX + && (register_operand (operands[0], SFmode) + || reg_or_0_operand (operands[1], SFmode))" + { return riscv_output_move (operands[0], operands[1]); } + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + (set_attr "mode" "SF")]) + (define_insn "*movsf_softfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m") (match_operand:SF 1 "move_operand" " Gr,m,r"))] @@ -1900,6 +1914,20 @@ (define_insn "*movdf_hardfloat_rv32" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) +(define_insn "*movdf_hardfloat_rv32" + [(set (match_operand:DF 0 + "nonimmediate_operand" "=f,f,f,m,Qmx, *r,*r,*Qmx") + (match_operand:DF 1 + "move_operand" " f,G,m,f,G,*r*G,*Qmx,*r"))] + "!TARGET_64BIT && TARGET_DOUBLE_FLOAT + && TARGET_XTHEADFMEMIDX + && (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 "mode" "DF")]) + (define_insn "*movdf_hardfloat_rv64" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))] diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c new file mode 100644 index 00000000000..006038ce3c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx --save-temps -O2" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadfmemidx --save-temps -O2" { target { rv32 } } } */ + +float func_f(float *a, int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flrw" } } */ + +double func_d(double *a, int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flrd" } } */ + +float func_sf(float *a, int b, float c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsrw" } } */ + +double func_sd(double *a, int b, double c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsrd" } } */ + +float func_uf(float *a, unsigned int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flurw" { target { rv64 } } } } */ + +double func_ud(double *a, unsigned int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flurd" { target { rv64 } } } } */ + +float func_usf(float *a, unsigned int b, float c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsurw" { target { rv64 } } } } */ + +double func_usd(double *a, unsigned int b, double c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsurd" { target { rv64 } } } } */ + +/* { dg-final { cleanup-saved-temps } } */