From patchwork Thu Sep 23 07:57:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kito Cheng X-Patchwork-Id: 45344 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 52CC8385843E for ; Thu, 23 Sep 2021 08:01:45 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by sourceware.org (Postfix) with ESMTPS id 5D6F1385802E for ; Thu, 23 Sep 2021 07:57:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5D6F1385802E 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-pf1-x42e.google.com with SMTP id w19so4952443pfn.12 for ; Thu, 23 Sep 2021 00:57:53 -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=xNCM44G/Ey/gWi6IUyG/ltOcbOyIPNF2SECKXwJZzS4=; b=Z6w5txClUM/wbwtzD7htdi2qW0leOVeTn1EL5KzlP85iAJwWyWnCRaSD03f/G47wW8 YfPU6sVXz+ugiGw2yzE6lXJig2oDSsx4grofExrlN0l/W2yL/JqQf38OWesaMJabTRZA ccAVx0NHDtLOyVGyoNJYaFLeFrFYS6Q116Ce2fvsPbI5txe2hLCMyQ1PiaT7KcylaFs2 IXPrwAslWnC6kF3oGGradgj2Msdor+ETo8RAkb8UueeipIUkUlNZ3YEpbqBN59zTkSSf 6f08W7MyjN+pP8fXmlWwFeWsgIQUwWxMU3I0OnuXP1cbb/CrxI1X5FbLNp5OxZp1Zow9 n+Ow== 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=xNCM44G/Ey/gWi6IUyG/ltOcbOyIPNF2SECKXwJZzS4=; b=qs4siinMzFL7WLqI+dj+BnTmhNxgHeIkY5tnTmc8bYzsfakU1ZKEsxHLnh6BO8G7tq U9MfYuzAdUBUEh0eXa09D076yqdS9WNKjJrBG9LpJ7zQOIYe3BSLu4obynroBlsiLuQq ZNedObdgtTrOAJk0njC+YTh20rVfimpysWJKO/CDMNnWO9xMk0BB6SNgJPIarAlPCXFd VM3zab5JbluCO4iahjvtbG89vtOBE9d0wJ5xsslYQyiX1x+Fm+r4lv1JR3hCX1uAtFaV BSPduCdjXc02Xv+AZbVGgMnRU/srEkRIPwYOptbCC0Qn0QirRzmhcY0B64egLKekXaW1 r2nQ== X-Gm-Message-State: AOAM532lUZUCqW4akpNhYOkY//7QrnEvt39sUCoOZKdf/CMuiTcfsJm1 tg6v5BWJfv6g5cFrxJjNj2tnwvkcO8wIhQ== X-Google-Smtp-Source: ABdhPJz/ZSylR8TCcwevggZQgX6pAtiwqv2WrBz0YGUUn9JxgVM8xrepEKy6wjunTrA/4X03PzN8Pg== X-Received: by 2002:a65:5a8e:: with SMTP id c14mr3023179pgt.125.1632383871929; Thu, 23 Sep 2021 00:57:51 -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.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Sep 2021 00:57:51 -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 7/8] RISC-V: Implement instruction patterns for ZBS extension. Date: Thu, 23 Sep 2021 15:57:30 +0800 Message-Id: <20210923075731.50125-8-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 , Shi-Hua Liao Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Jim Wilson 2021-09-23 Jim Wilson Kito Cheng gcc/ChangeLog: * config/riscv/bitmanip.md (shiftm1): New. (*bset): Ditto. (*bset_mask): Ditto. (*bset_1): Ditto. (*bset_1_mask): Ditto. (*bseti): Ditto. (*bclr): Ditto. (*bclri): Ditto. (*binv): Ditto. (*binvi): Ditto. (*bext): Ditto. (*bexti): Ditto. * config/riscv/predicates.md (splittable_const_int_operand): Handle bseti. (single_bit_mask_operand): New. (not_single_bit_mask_operand): Ditto. (const31_operand): Ditto. (const63_operand): Ditto. * config/riscv/riscv.c (riscv_build_integer_1): Handle cost model for zbb extension. (riscv_output_move): Handle bseti. (riscv_print_operand): Handle new operand type: T and S. * config/riscv/riscv.h (SINGLE_BIT_MASK_OPERAND): New. 2021-09-23 Jia-Wei Chen Shi-Hua Liao gcc/testsuite/ChangeLog: * gcc.target/riscv/zba-slliuw.c: Apply zbs to this testcase. * gcc.target/riscv/zbs-bclr.c: New. * gcc.target/riscv/zbs-bext.c: Ditto. * gcc.target/riscv/zbs-binv.c: Ditto. * gcc.target/riscv/zbs-bset.c: Ditto. Co-authored-by: Kito Cheng Co-authored-by: Jia-Wei Chen Co-authored-by: Shi-Hua Liao --- gcc/config/riscv/bitmanip.md | 102 ++++++++++++++++++++ gcc/config/riscv/predicates.md | 22 +++++ gcc/config/riscv/riscv.c | 35 ++++++- gcc/config/riscv/riscv.h | 8 ++ gcc/testsuite/gcc.target/riscv/zba-slliuw.c | 4 +- gcc/testsuite/gcc.target/riscv/zbs-bclr.c | 20 ++++ gcc/testsuite/gcc.target/riscv/zbs-bext.c | 20 ++++ gcc/testsuite/gcc.target/riscv/zbs-binv.c | 20 ++++ gcc/testsuite/gcc.target/riscv/zbs-bset.c | 41 ++++++++ 9 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-bclr.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-bext.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-binv.c create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-bset.c diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 4d624514049..59779b48f27 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -40,6 +40,7 @@ (ctz "ctz") (popcount "cpop")]) +(define_mode_attr shiftm1 [(SI "const31_operand") (DI "const63_operand")]) ;; ZBA extension. @@ -238,3 +239,104 @@ "TARGET_ZBB" "\t%0,%1,%2" [(set_attr "type" "bitmanip")]) + +;; ZBS extension. + +(define_insn "*bset" + [(set (match_operand:X 0 "register_operand" "=r") + (ior:X (ashift:X (const_int 1) + (match_operand:QI 2 "register_operand" "r")) + (match_operand:X 1 "register_operand" "r")))] + "TARGET_ZBS" + "bset\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bset_mask" + [(set (match_operand:X 0 "register_operand" "=r") + (ior:X (ashift:X (const_int 1) + (subreg:QI + (and:X (match_operand:X 2 "register_operand" "r") + (match_operand 3 "" "i")) 0)) + (match_operand:X 1 "register_operand" "r")))] + "TARGET_ZBS" + "bset\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bset_1" + [(set (match_operand:X 0 "register_operand" "=r") + (ashift:X (const_int 1) + (match_operand:QI 1 "register_operand" "r")))] + "TARGET_ZBS" + "bset\t%0,x0,%1" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bset_1_mask" + [(set (match_operand:X 0 "register_operand" "=r") + (ashift:X (const_int 1) + (subreg:QI + (and:X (match_operand:X 1 "register_operand" "r") + (match_operand 2 "" "i")) 0)))] + "TARGET_ZBS" + "bset\t%0,x0,%1" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bseti" + [(set (match_operand:X 0 "register_operand" "=r") + (ior:X (match_operand:X 1 "register_operand" "r") + (match_operand 2 "single_bit_mask_operand" "i")))] + "TARGET_ZBS" + "bseti\t%0,%1,%S2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bclr" + [(set (match_operand:X 0 "register_operand" "=r") + (and:X (rotate:X (const_int -2) + (match_operand:QI 2 "register_operand" "r")) + (match_operand:X 1 "register_operand" "r")))] + "TARGET_ZBS" + "bclr\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bclri" + [(set (match_operand:X 0 "register_operand" "=r") + (and:X (match_operand:X 1 "register_operand" "r") + (match_operand 2 "not_single_bit_mask_operand" "i")))] + "TARGET_ZBS" + "bclri\t%0,%1,%T2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*binv" + [(set (match_operand:X 0 "register_operand" "=r") + (xor:X (ashift:X (const_int 1) + (match_operand:QI 2 "register_operand" "r")) + (match_operand:X 1 "register_operand" "r")))] + "TARGET_ZBS" + "binv\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*binvi" + [(set (match_operand:X 0 "register_operand" "=r") + (xor:X (match_operand:X 1 "register_operand" "r") + (match_operand 2 "single_bit_mask_operand" "i")))] + "TARGET_ZBS" + "binvi\t%0,%1,%S2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bext" + [(set (match_operand:X 0 "register_operand" "=r") + (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (zero_extend:X + (match_operand:QI 2 "register_operand" "r"))))] + "TARGET_ZBS" + "bext\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + +(define_insn "*bexti" + [(set (match_operand:X 0 "register_operand" "=r") + (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "immediate_operand" "i")))] + "TARGET_ZBS" + "bexti\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 23211513554..3da6fd4c049 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -74,6 +74,11 @@ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) return false; + /* Check whether the constant can be loaded in a single + instruction with zbs extensions. */ + if (TARGET_64BIT && TARGET_ZBS && SINGLE_BIT_MASK_OPERAND (INTVAL (op))) + return false; + /* Otherwise check whether the constant can be loaded in a single instruction. */ return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); @@ -217,3 +222,20 @@ { return riscv_gpr_save_operation_p (op); }) + +;; Predicates for the ZBS extension. +(define_predicate "single_bit_mask_operand" + (and (match_code "const_int") + (match_test "pow2p_hwi (INTVAL (op))"))) + +(define_predicate "not_single_bit_mask_operand" + (and (match_code "const_int") + (match_test "pow2p_hwi (~INTVAL (op))"))) + +(define_predicate "const31_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 31"))) + +(define_predicate "const63_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 63"))) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 66daebbbc8f..77981d8e818 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -409,6 +409,13 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], codes[0].value = value; return 1; } + if (TARGET_ZBS && SINGLE_BIT_MASK_OPERAND (value)) + { + /* Simply BSETI. */ + codes[0].code = UNKNOWN; + codes[0].value = value; + return 1; + } /* End with ADDI. When constructing HImode constants, do not generate any intermediate value that is not itself a valid HImode constant. The @@ -2219,7 +2226,17 @@ riscv_output_move (rtx dest, rtx src) } if (src_code == CONST_INT) - return "li\t%0,%1"; + { + if (SMALL_OPERAND (INTVAL (src)) || LUI_OPERAND (INTVAL (src))) + return "li\t%0,%1"; + + if (TARGET_ZBS + && SINGLE_BIT_MASK_OPERAND (INTVAL (src))) + return "bseti\t%0,zero,%S1"; + + /* Should never reach here. */ + abort (); + } if (src_code == HIGH) return "lui\t%0,%h1"; @@ -3560,7 +3577,9 @@ riscv_memmodel_needs_release_fence (enum memmodel model) 'A' Print the atomic operation suffix for memory model OP. 'F' Print a FENCE if the memory model requires a release. 'z' Print x0 if OP is zero, otherwise print OP normally. - 'i' Print i if the operand is not a register. */ + 'i' Print i if the operand is not a register. + 'S' Print shift-index of single-bit mask OP. + 'T' Print shift-index of inverted single-bit mask OP. */ static void riscv_print_operand (FILE *file, rtx op, int letter) @@ -3600,6 +3619,18 @@ riscv_print_operand (FILE *file, rtx op, int letter) fputs ("i", file); break; + case 'S': + { + rtx newop = GEN_INT (ctz_hwi (INTVAL (op))); + output_addr_const (file, newop); + break; + } + case 'T': + { + rtx newop = GEN_INT (ctz_hwi (~INTVAL (op))); + output_addr_const (file, newop); + break; + } default: switch (code) { diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index f47d5b40a66..64287124735 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -526,6 +526,14 @@ enum reg_class (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \ || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0) +/* If this is a single bit mask, then we can load it with bseti. But this + is not useful for any of the low 31 bits because we can use addi or lui + to load them. It is wrong for loading SImode 0x80000000 on rv64 because it + needs to be sign-extended. So we restrict this to the upper 32-bits + only. */ +#define SINGLE_BIT_MASK_OPERAND(VALUE) \ + (pow2p_hwi (VALUE) && (ctz_hwi (VALUE) >= 32)) + /* Stack layout; function entry, exit and calling. */ #define STACK_GROWS_DOWNWARD 1 diff --git a/gcc/testsuite/gcc.target/riscv/zba-slliuw.c b/gcc/testsuite/gcc.target/riscv/zba-slliuw.c index 50399f68e08..a7a3dc77d53 100644 --- a/gcc/testsuite/gcc.target/riscv/zba-slliuw.c +++ b/gcc/testsuite/gcc.target/riscv/zba-slliuw.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zba -mabi=lp64 -O2" } */ +/* { dg-options "-march=rv64gc_zba_zbs -mabi=lp64 -O2" } */ long foo (long i) @@ -8,4 +8,4 @@ foo (long i) } /* XXX: This pattern need combine improvement or intermediate instruction * from zbs. */ -/* { dg-final { scan-assembler-not "slli.uw" } } */ +/* { dg-final { scan-assembler "slli.uw" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bclr.c b/gcc/testsuite/gcc.target/riscv/zbs-bclr.c new file mode 100644 index 00000000000..4a3c2f1cdaf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-bclr.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64 -O2" } */ + +/* bclr */ +long +foo0 (long i, long j) +{ + return i & ~(1L << j); +} + +/* bclri */ +long +foo1 (long i) +{ + return i & ~(1L << 20); +} + +/* { dg-final { scan-assembler-times "bclr\t" 1 } } */ +/* { dg-final { scan-assembler-times "bclri\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bext.c b/gcc/testsuite/gcc.target/riscv/zbs-bext.c new file mode 100644 index 00000000000..a093cdc8d1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-bext.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64 -O2" } */ + +/* bext */ +long +foo0 (long i, long j) +{ + return 1L & (i >> j); +} + +/* bexti */ +long +foo1 (long i) +{ + return 1L & (i >> 20); +} + +/* { dg-final { scan-assembler-times "bexti\t" 1 } } */ +/* { dg-final { scan-assembler-times "bext\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbs-binv.c b/gcc/testsuite/gcc.target/riscv/zbs-binv.c new file mode 100644 index 00000000000..e4e48b9cdfd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-binv.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64 -O2" } */ + +/* binv */ +long +foo0 (long i, long j) +{ + return i ^ (1L << j); +} + +/* binvi */ +long +foo1 (long i) +{ + return i ^ (1L << 20); +} + +/* { dg-final { scan-assembler-times "binv\t" 1 } } */ +/* { dg-final { scan-assembler-times "binvi\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bset.c b/gcc/testsuite/gcc.target/riscv/zbs-bset.c new file mode 100644 index 00000000000..733d4279d3a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-bset.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64 -O2" } */ + +/* bset */ +long +sub0 (long i, long j) +{ + return i | (1L << j); +} + +/* bset_mask */ +long +sub1 (long i, long j) +{ + return i | (1L << (j & 0x3f)); +} + +/* bset_1 */ +long +sub2 (long i) +{ + return 1L << i; +} + +/* bset_1_mask */ +long +sub3 (long i) +{ + return 1L << (i & 0x3f); +} + +/* bseti */ +long +sub4 (long i) +{ + return i | (1L << 20); +} + +/* { dg-final { scan-assembler-times "bset\t" 4 } } */ +/* { dg-final { scan-assembler-times "bseti\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */