From patchwork Thu Mar 2 08:35: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: 65887 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 4A86A385E004 for ; Thu, 2 Mar 2023 08:36:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by sourceware.org (Postfix) with ESMTPS id 142403858CDB for ; Thu, 2 Mar 2023 08:35:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 142403858CDB Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x531.google.com with SMTP id u9so14977262edd.2 for ; Thu, 02 Mar 2023 00:35:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746139; 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=UXrhfLAtgJxbUXo5bV77xKG5zM05/K0bOJ5fkEHpg+e7oEeElLxAOhhVruar8hD36a isL0fFoCGogUZyYKxulAWGA5I8XknRa0An9ubTpeIGSd69zAabAzVohSr7i6HAgc6g0E bk149LGYFQavp71YXhwJxP0XjuiNZb09dvHXElAyRd9nt+yoTTY1g5iXhSlaG8+IPw4l EMUyFxLsHEyH+sqSokbd+JxTuv7JuwOC1FfabjE9D5NE/rmNTwWjaI5MV4/hGS/TpiqZ dLg4ZsNiTc1R15jOybYL6JkKrfdFhpuqkV5/PiNZDZ/mGrSyefRpqhuGDf778zaIjtP4 d/Mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746139; 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=KbWccjKbAw6s4sbQzDIz23lHDQx0sPkrOiBI0l0I9aIM1AtwsLUk14RFQf2oF6Uwme 0MeywSexFhDNE9pQpCgHzeY99rNp7rM/r3x920YGGZVKfl9XNek0mfrWQFY4yn1eSNpf iiduZCAL4t3a9U5m7GejQbKmMEZPnmZCQSumwvr6TejYVCyykz60SwRMXBGGN2V06B8M CBCBiEiHtPUmPQuI5ZTYiehUXruSN58JauXoJWSQ6TKnP0tjW9wZuZP8AdIgSvLTBMYi kRTGSyKR5ww63QBvcp3I71K5uKsMe1oETfxf1kQN8LrIf9xSwS6kJehUT/uofwqvdyb4 jJNQ== X-Gm-Message-State: AO0yUKWXKIARtNFzZ54oFqCsZGXwRwgXYGSo7knsWEjVjJWBLykJgLt0 nA85sf383zO73xlGc2hafGQLFZOBL0MhSOOU X-Google-Smtp-Source: AK7set+QL59ObXAJcn9Uny+h5O95bcK0Cy3qUH2J2CdoQ1+DoVOmfbH/JdDQYzzsKNgFIrfgguv1VQ== X-Received: by 2002:a17:907:3da7:b0:7e0:eed0:8beb with SMTP id he39-20020a1709073da700b007e0eed08bebmr13423071ejc.41.1677746139321; Thu, 02 Mar 2023 00:35: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 p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:38 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 1/9] riscv: Add basic XThead* vendor extension support Date: Thu, 2 Mar 2023 09:35:26 +0100 Message-Id: <20230302083534.4076244-2-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 Thu Mar 2 08:35: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: 65888 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 C626A3854153 for ; Thu, 2 Mar 2023 08:36:21 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by sourceware.org (Postfix) with ESMTPS id 7E0A33858C83 for ; Thu, 2 Mar 2023 08:35:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7E0A33858C83 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x530.google.com with SMTP id a25so1969061edb.0 for ; Thu, 02 Mar 2023 00:35:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746141; 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=V1aDJarezix64IlYgzEiVjtY/TEd41dbNpF7a3ZRrRgZAyRi+hXlQne+05SYCkKCGD YVv9LRhX+xfxxOXkWnVemEOT8VqAH2aUlvoU+ghiSy9D33QS4l6D3WXrXLGc87PpO88m rYkWuKE54I0KGfq3ghJwCvI5vLfVOfKXzGzFdlm5Qhqn8X3iegYhtuz6FCtMw408xWBF Gc6ZcwnlKIpuk/X4ExsG67KKewybKzhvDJLtanKu/jFgTV1YgAtxZbDC/zTuzwpHxZEQ gSlDuYnKFG3s/VSYHv19wtS/pyR7OtQZqEHtbtE1LbEcKsu7ieyg1871HhbmU4xVijzJ z0dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746141; 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=RKAyUxn5CRAaQxejQ9QT3x4lTPRK2LduCl8s1VOwivgT9Rtu6y3swyMI5gvENUFI09 xMORWS66X6/8bhgOpW++JHU8h+6hbetkyw7EPlwOh/LKhsRNeO6M0GH2LVNv8K2R8Q7R X10AQQgFH5Cq7RuQgUkiOuEuQn34u4WAVpmn7flE5ATt2tv5/r6nLCcX9oDOXNa1o8PP GRkE8t3lr6YmpgZSySdA9m09DdqCV+uTeQfNst64f0WamS8R/DhnbPpPrP9IFbeIoDoe 2EXGoP9+hZ3bFG/b8otJ4VAbNgHXGgykdscbJPiqa8bmC5jARu+onuWSNllKimpN3uF7 Wwcw== X-Gm-Message-State: AO0yUKXGMfk+w1LDrC2m01qDYgO5dkXtvukdEl0XYqCkLNhPd7Gpi3DL g13MJRcaMlAHjegMkx2KxWjXCDyOh43VPZeA X-Google-Smtp-Source: AK7set+jkd5ylCgnDJ0LF+n0+7GUWn7nNnbeXhi5803EcUciqsPYttcF44WFif3Z0PhgTRuEX02Bug== X-Received: by 2002:a17:907:a0c8:b0:8b1:7de3:cfaa with SMTP id hw8-20020a170907a0c800b008b17de3cfaamr14272732ejc.3.1677746140937; Thu, 02 Mar 2023 00:35:40 -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 p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:40 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 2/9] riscv: riscv-cores.def: Add T-Head XuanTie C906 Date: Thu, 2 Mar 2023 09:35:27 +0100 Message-Id: <20230302083534.4076244-3-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 Thu Mar 2 08:35:28 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: 65890 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 62CA4385022C for ; Thu, 2 Mar 2023 08:37:03 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by sourceware.org (Postfix) with ESMTPS id 0848C3858C53 for ; Thu, 2 Mar 2023 08:35:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0848C3858C53 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x529.google.com with SMTP id s11so471719edy.8 for ; Thu, 02 Mar 2023 00:35:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746142; 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=vuNbq6CbrFrvHwIU1bb4WPM0Z/DlyK4Wnr9ea027iM8=; b=QPVtu2AAISYyZyF33+v+jKngzrAhnbwJNmXXxN5yRTU9LZqbw/sXKyWlWxNeFeH8/9 q5zrsRDinXAet0NjBB/ZpHR2iWUEmt+rS/oGdc+yU437G86q+DsStsXcmHr0Be/jq2Ub GOP4vZVZQFJG5jr0MFOKhyCUKuI/u82tcJCZXh2AklbXX0+kwh0E3/QZuJvBWxJo5FmX HywDByJY2Pac1enyJXWPKASkXAvDieEsf97RZjwWMU7EULqaua9YhDqF14wdm1Y7Bg0m oOKnBpOaMNOLkqrl/9LycNDREG4InOBKnA59nZmns3mIoox4qHQGDa76zEJZl38whOO2 /QpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746142; 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=vuNbq6CbrFrvHwIU1bb4WPM0Z/DlyK4Wnr9ea027iM8=; b=0nqBQelrKyybXF6WyNUd3nzoIw7GEBG5V/0syH/ejc+yDSuBbzAzj0Be0N2FatxD58 x2YyZ4qw3TfENd9gC3ec+71M0IpERxBNvecOZy0uB3fFQF4IEMXSoxfxow9UMa7+9xp/ SR84qmpRUl/kf+rcdMS6cvx2liAbeZUC68nzdmZYPQ11yaBLGUQKDFjsZJHCAIWmDMk1 dgEkim/yESqk3We9/bDoOn/pi7m9U9BcLF7XkyOltSEYMtVVVyD/AwsuoKz6h2dYbrDa ktmhZ9/FXahEOPOCpukVUcW8OkJIAOuyq8U7dXXyddZ8Y5dmRwbtXdTlvpR4Q9OgCX9q /+kw== X-Gm-Message-State: AO0yUKXV9W2FmcLYZqn1h06Zo5MZ/S2VJAyZoyuN1wuGT+zOAbViLpoO jFecbyFYqlHjOpdU2aQfOL0m5qO1znxjUMAV X-Google-Smtp-Source: AK7set/9XB34rV8tUrs+cjGbkMLY3w7x+Wl/v6TqYltPOmpeQgCuPuT7QbJN0pRlHxo3BuyCppfzEw== X-Received: by 2002:a50:fb02:0:b0:4c0:1f45:c194 with SMTP id d2-20020a50fb02000000b004c01f45c194mr1348531edq.12.1677746142137; Thu, 02 Mar 2023 00:35: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 p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:41 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 3/9] riscv: thead: Add support for the XTheadBa ISA extension Date: Thu, 2 Mar 2023 09:35:28 +0100 Message-Id: <20230302083534.4076244-4-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 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 v4: - Replace 'immediate_operand' by 'const_int_operand' - Add number of arguments to pattern name 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..2da5aaee94f --- /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_addsl4" + [(set (match_operand:X 0 "register_operand" "=r") + (plus:X (ashift:X (match_operand:X 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n")) + (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 Thu Mar 2 08:35:29 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: 65889 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 48BBA3850402 for ; Thu, 2 Mar 2023 08:36:51 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by sourceware.org (Postfix) with ESMTPS id B5551385842C for ; Thu, 2 Mar 2023 08:35:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B5551385842C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x52b.google.com with SMTP id x3so1477838edb.10 for ; Thu, 02 Mar 2023 00:35:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746144; 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=wAqXfo7+5IP14ySE80w5vDqMIr4VdiAug7HDCySEHic=; b=ajOXkYHe56TQVPdiQ3YpUGEeZrR+Ac3dMvxhLlokhEhV2s4SiaxPAvu6FYLFZcQALl CyBKPFuYRb/YSK4HUTQub9OGF5zcSt9Ai9URGlOGG9FEpI5nWIyqojjZmnFeqlKvi3O1 7+aRyyyFXA9Zvjf7goEPLwEUankfaczurYaEv5NQ+0r6gRIUi+dXuETD8lBVe3wVXN4/ SbkdNqb238EnKGH2c2ltzJ0j7lRijHMQGNYSF3Gld3laQB6/G5TfWKD+LY7xviWKpOY2 L81FliQ2M2Q1eM/b5OSbgwJ2JIGn3C654B10LWvNfFfj152pagyDWV1g5k7fvBF3fOsH LWjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746144; 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=wAqXfo7+5IP14ySE80w5vDqMIr4VdiAug7HDCySEHic=; b=BvAbJPA7EyhuH4+wNz6J2j9aM45OTeuNNdWAEIIB5D/ta5MliDHObFlxlyJbQKllQc XxLDkZ/jSZT7FZgFEFun7vs9NhgHUZXJS+lcLIzWbu/GaXAYqglWwnwXi6wvftOYPK2v 0n18ouN3iDiY0bTpyV83kv6p1DquMOEIh+5YY4MCFC26dBlFgZ1ILty+1Idu2CYrlKmq zL3DXmGX2L4iWriBTKXHHrohWtv6QoVHtjRcTeF/g0WW1PofKyma+yZmO3Hr3VsvFTYd yhbOETizugsS4K6h/xa2M7Q0K+2jW5CsdAMOQysqTZWa7XXfSRsxE+EggY8kFKDNQpit yBaQ== X-Gm-Message-State: AO0yUKVvDJBAVtUhaHCreqVQIAfJNabAKpXhizrLeahevfP3j+PMf254 dDc0kZ92cTnJmWITjMqGmNjxbSErthkDzFOG X-Google-Smtp-Source: AK7set/na3apJ5tIi3t417YKXxzSch+EmSWQu0HC5iD+gCyxuz+Ap7hZdHTNjL9nMrmX4HTDXqG9nQ== X-Received: by 2002:a17:906:bcf7:b0:89e:8c3d:bb87 with SMTP id op23-20020a170906bcf700b0089e8c3dbb87mr10342100ejb.71.1677746143984; Thu, 02 Mar 2023 00:35:43 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:43 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 4/9] riscv: thead: Add support for the XTheadBs ISA extension Date: Thu, 2 Mar 2023 09:35:29 +0100 Message-Id: <20230302083534.4076244-5-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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_tst3): New INSN. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadbs-tst.c: New test. Changes in v4: - Replace 'immediate_operand' by 'const_int_operand' - Add number of arguments to pattern name - Add range check 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 2da5aaee94f..3842a194d16 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -29,3 +29,14 @@ (define_insn "*th_addsl4" "th.addsl\t%0,%3,%1,%2" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) + +;; XTheadBs + +(define_insn "*th_tst3" + [(set (match_operand:X 0 "register_operand" "=r") + (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "const_int_operand" "n")))] + "TARGET_XTHEADBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)" + "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 Thu Mar 2 08:35:30 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: 65891 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 BA0FF384D19A for ; Thu, 2 Mar 2023 08:37:21 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id 119143858C54 for ; Thu, 2 Mar 2023 08:35:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 119143858C54 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x52f.google.com with SMTP id g3so9001049eda.1 for ; Thu, 02 Mar 2023 00:35:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746145; 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=pc7OF2xK1PlmeHT84BgouqI8O26BnIBBkbWZ+fCu4vE=; b=XjyhLP4AB1EWviWJTDGM1gpDU3OXItQA+iiS1o4Z6vElkL8Gp/LPm7hL2K/XBismrC 7CkB8lgo88KyiKB8SaqHF/CfLisjRYHP1Nz1m2QHFawxWfetZrtN+W/WG2FU2pAW7H53 RG6WeSNDDA3SYX/RBmLQ+P/Ko30CvalGqAQ71JaAkgR4fwhSDzDubSYihgGCMI+UL6oY SLhnAG/zsnI1WBuGcIZkZZZOTIVC4jU63zyL/TbaSGi0fpeAipXodiuDw6zLGAwkt2yA Nv+WHlVTWXbvdTbniMpTvTCDkG53hmCc/pe0Ck/u1Ajm+hxgR3Aa5Ybuq/GC+4sFEeNs /ENw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746145; 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=pc7OF2xK1PlmeHT84BgouqI8O26BnIBBkbWZ+fCu4vE=; b=wpNWvtFjs0tKNUC0gshmC+R1U/BMpPHWWMeR7FvNa6uevvNDB2iPIob6c8XMnfCzmV ANIOobmrhNwhQZDYgQNbpDc0bj6z0so+JuvbZYKqYXqvHurxufmB556Agvj33r/QvrYi Y5Jj/hX2f3Y2VpNdnN6cAZ51xtLnTCnRToBp0TgNwf5Ga4ZwGrEn1SJ4x3QpmrjqK7De xYwd9r3ygfAqkMfLFC/lJSJ+3it/3B62fhwXNcP8FPC+uevfXKoBJ+wj1SnvVdLXNXsT Z3lcYdKitbhPNur3k0J4AnlqfI4o7axOp0o0ub//Qx+xRShy3vJSUPJx4JmP7m+H5mKH souA== X-Gm-Message-State: AO0yUKXKJL8jN3SOiy6nVUpkRBfkLj907SqeoBB6dsg6DwuPKHBJjtkp kocagdUe0toFlIVX+1MZWPivNfpAu9k1vT5o X-Google-Smtp-Source: AK7set8bm96sg5t5fgPZdeah9ZDhQrhpauPf6B77VpGkKej3waf4Ge3DalfOHmz/FqUrbiMW8tuq5w== X-Received: by 2002:a17:907:d50c:b0:881:23a:aba5 with SMTP id wb12-20020a170907d50c00b00881023aaba5mr10471648ejc.11.1677746145291; Thu, 02 Mar 2023 00:35: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 p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:44 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 5/9] riscv: thead: Add support for the XTheadBb ISA extension Date: Thu, 2 Mar 2023 09:35:30 +0100 Message-Id: <20230302083534.4076244-6-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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_srri3): New INSN. (*th_ext): New INSN. (*th_extu): New INSN. (*th_clz2): New INSN. (*th_rev2): 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 in v4: - Replace 'immediate_operand' by 'const_int_operand' - Add number of arguments to pattern names - Merge th_srri3 patterns - Merge th_rev2 patterns - Improve coverage of th.srri 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 | 61 +++++++++++++++++++ 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 | 25 ++++++++ 10 files changed, 288 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 3842a194d16..372d4603543 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -30,6 +30,67 @@ (define_insn "*th_addsl4" [(set_attr "type" "bitmanip") (set_attr "mode" "")]) +;; XTheadBb + +(define_insn "*th_srri3" + [(set (match_operand:GPR 0 "register_operand" "=r") + (rotatert:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n")))] + "TARGET_XTHEADBB && (TARGET_64BIT || mode == SImode)" + { + bool wform = TARGET_64BIT && (mode == SImode); + operands[2] = GEN_INT (INTVAL (operands[2]) + & (GET_MODE_BITSIZE (mode) - 1)); + return wform ? "th.srriw\t%0,%1,%2" : "th.srri\t%0,%1,%2"; + } + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*th_ext4" + [(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_extu4" + [(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_rev2" + [(set (match_operand:GPR 0 "register_operand" "=r") + (bswap:GPR (match_operand:GPR 1 "register_operand" "r")))] + "TARGET_XTHEADBB && (TARGET_64BIT || mode == SImode)" + { + bool wform = TARGET_64BIT && (mode == SImode); + return wform ? "th.revw\t%0,%1" : "th.rev\t%0,%1"; + } + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + ;; XTheadBs (define_insn "*th_tst3" 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..973ed175f17 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c @@ -0,0 +1,25 @@ +/* { 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) +{ + unsigned sz = sizeof(unsigned long) * 8; + unsigned shamt = sz - 11; + return (rs1 << shamt) | (rs1 >> (sz - shamt)); +} + +unsigned int +foo2 (unsigned int rs1) +{ + unsigned sz = sizeof(unsigned int) * 8; + unsigned shamt = sz - 11; + return (rs1 << shamt) | (rs1 >> (sz - shamt)); +} + +/* { dg-final { scan-assembler-times "th.srri\t" 2 { target { rv32 } } } } */ + +/* { dg-final { scan-assembler-times "th.srri\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.srriw\t" 1 { target { rv64 } } } } */ From patchwork Thu Mar 2 08:35:31 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: 65892 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 9E1CF384F488 for ; Thu, 2 Mar 2023 08:37:22 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by sourceware.org (Postfix) with ESMTPS id 80F33385840F for ; Thu, 2 Mar 2023 08:35:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 80F33385840F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x531.google.com with SMTP id x3so1478289edb.10 for ; Thu, 02 Mar 2023 00:35:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746147; 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=j3HukEc6ED2T7YDVmmiNnPdfhm7jVdnfxr6la9SxRCc=; b=e3aj8veulzVkcbwIyEzyHNgZ4OhGMwRL2XsCIAhYyEU9vevGiOK9DgK9pMkhw0pc42 6AIofwSCxQWlz/pZfh8zhAJcamJpOzidZ7e5w9qxATH97XV/Yy9QWhFLVTU95rBZ9/DX M4cUljdLS88scEabYzrclJpPvCQAVWLNBIOUC330O+dp2/l9rHEf429eoefbM5B9I9kv Ch+/nkiLotiniiofdCZ74slDvZKzkXM21cLMfAQeuf3bo6Lj6sjrxKkONUYYXQiC/ajH KO1GKkmBq6BexjYBG9o18JR74I0jQvAAU+BUtm78eBuhz2thPO/pcxBb/yY+sdhBdEME +++g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746147; 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=j3HukEc6ED2T7YDVmmiNnPdfhm7jVdnfxr6la9SxRCc=; b=NfaLgszlQRUVJOl+3rK2m/A7/2uO9TGNhafb8l1NSeMn5VwMzEkH0ozNInZjsLOoms WCsyj8YbF/kp47YyU+iggH8pXrTcQ6QpHAhS+S5hsONTRm20tfuSRWwOaISC1eQOW2Wf u1VCY7H644Q1FnYOrcwJHiaHRoK6GuhR1xXygbwvRgd3xESbeeMJgK8RBnJ01E4lQJfy IRH/mx73VayFjVwMqg8TN+jZ3KBo4ihfzENTXwxziJBAtFrtrW9aCNDXESQ+YFbehG/x LQK1ANc9mXddPH0nwvlB/szfzIBi12ySbgpf5iEB2UfLwL2cj/SrotpfSU2CL0Co68eB hCbQ== X-Gm-Message-State: AO0yUKWjLvTXsoWNyH/fYI+qoG6/nwU5oJknIC3hSCQLZyN9eehiTkgn 6HjjcLGbO1+kS8zvvjRY4Rm+sLFTo9uoanB8 X-Google-Smtp-Source: AK7set9Pm+KBPvM0+ayb61anvVJXVF+9kp3zKpDFyDA4FUUkSZaCz34Wif1zso/vQ3vl5BrOgDFjJg== X-Received: by 2002:a17:906:a943:b0:87f:5d0a:c610 with SMTP id hh3-20020a170906a94300b0087f5d0ac610mr9452725ejb.32.1677746146814; Thu, 02 Mar 2023 00:35:46 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:46 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 6/9] riscv: thead: Add support for the XTheadCondMov ISA extensions Date: Thu, 2 Mar 2023 09:35:31 +0100 Message-Id: <20230302083534.4076244-7-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 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 372d4603543..88b6a95e993 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -101,3 +101,40 @@ (define_insn "*th_tst3" "TARGET_XTHEADBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (mode)" "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 Thu Mar 2 08:35:32 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: 65894 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 534A93881D2E for ; Thu, 2 Mar 2023 08:38:00 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id E38C3385842B for ; Thu, 2 Mar 2023 08:35:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E38C3385842B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x532.google.com with SMTP id g3so9001476eda.1 for ; Thu, 02 Mar 2023 00:35:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746148; 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=SqOf0suC870UaAD0M4ZvhPFAOl1GF33Z7kTno04gBhY=; b=kHOl70qbOSCLi3RmYQH5DrcEaAErECKyCeocJTrf/OfRFMELK0svxXLguvVWyuB9x2 83nYKCXPQiFd2c2IExdH/iqjejmqxui7qc+lxFfYPguZLuzQvnbEL2oogU4GgpHRcb8y 2JcZnNddilkgZQ+mUBm5TTZL2Zh03kJa5Q4J/AHP1pLriMq+3qTle4vQ8sbf47aYYUeP ULibQWgDd9rs1dkhjg1eKdq3//vNqrChTF30JVwR/ksmU7ZUMtd9lhii0n4SN/Zt/Sp8 my3DgTTLS3k9AOCLqcyP0NjUqrqfzBQ1qvgN7jkFWLQaCqabwBaYQoPS0gUiJ4/p8sTX g51A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746148; 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=SqOf0suC870UaAD0M4ZvhPFAOl1GF33Z7kTno04gBhY=; b=WLhT78ZGOl7nF/J/kRri4EBH653MCZ6XXRSbSYVeYvJCaAWgCYykR0LbaAgIrW0yX9 SnpCrcXcuC+1D6U718e6cbTihz38OHdMHhxUcuRbg82KrjsDctdulh09xsW1Y2rOqDAN NKCIvYR+hWtkdSLEQg0wUsMe98dEowuAEF2SggsGlqTpXWGqKth0RBFyDhZOnQpYEGFC muLK+8h7PkBrhsFts+k7PfaZasjvj1ZAzP/eHmJzN8PhXDFlY0DQK6/9viVmE1Q3WMv/ 0fwbnyxTKdrRcc8ISUl9Cyd2LnwPcRhfhjSqYO2vm+zVi36xmgMke2OgxAMScRV6Bkg1 6xiw== X-Gm-Message-State: AO0yUKVKbb2BgIS3X5MHgM/T3SZlMi0me3cY/aI2sm48GxK1Hwdf0jtb UWBJvns/ZpGVSBxLpMRHGFQfpTYR1W357C59 X-Google-Smtp-Source: AK7set9Bk6TYny1SURajFI9VM8uXvYbB88wxx5tOcSrcOnmk87NhkF9jNZy89Cq0OsWFoAQB/ezNGQ== X-Received: by 2002:a17:906:7388:b0:87b:7c1d:e02b with SMTP id f8-20020a170906738800b0087b7c1de02bmr9700299ejl.36.1677746148231; Thu, 02 Mar 2023 00:35:48 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:47 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 7/9] riscv: thead: Add support for the XTheadMac ISA extension Date: Thu, 2 Mar 2023 09:35:32 +0100 Message-Id: <20230302083534.4076244-8-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 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 88b6a95e993..ce709ca79a4 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -138,3 +138,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 Thu Mar 2 08:35:33 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: 65893 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 A845438560A6 for ; Thu, 2 Mar 2023 08:37:47 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id 9FE8D38582BC for ; Thu, 2 Mar 2023 08:35:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9FE8D38582BC Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x534.google.com with SMTP id da10so64535620edb.3 for ; Thu, 02 Mar 2023 00:35:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746150; 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=RiEqSFTvvu0UM+NyoFMRky1hW9pgX7eohw454dq1Fb4=; b=pQLPv7h4Z+RGlVSiZ++1nolHYdNC1BggGE1jMXV+W0hikRatFF46xiQdzpvljeqj6W Oh3H8DTe5Rfru/hdpgo+a91V+N8XKE4FU1l3S15obzedQ5tXDvh7gBUPhZrvMmjgwAFO xOzmfbtt7e9QE/XJIyNwTyK5ywWgmyDuL0G5rxvtpZt4RrfWvMK5oymA1BUboAksIm+K FZJLfBn2rL6cb52nmrmwiPRNzGeGO6fmYoRqNPXlyalAKyRyJ42QrhV3xwZM3iSzrlPW BzW97MSE+Q33PGxrHDEwQkspi3vn3fNmoSKQi9kcJ+1d+mrkIyv4VAjGcahT/GWJ2fCq GMrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746150; 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=RiEqSFTvvu0UM+NyoFMRky1hW9pgX7eohw454dq1Fb4=; b=PX2cCF21X3B0yiXl0pwZfe5IP7lwvSGBxtMXGL9VPbQrNDaAHLHntQCLoyoOTxIjYM ud5IriyMot2kM5e+QlAu4UYWU16CjAa7IFae6ucwlEgNuSz+Lf1sfd/jyN25LxhdG+wS F76jQvDhmnqO+ElHS2u7Fe9XMV+AkkyxzMdlclVYFS7SEx8b3Dilg93q8EHVfaxcWEJt UnXCMYQAkM2mBGq8gMmUH5aMVqmiJLnTjpAgxXJqVlpxIRjjcJupFdQ4IcpGdB2e2Z+9 P6U2PUsOWuQZUuWTCCalxcvi3MwuGy3oWmk3qPqYmIfx6AftGFvvNJzSSdLdcCeGhDoi YilA== X-Gm-Message-State: AO0yUKUhacMb81B1CH8LuLYsQUhNKZTzkhKz+b8WJR5Dhdw8qJSjUOJL eICY9NUQLbu5xideJZXnAPv6RC1qrAUa3lkI X-Google-Smtp-Source: AK7set+H0p4Oc7zHp3+jJLl9iTBx8qzP+8dR0O44HuMPFDyPKn1P6Qo9K1Wta8t9QCe4PptgXKjfUw== X-Received: by 2002:a17:907:9721:b0:8af:2cf7:dd2b with SMTP id jg33-20020a170907972100b008af2cf7dd2bmr10824388ejc.13.1677746149771; Thu, 02 Mar 2023 00:35: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 p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:49 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 8/9] riscv: thead: Add support for the XTheadFmv ISA extension Date: Thu, 2 Mar 2023 09:35:33 +0100 Message-Id: <20230302083534.4076244-9-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-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 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 ce709ca79a4..b0a71d595fd 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -139,6 +139,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 Thu Mar 2 08:35:34 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: 65895 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 8619B385021B for ; Thu, 2 Mar 2023 08:38:21 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by sourceware.org (Postfix) with ESMTPS id BEE023858428 for ; Thu, 2 Mar 2023 08:35:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BEE023858428 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ed1-x52b.google.com with SMTP id x3so1478992edb.10 for ; Thu, 02 Mar 2023 00:35:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1677746152; 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=yC22w2T1sNOAMLhtcQIXxfE2yqDWSwV1nn4wK8JCgs0=; b=L/Pq68Vs9wU6uXidMlhQc7rAEe3e3IrVB0D8Z8aXjuF+uaTrDTTDyBq5OWUlYuJRdg rr6fX6GYBV+fTXRiLERzunpJw7lQwZGRuAuSBqcsLbjn+JFWXka9v1OtuMMq3eb1I7e4 uODOTeRAjyUX6Qfg51rTLV0O8OAEl3YwHAkSVcwOt5izUUmy56vTWrsb15aj8TNFdlLb ROyuWxQ+wH8vh/U7zTScFlDoeS6s+8e4A1bzxIaNkgmAJqt9Rp2KaMecgJDPcxObYOVq +7uZhuLoEpzaCjRAeLl8lXhTv+FpjBT6nL6WxjS0WWffLAfVkRWOp1H6TDgUC1cdTTAp 7W8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677746152; 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=yC22w2T1sNOAMLhtcQIXxfE2yqDWSwV1nn4wK8JCgs0=; b=j55pXOlppt7MKF4+17byGULN7whpj/+5V29XhNe2VTW1KTrDyzw2YO7o8HDnqxn0r+ Zr+gLAtqZHn9Rv0Xu6ilFhIzfpc8SRvr36muANsUlMVxxWD5YbOc4vuUTbaOEUiCzXi1 VTCsVmfOwMos9uOM5wgrY7sGEA7T0HAYx6OuTYdDAEoIkzC2cEUJUHl1FsitkKhhZiRJ SHBvOYE4UYLLKzNLpihb1c+JE9aAJLAn4RAK1IBRFWx7zzl+ViMJzt5LSmyvy68ExG9Z tjOsMFJrPT1F6qfsPs7YbpocDF8Knrp3cR52eKxxY4ZQssRmVdMBZL8atWvs8M6Zs5jW RMIA== X-Gm-Message-State: AO0yUKUKZbnOp6a79f9cGSEFGADzHdx9s9pEkpb9FPzAc2D0a0CxcISH ImaO3uhrf8Bd2FJ8xalcgkGC+CUeKB9pAaf/ X-Google-Smtp-Source: AK7set82ExBpSw+ypIKRSeJSiVRpFrMqP96S2bgwKKAPbj2FaBOBlWKY6V29jngoHJxpLr8hv2TGig== X-Received: by 2002:a05:6402:b1c:b0:4be:b37d:6134 with SMTP id bm28-20020a0564020b1c00b004beb37d6134mr3179228edb.5.1677746151559; Thu, 02 Mar 2023 00:35:51 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id p17-20020a170906229100b008e68d2c11d8sm6853872eja.218.2023.03.02.00.35.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:35:50 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu , Andrew Pinski , Hans-Peter Nilsson Cc: =?utf-8?q?Christoph_M=C3=BCllner?= Subject: [PATCH v4 9/9] riscv: thead: Add support for the XTheadMemPair ISA extension Date: Thu, 2 Mar 2023 09:35:34 +0100 Message-Id: <20230302083534.4076244-10-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230302083534.4076244-1-christoph.muellner@vrull.eu> References: <20230302083534.4076244-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-11.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, 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.gcc: Add thead.o to RISC-V extra_objs. * config/riscv/peephole.md: Add mempair peephole passes. * config/riscv/riscv-protos.h (riscv_split_64bit_move_p): New prototype. (th_mempair_operands_p): Likewise. (th_mempair_order_operands): Likewise. (th_mempair_prepare_save_restore_operands): Likewise. (th_mempair_save_restore_regs): Likewise. (th_mempair_output_move): Likewise. * config/riscv/riscv.cc (riscv_save_reg): Move code. (riscv_restore_reg): Move code. (riscv_for_each_saved_reg): Add code to emit mempair insns. * config/riscv/t-riscv: Add thead.cc. * config/riscv/thead.md (*th_mempair_load_2): New insn. (*th_mempair_store_2): Likewise. (*th_mempair_load_extendsidi2): Likewise. (*th_mempair_load_zero_extendsidi2): Likewise. * config/riscv/thead.cc: New file. 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 v4: - Unify function prefix ("th_") - Move th_* functions to thead.cc - Minimize code in CFA code in riscv.cc 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.gcc | 1 + gcc/config/riscv/peephole.md | 56 +++ gcc/config/riscv/riscv-protos.h | 14 + gcc/config/riscv/riscv.cc | 88 ++-- gcc/config/riscv/t-riscv | 4 + gcc/config/riscv/thead.cc | 427 ++++++++++++++++++ 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 ++ 10 files changed, 824 insertions(+), 29 deletions(-) create mode 100644 gcc/config/riscv/thead.cc 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.gcc b/gcc/config.gcc index c070e6ecd2e..ad0b6d3302a 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -531,6 +531,7 @@ riscv*) cpu_type=riscv extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o riscv-v.o riscv-vsetvl.o" extra_objs="${extra_objs} riscv-vector-builtins.o riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o" + extra_objs="${extra_objs} thead.o" d_target_objs="riscv-d.o" extra_headers="riscv_vector.h" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.cc" diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index 0ef0c04410b..67e7046d7e6 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 + && th_mempair_operands_p (operands, true, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + th_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 + && th_mempair_operands_p (operands, false, mode)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])] +{ + th_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 + && th_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)))])] +{ + th_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 + && th_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)))])] +{ + th_mempair_order_operands (operands, true, SImode); +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 5cf4fafd662..6b2d1c722b4 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -54,6 +54,7 @@ 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 (); + #ifdef 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); @@ -200,4 +201,17 @@ const unsigned int RISCV_BUILTIN_SHIFT = 1; /* Mask that selects the riscv_builtin_class part of a function code. */ const unsigned int RISCV_BUILTIN_CLASS = (1 << RISCV_BUILTIN_SHIFT) - 1; +/* Routines implemented in thead.cc. */ +extern bool th_mempair_operands_p (rtx[4], bool, machine_mode); +extern void th_mempair_order_operands (rtx[4], bool, machine_mode); +extern void th_mempair_prepare_save_restore_operands (rtx[4], bool, + machine_mode, + int, HOST_WIDE_INT, + int, HOST_WIDE_INT); +extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode); +#ifdef RTX_CODE +extern const char* +th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE); +#endif + #endif /* ! GCC_RISCV_PROTOS_H */ diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 48f2cb399ae..20af3506275 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4963,6 +4963,35 @@ riscv_set_return_address (rtx address, rtx scratch) riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address); } +/* Save register REG to MEM. Make the instruction frame-related. */ + +static void +riscv_save_reg (rtx reg, rtx mem) +{ + riscv_emit_move (mem, reg); + riscv_set_frame_expr (riscv_frame_set (mem, reg)); +} + +/* Restore register REG from MEM. */ + +static void +riscv_restore_reg (rtx reg, rtx mem) +{ + rtx insn = riscv_emit_move (reg, mem); + rtx dwarf = NULL_RTX; + dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); + + if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM) + { + rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (epilogue_cfa_sp_offset)); + dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); + } + + REG_NOTES (insn) = dwarf; + RTX_FRAME_RELATED_P (insn) = 1; +} + /* A function to save or store a register. The first argument is the register and the second is the stack slot. */ typedef void (*riscv_save_restore_fn) (rtx, rtx); @@ -5057,6 +5086,36 @@ 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); + + /* 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))) + { + bool load_p = (fn == riscv_restore_reg); + rtx operands[4]; + th_mempair_prepare_save_restore_operands (operands, + load_p, word_mode, + regno, offset, + regno2, offset2); + + /* If the operands fit into a mempair insn, then emit one. */ + if (th_mempair_operands_p (operands, load_p, word_mode)) + { + th_mempair_save_restore_regs (operands, load_p, word_mode); + offset = offset2; + regno = regno2; + continue; + } + } + } + riscv_save_restore_reg (word_mode, regno, offset, fn); } @@ -5075,35 +5134,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/t-riscv b/gcc/config/riscv/t-riscv index d30e0235356..dc30ecff678 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -75,6 +75,10 @@ riscv-v.o: $(srcdir)/config/riscv/riscv-v.cc $(COMPILE) $< $(POSTCOMPILE) +thead.o: $(srcdir)/config/riscv/thead.cc + $(COMPILE) $< + $(POSTCOMPILE) + PASSES_EXTRA += $(srcdir)/config/riscv/riscv-passes.def $(common_out_file): $(srcdir)/config/riscv/riscv-cores.def \ diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc new file mode 100644 index 00000000000..75203805310 --- /dev/null +++ b/gcc/config/riscv/thead.cc @@ -0,0 +1,427 @@ +/* Subroutines used for code generation for RISC-V. + Copyright (C) 2023 Free Software Foundation, Inc. + Contributed by Christoph Müllner (christoph.muellner@vrull.eu). + + 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 + . */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "backend.h" +#include "rtl.h" +#include "memmodel.h" +#include "emit-rtl.h" +#include "poly-int.h" +#include "output.h" + +/* 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 +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 * +th_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"; + } + + split_plus (XEXP (mem1, 0), &base1, &offset1); + 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 +th_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 +th_mempair_operand_p (rtx mem, machine_mode mode) +{ + if (!MEM_SIZE_KNOWN_P (mem)) + return false; + + /* Only DI or SI mempair instructions exist. */ + gcc_assert (mode == SImode || mode == DImode); + 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; + 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 +th_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; + 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 +th_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 (th_mempair_load_overlap_p (reg_1, reg_2, mem_1)) + return false; + if (th_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 (!th_mempair_check_consecutive_mems (mode, &mem_1, &mem_2, &reversed)) + return false; + + /* The first memory accesses must be a mempair operand. */ + if ((!reversed && !th_mempair_operand_p (mem_1, mode)) + || (reversed && !th_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 +th_mempair_order_operands (rtx operands[4], bool load_p, machine_mode mode) +{ + int mem_op = load_p ? 1 : 0; + bool reversed = false; + if (!th_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]); + } +} + +/* Similar like riscv_save_reg, but saves two registers to memory + and marks the resulting instruction as frame-related. */ + +static void +th_mempair_save_regs (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)); +} + +/* Similar like riscv_restore_reg, but restores two registers from memory + and marks the instruction frame-related. */ + +static void +th_mempair_restore_regs (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]); +} + +/* Prepare the OPERANDS array to emit a mempair instruction using the + provided information. No checks are performed, the resulting array + should be validated using th_mempair_operands_p(). */ + +void +th_mempair_prepare_save_restore_operands (rtx operands[4], + bool load_p, machine_mode mode, + int regno, HOST_WIDE_INT offset, + int regno2, HOST_WIDE_INT offset2) +{ + int reg_op = load_p ? 0 : 1; + int mem_op = load_p ? 1 : 0; + + rtx mem1 = plus_constant (mode, stack_pointer_rtx, offset); + mem1 = gen_frame_mem (mode, mem1); + rtx mem2 = plus_constant (mode, stack_pointer_rtx, offset2); + mem2 = gen_frame_mem (mode, mem2); + + operands[reg_op] = gen_rtx_REG (mode, regno); + operands[mem_op] = mem1; + operands[2 + reg_op] = gen_rtx_REG (mode, regno2); + operands[2 + mem_op] = mem2; +} + +/* Emit a mempair instruction to save/restore two registers to/from stack. */ + +void +th_mempair_save_restore_regs (rtx operands[4], bool load_p, + machine_mode mode) +{ + gcc_assert (th_mempair_operands_p (operands, load_p, mode)); + + th_mempair_order_operands (operands, load_p, mode); + + if (load_p) + th_mempair_restore_regs (operands); + else + th_mempair_save_regs (operands); +} diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index b0a71d595fd..63c4af6f77d 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -292,3 +292,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 + && th_mempair_operands_p (operands, true, mode)" + { return th_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 + && th_mempair_operands_p (operands, false, mode)" + { return th_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 + && th_mempair_operands_p (operands, true, SImode)" + { return th_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 + && th_mempair_operands_p (operands, true, SImode)" + { return th_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..34a29ab9c04 --- /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.lwud\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 } } } } */