From patchwork Thu Sep 23 07:57:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kito Cheng X-Patchwork-Id: 45341 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 CAC9B3857C52 for ; Thu, 23 Sep 2021 08:00:03 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by sourceware.org (Postfix) with ESMTPS id 28B0E3857C65 for ; Thu, 23 Sep 2021 07:57:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 28B0E3857C65 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com Received: by mail-pj1-x1036.google.com with SMTP id p12-20020a17090adf8c00b0019c959bc795so4300141pjv.1 for ; Thu, 23 Sep 2021 00:57:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Md0MlY0IBgOGwopl5z+3ZrODpX7nE/7Is0iNcW4Ldl0=; b=H/1dzIPN1uNnqW8PXZsFdaooi9+Lq9bjd68PmEkNqwYM2FYjTZqZrQkEZE59r8f70O qDDHh5vtC0YGkH22ft0/Yyjc//GIQeE93YM2FmplFfuGs7G8RFQhq/5Hjx4ajPHKOAv5 pshWa6sS3XQyfCa2nrNbSUDweJ9bCF5k6bf8FEhgQtkiaJfBzIFjHHttLFoR0U8FohlV 9wqdLcTiDHm0CR3oTz86q8SS8k2W/KcYpQUK7UWRn0NCDNDYuYVk3fQjHouMqTH6jWs/ lCl7R3c+ZOC5eOgz+Mphy5CBGHqhnnEUFSHrM10c/SDkENwVdyJ8d3LruWP5XX/+NIvG JWSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Md0MlY0IBgOGwopl5z+3ZrODpX7nE/7Is0iNcW4Ldl0=; b=w1lS4TFDbTyvtLDaKRUX1v/h916ji1UzlRlgihwMINCIJIKnIJO1/maRVgja4GOHqm u20NXrOpv+9dZ3B9+RiaA8f8XnJ9+52AXbkBLM5m4xBe9T4Wd1VpU5sYlyQOHWZNEgZT 5D1sB1wtM/FPGz3E2YiPYt/5CvxiDVBcY+okXbi2ATbz4rNp6tQA8ju/W+owJK0tY4tD JTaRPXC6Z1Iav4nE3VPHeP+KL05tqY2zF6kKQ6CK3//YA+p72BI8yZGKXQVySVNE0/Pe fF1yL/T8OL5/K2yWO992UMR5ClTHXhpABetnpqvxToaqXUQE6WYZU3hKM/SNlqndxUhF Dgow== X-Gm-Message-State: AOAM530STvOUo92A0CcD7NxSMgTfkfR1RcUQssepRx4Qm7c37ZOn1jUr bZyR2hh5gzCa/evsGgs5Xkt2+6oAkMfrIA== X-Google-Smtp-Source: ABdhPJzsyZSg59ZvTALJoanNIXnWxrs1F4Do+pY/LTvXakcY3eB6ErVu0Y/tC02dUy99NUMIwCu7Hw== X-Received: by 2002:a17:902:b711:b029:11e:6480:258a with SMTP id d17-20020a170902b711b029011e6480258amr2996095pls.41.1632383865786; Thu, 23 Sep 2021 00:57:45 -0700 (PDT) Received: from hsinchu02.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id pc3sm8132163pjb.0.2021.09.23.00.57.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Sep 2021 00:57:45 -0700 (PDT) From: Kito Cheng To: gcc-patches@gcc.gnu.org, kito.cheng@gmail.com, jimw@sifive.com, jiawei@iscas.ac.cn, cmuellner@ventanamicro.com, palmer@dabbelt.com, andrew@sifive.com Subject: [RFC PATCH 4/8] RISC-V: Implement instruction patterns for ZBB extension. Date: Thu, 23 Sep 2021 15:57:27 +0800 Message-Id: <20210923075731.50125-5-kito.cheng@sifive.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210923075731.50125-1-kito.cheng@sifive.com> References: <20210923075731.50125-1-kito.cheng@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kito Cheng Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Jim Wilson 2021-09-23 Jim Wilson Kito Cheng Jia-Wei Chen gcc/ChangeLog: * config/riscv/bitmanip.md (bitmanip_bitwise): New. (bitmanip_minmax): New. (clz_ctz_pcnt): New. (bitmanip_optab): New. (bitmanip_insn): New. (*_not): New. (*xor_not): New. (si2): New. (*disi2): New. (di2): New. (*zero_extendhi2_bitmanip): New. (*extend2_zbb): New. (*zero_extendhi2_zbb): New. (rotrsi3): New. (rotrdi3): New. (rotrsi3_sext): New. (rotlsi3): New. (rotldi3): New. (rotlsi3_sext): New. (bswap2): New. (3): New. * config/riscv/riscv.c (riscv_extend_cost): Handle cost model for zbb extension. (riscv_rtx_costs): Ditto. * config/riscv/riscv.md (type): Add rotate. (zero_extendhi2): Change to define_expand pattern. (*zero_extendhi2): New. (extend2): Change to define_expand pattern. (*extend2): New. gcc/testsuite/ChangeLog: * gcc.target/riscv/zbb-andn-orn-xnor-01.c: New. * gcc.target/riscv/zbb-andn-orn-xnor-02.c: Ditto. * gcc.target/riscv/zbb-min-max.c: Ditto. * gcc.target/riscv/zbb-rol-ror-01.c: Ditto. * gcc.target/riscv/zbb-rol-ror-02.c: Ditto. * gcc.target/riscv/zbb-rol-ror-03.c: Ditto. * gcc.target/riscv/zbbw.c: Ditto. Co-authored-by: Kito Cheng Co-authored-by: Jia-Wei Chen --- gcc/config/riscv/bitmanip.md | 164 ++++++++++++++++++ gcc/config/riscv/riscv.md | 21 ++- .../gcc.target/riscv/zbb-andn-orn-xnor-01.c | 21 +++ .../gcc.target/riscv/zbb-andn-orn-xnor-02.c | 21 +++ gcc/testsuite/gcc.target/riscv/zbb-min-max.c | 31 ++++ .../gcc.target/riscv/zbb-rol-ror-01.c | 16 ++ .../gcc.target/riscv/zbb-rol-ror-02.c | 16 ++ .../gcc.target/riscv/zbb-rol-ror-03.c | 17 ++ gcc/testsuite/gcc.target/riscv/zbbw.c | 25 +++ 9 files changed, 327 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-02.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-min-max.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-rol-ror-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-rol-ror-02.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbbw.c diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 3849d21dc15..4d624514049 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -17,6 +17,30 @@ ;; along with GCC; see the file COPYING3. If not see ;; . +(define_code_iterator bitmanip_bitwise [and ior]) + +(define_code_iterator bitmanip_minmax [smin umin smax umax]) + +(define_code_iterator clz_ctz_pcnt [clz ctz popcount]) + +(define_code_attr bitmanip_optab [(smin "smin") + (smax "smax") + (umin "umin") + (umax "umax") + (clz "clz") + (ctz "ctz") + (popcount "popcount")]) + + +(define_code_attr bitmanip_insn [(smin "min") + (smax "max") + (umin "minu") + (umax "maxu") + (clz "clz") + (ctz "ctz") + (popcount "cpop")]) + + ;; ZBA extension. (define_insn "*zero_extendsidi2_bitmanip" @@ -74,3 +98,143 @@ "slli.uw\t%0,%1,%2" [(set_attr "type" "bitmanip") (set_attr "mode" "DI")]) + +;; ZBB extension. + +(define_insn "*_not" + [(set (match_operand:X 0 "register_operand" "=r") + (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r")) + (match_operand:X 2 "register_operand" "r")))] + "TARGET_ZBB" + "n\t%0,%2,%1" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*xor_not" + [(set (match_operand:X 0 "register_operand" "=r") + (not:X (xor:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "register_operand" "r"))))] + "TARGET_ZBB" + "xnor\t%0,%1,%2" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "si2" + [(set (match_operand:SI 0 "register_operand" "=r") + (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_ZBB" + { return TARGET_64BIT ? "w\t%0,%1" : "\t%0,%1"; } + [(set_attr "type" "bitmanip") + (set_attr "mode" "SI")]) + +(define_insn "*disi2" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))] + "TARGET_64BIT && TARGET_ZBB" + "w\t%0,%1" + [(set_attr "type" "bitmanip") + (set_attr "mode" "SI")]) + +(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" + "\t%0,%1" + [(set_attr "type" "bitmanip") + (set_attr "mode" "DI")]) + +(define_insn "*zero_extendhi2_bitmanip" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))] + "TARGET_ZBB" + "@ + zext.h\t%0,%1 + lhu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "")]) + +(define_insn "*extend2_zbb" + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + (sign_extend:SUPERQI + (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] + "TARGET_ZBB" + "@ + sext.\t%0,%1 + l\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "")]) + +(define_insn "*zero_extendhi2_zbb" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (zero_extend:GPR + (match_operand:HI 1 "nonimmediate_operand" " r,m")))] + "TARGET_ZBB" + "@ + zext.h\t%0,%1 + lhu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "HI")]) + +(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")))] + "TARGET_ZBB" + { return TARGET_64BIT ? "ror%i2w\t%0,%1,%2" : "ror%i2\t%0,%1,%2"; } + [(set_attr "type" "bitmanip")]) + +(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")))] + "TARGET_64BIT && TARGET_ZBB" + "ror%i2\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(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"))))] + "TARGET_64BIT && TARGET_ZBB" + "rorw\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "rotlsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "register_operand" "r")))] + "TARGET_ZBB" + { return TARGET_64BIT ? "rolw\t%0,%1,%2" : "rol\t%0,%1,%2"; } + [(set_attr "type" "bitmanip")]) + +(define_insn "rotldi3" + [(set (match_operand:DI 0 "register_operand" "=r") + (rotate:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:QI 2 "register_operand" "r")))] + "TARGET_64BIT && TARGET_ZBB" + "rol\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "rotlsi3_sext" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "register_operand" "r"))))] + "TARGET_64BIT && TARGET_ZBB" + "rolw\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "bswap2" + [(set (match_operand:X 0 "register_operand" "=r") + (bswap:X (match_operand:X 1 "register_operand" "r")))] + "TARGET_64BIT && TARGET_ZBB" + "rev8\t%0,%1" + [(set_attr "type" "bitmanip")]) + +(define_insn "3" + [(set (match_operand:X 0 "register_operand" "=r") + (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "register_operand" "r")))] + "TARGET_ZBB" + "\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index dedfd20e5b3..25186067646 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -170,7 +170,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" + fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate" (cond [(eq_attr "got" "load") (const_string "load") ;; If a doubleword move uses these expensive instructions, @@ -1326,11 +1326,17 @@ [(set_attr "move_type" "shift_shift,load") (set_attr "mode" "DI")]) -(define_insn_and_split "zero_extendhi2" +(define_expand "zero_extendhi2" + [(set (match_operand:GPR 0 "register_operand") + (zero_extend:GPR + (match_operand:HI 1 "nonimmediate_operand")))] + "") + +(define_insn_and_split "*zero_extendhi2" [(set (match_operand:GPR 0 "register_operand" "=r,r") (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "" + "!TARGET_ZBB" "@ # lhu\t%0,%1" @@ -1377,11 +1383,16 @@ [(set_attr "move_type" "move,load") (set_attr "mode" "DI")]) -(define_insn_and_split "extend2" +(define_expand "extend2" + [(set (match_operand:SUPERQI 0 "register_operand") + (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand")))] + "") + +(define_insn_and_split "*extend2" [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] - "" + "!TARGET_ZBB" "@ # l\t%0,%1" diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-01.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-01.c new file mode 100644 index 00000000000..0037dea5647 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-01.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */ + +unsigned long long foo1(unsigned long long rs1, unsigned long long rs2) +{ +return rs1 & ~rs2; +} + +unsigned long long foo2(unsigned long long rs1, unsigned long long rs2) +{ +return rs1 | ~rs2; +} + +unsigned long long foo3(unsigned long long rs1, unsigned long long rs2) +{ +return rs1 ^ ~rs2; +} + +/* { dg-final { scan-assembler-times "andn" 2 } } */ +/* { dg-final { scan-assembler-times "orn" 2 } } */ +/* { dg-final { scan-assembler-times "xnor" 2 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-02.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-02.c new file mode 100644 index 00000000000..b0c1e40c554 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-xnor-02.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zbb -mabi=ilp32 -O2" } */ + +unsigned int foo1(unsigned int rs1, unsigned int rs2) +{ +return rs1 & ~rs2; +} + +unsigned int foo2(unsigned int rs1, unsigned int rs2) +{ +return rs1 | ~rs2; +} + +unsigned int foo3(unsigned int rs1, unsigned int rs2) +{ +return rs1 ^ ~rs2; +} + +/* { dg-final { scan-assembler-times "andn" 2 } } */ +/* { dg-final { scan-assembler-times "orn" 2 } } */ +/* { dg-final { scan-assembler-times "xnor" 2 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbb-min-max.c b/gcc/testsuite/gcc.target/riscv/zbb-min-max.c new file mode 100644 index 00000000000..f44c398ea08 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-min-max.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */ + +long +foo1 (long i, long j) +{ + return i < j ? i : j; +} + +long +foo2 (long i, long j) +{ + return i > j ? i : j; +} + +unsigned long +foo3 (unsigned long i, unsigned long j) +{ + return i < j ? i : j; +} + +unsigned long +foo4 (unsigned long i, unsigned long j) +{ + return i > j ? i : j; +} + +/* { dg-final { scan-assembler-times "min" 3 } } */ +/* { dg-final { scan-assembler-times "max" 3 } } */ +/* { dg-final { scan-assembler-times "minu" 1 } } */ +/* { dg-final { scan-assembler-times "maxu" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-01.c b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-01.c new file mode 100644 index 00000000000..958966289df --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-01.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */ + +unsigned long foo1(unsigned long rs1, unsigned long rs2) +{ + long shamt = rs2 & (64 - 1); + return (rs1 << shamt) | (rs1 >> ((64 - shamt) & (64 - 1))); +} +unsigned long foo2(unsigned long rs1, unsigned long rs2) +{ + unsigned long shamt = rs2 & (64 - 1); + return (rs1 >> shamt) | (rs1 << ((64 - shamt) & (64 - 1))); +} + +/* { dg-final { scan-assembler-times "rol" 2 } } */ +/* { dg-final { scan-assembler-times "ror" 2 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-02.c b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-02.c new file mode 100644 index 00000000000..24b482f2145 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-02.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zbb -mabi=ilp32 -O2" } */ + +unsigned int foo1(unsigned int rs1, unsigned int rs2) +{ + unsigned int shamt = rs2 & (32 - 1); + return (rs1 << shamt) | (rs1 >> ((32 - shamt) & (32 - 1))); +} +unsigned int foo2(unsigned int rs1, unsigned int rs2) +{ + unsigned int shamt = rs2 & (32 - 1); + return (rs1 >> shamt) | (rs1 << ((32 - shamt) & (32 - 1))); +} + +/* { dg-final { scan-assembler-times "rol" 2 } } */ +/* { dg-final { scan-assembler-times "ror" 2 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c new file mode 100644 index 00000000000..ffde7c9cd58 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */ + +/* RV64 only*/ +unsigned int rol(unsigned int rs1, unsigned int rs2) +{ + int shamt = rs2 & (32 - 1); + return (rs1 << shamt) | (rs1 >> ((64 - shamt) & (32 - 1))); +} +unsigned int ror(unsigned int rs1, unsigned int rs2) +{ + int shamt = rs2 & (64 - 1); + return (rs1 >> shamt) | (rs1 << ((32 - shamt) & (32 - 1))); +} + +/* { dg-final { scan-assembler-times "rolw" 1 } } */ +/* { dg-final { scan-assembler-times "rorw" 1 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbbw.c b/gcc/testsuite/gcc.target/riscv/zbbw.c new file mode 100644 index 00000000000..236ddf7b583 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbbw.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */ + +int +clz (int i) +{ + return __builtin_clz (i); +} + +int +ctz (int i) +{ + return __builtin_ctz (i); +} + +int +popcount (int i) +{ + return __builtin_popcount (i); +} + + +/* { dg-final { scan-assembler-times "clzw" 1 } } */ +/* { dg-final { scan-assembler-times "ctzw" 1 } } */ +/* { dg-final { scan-assembler-times "cpopw" 1 } } */