From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by sourceware.org (Postfix) with ESMTPS id 650143858CDA for ; Fri, 28 Apr 2023 06:23:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 650143858CDA Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-94eff00bcdaso1760739366b.1 for ; Thu, 27 Apr 2023 23:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1682662999; x=1685254999; 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=7WJ0WudPvy2ZOeMS7NcXHd9tc3NOUde52+0PpVZwY70=; b=Ubr/lbAgH4HzxM7AkYlLWIKxuFZEeyq5UIemHnbepzCtoa0KESG4oLfL8FyRPwRqpZ MRKylyn9VGSO38Fq0k90nlRIZBme+/DQZnXmVVB51VGdo6xymEx1V3+gHBryUCQTJQwa jtPqnT7edW0CaO0eTIDSHzIiiS+NSeu72zRyo0i2kmoMYNTFXgWvifrYZcOZyYd46W/R 0AuNIBZMFPvHCPc1S8cvwSUfCqvS8VPPgRC+hFgprwCdgeGVCmxc7IuejBazZ7aA4IBH jc4fA4+kbt8vxvF52DPFVPlpVIu6mgdIa0ev1S2AdmNbIJocnV6QcYIxRgw4Mmava0Sb m43w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682662999; x=1685254999; 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=7WJ0WudPvy2ZOeMS7NcXHd9tc3NOUde52+0PpVZwY70=; b=KSHvaDNweAkTV6s25i49qlqkcLa/btuuPNdG1FuLoWIbkx0PDYUGBA1N5N5IX/HU/s hVwLR8w8daGaG+YiLY64iFmQ9tw5aHKcjG3QtKICcvMdCbPHEyxMsRTvGNDI96nIcu8/ akwsuiXqZh3C5VSwNEPDttsAzQUluNxw/PT9SfFlRUCCHcZZSfc254Z3hoYCpbtU+MIa 5g7+kDms5aW3/CXewjBJ0O8KEFo+yfRteRqqikQxKmrTMgogHHXGptiUNKdcH2PgfWGw aj/Jpx8cDjLB/I5x6jUFd15zhSlT0Ek1jhv4bj55AhQ8iKSboyTHkDj8uZErVE4hT/HA JoNg== X-Gm-Message-State: AC+VfDxcILaHGnVlwwJeN0rtt0rnqiW9mg6V9ejRwC627ieICK188VPB cI+f1GvBkEimPNNBKPXIJizVr/K5yANs6rAvHg0= X-Google-Smtp-Source: ACHHUZ4bfXrKdkOGOrP83u87fUpQoxNfuJCIs7XjOqwful+fL21iNA3waQnQoUKKSbSUfj93xS4ukA== X-Received: by 2002:a17:906:eec8:b0:94f:444c:fc25 with SMTP id wu8-20020a170906eec800b0094f444cfc25mr4114438ejb.12.1682662999493; Thu, 27 Apr 2023 23:23:19 -0700 (PDT) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id e14-20020a170906504e00b0094a90d3e385sm10556730ejk.30.2023.04.27.23.23.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Apr 2023 23:23:18 -0700 (PDT) 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 Cc: =?UTF-8?q?Christoph=20M=C3=BCllner?= Subject: [PATCH 11/11] riscv: thead: Add support for the XTheadFMemIdx ISA extension Date: Fri, 28 Apr 2023 08:23:14 +0200 Message-Id: <20230428062314.2995571-2-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230428062314.2995571-1-christoph.muellner@vrull.eu> References: <20230428062314.2995571-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Christoph Müllner The XTheadFMemIdx ISA extension provides additional load and store instructions for floating-point registers with new addressing modes. The following memory accesses types are supported: * ftype = [w,d] (single-precision, double-precision) The following addressing modes are supported: * register offset with additional immediate offset (4 instructions): flr, fsr * zero-extended register offset with additional immediate offset (4 instructions): flur, fsur These addressing modes are also part of the similar XTheadMemIdx ISA extension support, whose code is reused and extended to support floating-point registers. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_index_reg_class): Also allow for XTheadFMemIdx. (riscv_regno_ok_for_index_p): Likewise. * config/riscv/thead-peephole.md (TARGET_64BIT): Generalize peepholes for XTheadFMemIdx. * config/riscv/thead.cc (is_fmemidx_mode): New function. (th_memidx_classify_address_index): Add support for XTheadFMemIdx. (th_fmemidx_output_index): New function. (th_output_move): Add support for XTheadFMemIdx. * config/riscv/thead.md (*th_fmemidx_movsf_hardfloat): New INSN. (*th_fmemidx_movdf_hardfloat_rv64): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadmemidx-helpers.h: Add helpers for XTheadMemFIdx. * gcc.target/riscv/xtheadfmemidx-index-update.c: New test. * gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c: New test. * gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c: New test. * gcc.target/riscv/xtheadfmemidx-index.c: New test. * gcc.target/riscv/xtheadfmemidx-uindex-update.c: New test. * gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c: New test. * gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c: New test. * gcc.target/riscv/xtheadfmemidx-uindex.c: New test. Signed-off-by: Christoph Müllner --- gcc/config/riscv/riscv.cc | 4 +- gcc/config/riscv/thead-peephole.md | 24 ++++--- gcc/config/riscv/thead.cc | 68 +++++++++++++++++- gcc/config/riscv/thead.md | 22 ++++++ .../riscv/xtheadfmemidx-index-update.c | 20 ++++++ .../xtheadfmemidx-index-xtheadbb-update.c | 20 ++++++ .../riscv/xtheadfmemidx-index-xtheadbb.c | 22 ++++++ .../gcc.target/riscv/xtheadfmemidx-index.c | 22 ++++++ .../riscv/xtheadfmemidx-uindex-update.c | 20 ++++++ .../xtheadfmemidx-uindex-xtheadbb-update.c | 20 ++++++ .../riscv/xtheadfmemidx-uindex-xtheadbb.c | 24 +++++++ .../gcc.target/riscv/xtheadfmemidx-uindex.c | 25 +++++++ .../gcc.target/riscv/xtheadmemidx-helpers.h | 70 +++++++++++++++++++ 13 files changed, 348 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 1691ecf3a94..d1e08974023 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -834,7 +834,7 @@ riscv_regno_mode_ok_for_base_p (int regno, enum reg_class riscv_index_reg_class () { - if (TARGET_XTHEADMEMIDX) + if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) return GR_REGS; return NO_REGS; @@ -847,7 +847,7 @@ riscv_index_reg_class () int riscv_regno_ok_for_index_p (int regno) { - if (TARGET_XTHEADMEMIDX) + if (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) return riscv_regno_mode_ok_for_base_p (regno, VOIDmode, 1); return 0; diff --git a/gcc/config/riscv/thead-peephole.md b/gcc/config/riscv/thead-peephole.md index 2a4c734a220..e3de9b8e8d3 100644 --- a/gcc/config/riscv/thead-peephole.md +++ b/gcc/config/riscv/thead-peephole.md @@ -73,11 +73,15 @@ (define_peephole2 th_mempair_order_operands (operands, true, SImode); }) -;; All modes that are supported by XTheadMemIdx -(define_mode_iterator TH_M_ANY [QI HI SI (DI "TARGET_64BIT")]) +;; All modes that are supported by XTheadMemIdx and XTheadFMemIdx +(define_mode_iterator TH_M_ANY [QI HI SI (DI "TARGET_64BIT") + (SF "TARGET_HARD_FLOAT") + (DF "TARGET_DOUBLE_FLOAT")]) -;; All non-extension modes that are supported by XTheadMemIdx -(define_mode_iterator TH_M_NOEXT [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")]) +;; All non-extension modes that are supported by XTheadMemIdx and XTheadFMemIdx +(define_mode_iterator TH_M_NOEXT [(SI "!TARGET_64BIT") (DI "TARGET_64BIT") + (SF "TARGET_HARD_FLOAT") + (DF "TARGET_DOUBLE_FLOAT")]) ;; XTheadMemIdx overview: ;; All peephole passes attempt to improve the operand utilization of @@ -125,7 +129,7 @@ (define_peephole2 (mem:TH_M_NOEXT (plus:X (match_dup 0) (match_operand:X 4 "register_operand" ""))))] - "TARGET_XTHEADMEMIDX + "(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (2, operands[0]) && IN_RANGE (INTVAL (operands[2]), 0, 3)" [(set (match_dup 3) @@ -161,7 +165,7 @@ (define_peephole2 (match_dup 0) (match_operand:X 4 "register_operand" ""))) (match_operand:TH_M_ANY 3 "register_operand" ""))] - "TARGET_XTHEADMEMIDX + "(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (2, operands[0]) && IN_RANGE (INTVAL (operands[2]), 0, 3)" [(set (mem:TH_M_ANY (plus:X @@ -180,7 +184,7 @@ (define_peephole2 (mem:TH_M_NOEXT (plus:DI (match_dup 3) (match_operand:DI 6 "register_operand" ""))))] - "TARGET_64BIT && TARGET_XTHEADMEMIDX + "TARGET_64BIT && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[3]) && IN_RANGE (INTVAL (operands[4]), 29, 32)" @@ -226,7 +230,7 @@ (define_peephole2 (match_dup 3) (match_operand:DI 6 "register_operand" ""))) (match_operand:TH_M_ANY 5 "register_operand" ""))] - "TARGET_64BIT && TARGET_XTHEADMEMIDX + "TARGET_64BIT && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[3]) && IN_RANGE (INTVAL (operands[4]), 29, 32)" @@ -247,7 +251,7 @@ (define_peephole2 (mem:TH_M_NOEXT (plus:DI (match_dup 0) (match_operand:DI 4 "register_operand" ""))))] - "TARGET_64BIT && TARGET_XTHEADMEMIDX + "TARGET_64BIT && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 3) (mem:TH_M_NOEXT (plus:DI @@ -279,7 +283,7 @@ (define_peephole2 (match_dup 0) (match_operand:DI 4 "register_operand" ""))) (match_operand:TH_M_ANY 3 "register_operand" ""))] - "TARGET_64BIT && TARGET_XTHEADMEMIDX + "TARGET_64BIT && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) && peep2_reg_dead_p (2, operands[0])" [(set (mem:TH_M_ANY (plus:DI (match_dup 4) diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index bfe035250af..3671f1bf9ac 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -591,6 +591,21 @@ is_memidx_mode (machine_mode mode) return false; } +static bool +is_fmemidx_mode (machine_mode mode) +{ + if (!TARGET_HARD_FLOAT) + return false; + + if (mode == SFmode) + return true; + + if (mode == DFmode && TARGET_DOUBLE_FLOAT) + return true; + + return false; +} + /* Return true if X is a valid address for T-Head's memory addressing modes with scaled register offsets for machine mode MODE. If it is, fill in INFO appropriately (if non-NULL). @@ -601,7 +616,8 @@ th_memidx_classify_address_index (struct riscv_address_info *info, rtx x, machine_mode mode, bool strict_p) { /* Ensure that the mode is supported. */ - if (!(TARGET_XTHEADMEMIDX && is_memidx_mode (mode))) + if (!(TARGET_XTHEADMEMIDX && is_memidx_mode (mode)) + && !(TARGET_XTHEADFMEMIDX && is_fmemidx_mode (mode))) return false; if (GET_CODE (x) != PLUS) @@ -757,6 +773,40 @@ th_memidx_output_index (rtx x, machine_mode mode, bool load) return buf; } +/* Provide a buffer for a th.flX/th.fluX/th.fsX/th.fsuX instruction + for the given MODE. If LOAD is true, a load instruction will be + provided (otherwise, a store instruction). If X is not suitable + return NULL. */ + +static const char * +th_fmemidx_output_index (rtx x, machine_mode mode, bool load) +{ + struct riscv_address_info info; + static char buf[128] = {0}; + + /* Validate x. */ + if (!th_memidx_classify_address_index (&info, x, mode, false)) + return NULL; + + int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()) - 2; + bool uindex = info.type == ADDRESS_REG_UREG; + + const char *const insn[][2] = { + { + "th.fs%srw\t%%z1,%%0", + "th.fs%srd\t%%z1,%%0" + }, + { + "th.fl%srw\t%%0,%%1", + "th.fl%srd\t%%0,%%1" + } + }; + + snprintf (buf, sizeof (buf), insn[load][index], uindex ? "u" : ""); + + return buf; +} + /* Return true if X is a valid address for T-Head's memory addressing modes for machine mode MODE. If it is, fill in INFO appropriately (if non-NULL). If STRICT_P is true then REG_OK_STRICT is in effect. */ @@ -811,6 +861,14 @@ th_output_move (rtx dest, rtx src) if ((insn = th_memidx_output_modify (x, mode, true))) return insn; } + else if (dest_code == REG && FP_REG_P (REGNO (dest)) && src_code == MEM) + { + rtx x = XEXP (src, 0); + mode = GET_MODE (src); + + if ((insn = th_fmemidx_output_index (x, mode, true))) + return insn; + } else if (((src_code == REG && GP_REG_P (REGNO (src))) || (src == CONST0_RTX (mode))) && dest_code == MEM) @@ -824,6 +882,14 @@ th_output_move (rtx dest, rtx src) if ((insn = th_memidx_output_modify (x, mode, false))) return insn; } + else if (src_code == REG && FP_REG_P (REGNO (src)) && dest_code == MEM) + { + rtx x = XEXP (dest, 0); + mode = GET_MODE (dest); + + if ((insn = th_fmemidx_output_index (x, mode, false))) + return insn; + } return NULL; } diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 5536500e4ff..e8759e1b77d 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -555,4 +555,26 @@ (define_insn "*th_memidx_bb_extendqi2" [(set_attr "move_type" "shift_shift,load,load,load,load,load") (set_attr "mode" "")]) +;; XTheadFMemIdx + +(define_insn "*th_fmemidx_movsf_hardfloat" + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu") + (match_operand:SF 1 "move_operand" " th_m_mir,f,th_m_miu,f"))] + "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX + && (register_operand (operands[0], SFmode) + || reg_or_0_operand (operands[1], SFmode))" + { return riscv_output_move (operands[0], operands[1]); } + [(set_attr "move_type" "fpload,fpstore,fpload,fpstore") + (set_attr "mode" "SF")]) + +(define_insn "*th_fmemidx_movdf_hardfloat_rv64" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu") + (match_operand:DF 1 "move_operand" " th_m_mir,f,th_m_miu,f"))] + "TARGET_64BIT && TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX + && (register_operand (operands[0], DFmode) + || reg_or_0_operand (operands[1], DFmode))" + { return riscv_output_move (operands[0], operands[1]); } + [(set_attr "move_type" "fpload,fpstore,fpload,fpstore") + (set_attr "mode" "DF")]) + (include "thead-peephole.md") diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c new file mode 100644 index 00000000000..cc97fd2f786 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-update.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLR_REG_IMM_UPD(float, 0) +#if __riscv_xlen == 64 +FLR_REG_IMM_UPD(double, 2) +#endif + +FSR_REG_IMM_UPD(float, 1) +#if __riscv_xlen == 64 +FSR_REG_IMM_UPD(double, 3) +#endif + +/* If the shifted value is used later, we cannot eliminate it. */ +/* { dg-final { scan-assembler-times "slli" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "slli" 3 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c new file mode 100644 index 00000000000..3b3a7fbdd4a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb-update.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadbb_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadbb_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLR_REG_IMM_UPD(float, 0) +#if __riscv_xlen == 64 +FLR_REG_IMM_UPD(double, 2) +#endif + +FSR_REG_IMM_UPD(float, 1) +#if __riscv_xlen == 64 +FSR_REG_IMM_UPD(double, 3) +#endif + +/* If the shifted value is used later, we cannot eliminate it. */ +/* { dg-final { scan-assembler-times "slli" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "slli" 3 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c new file mode 100644 index 00000000000..55d1f651bd2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index-xtheadbb.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadbb_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadbb_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLR_REG_IMM(float, 0) +/* { dg-final { scan-assembler-times "th.flrw\t\[^\n\r\]*0\[\n\r\]" 1 } } */ +#if __riscv_xlen == 64 +FLR_REG_IMM(double, 2) +/* { dg-final { scan-assembler-times "th.flrd\t\[^\n\r\]*2\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +FSR_REG_IMM(float, 1) +/* { dg-final { scan-assembler-times "th.fsrw\t\[^\n\r\]*1\[\n\r\]" 1 } } */ +#if __riscv_xlen == 64 +FSR_REG_IMM(double, 3) +/* { dg-final { scan-assembler-times "th.fsrd\t\[^\n\r\]*3\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +/* { dg-final { scan-assembler-not "slli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c new file mode 100644 index 00000000000..b92f4adc0b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-index.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLR_REG_IMM(float, 0) +/* { dg-final { scan-assembler-times "th.flrw\t\[^\n\r\]*0\[\n\r\]" 1 } } */ +#if __riscv_xlen == 64 +FLR_REG_IMM(double, 2) +/* { dg-final { scan-assembler-times "th.flrd\t\[^\n\r\]*2\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +FSR_REG_IMM(float, 1) +/* { dg-final { scan-assembler-times "th.fsrw\t\[^\n\r\]*1\[\n\r\]" 1 } } */ +#if __riscv_xlen == 64 +FSR_REG_IMM(double, 3) +/* { dg-final { scan-assembler-times "th.fsrd\t\[^\n\r\]*3\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +/* { dg-final { scan-assembler-not "slli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c new file mode 100644 index 00000000000..075cefdb971 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-update.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLUR_REG_IMM_UPD(float, 0) +#if __riscv_xlen == 64 +FLUR_REG_IMM_UPD(double, 2) +#endif + +FSUR_REG_IMM_UPD(float, 1) +#if __riscv_xlen == 64 +FSUR_REG_IMM_UPD(double, 3) +#endif + +/* If the shifted value is used later, we cannot eliminate it. */ +/* { dg-final { scan-assembler-times "slli" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "slli" 3 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c new file mode 100644 index 00000000000..a677e82768a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb-update.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadbb_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadbb_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLUR_REG_IMM_UPD(float, 0) +#if __riscv_xlen == 64 +FLUR_REG_IMM_UPD(double, 2) +#endif + +FSUR_REG_IMM_UPD(float, 1) +#if __riscv_xlen == 64 +FSUR_REG_IMM_UPD(double, 3) +#endif + +/* If the shifted value is used later, we cannot eliminate it. */ +/* { dg-final { scan-assembler-times "slli" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "slli" 3 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c new file mode 100644 index 00000000000..3377c26963b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-xtheadbb.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadbb_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadbb_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLUR_REG_IMM(float, 0) +/* { dg-final { scan-assembler-times "th.flurw\t\[^\n\r\]*0\[\n\r\]" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.flrw\t\[^\n\r\]*0\[\n\r\]" 1 { target { rv32 } } } } */ +#if __riscv_xlen == 64 +FLUR_REG_IMM(double, 2) +/* { dg-final { scan-assembler-times "th.flurd\t\[^\n\r\]*2\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +FSUR_REG_IMM(float, 1) +/* { dg-final { scan-assembler-times "th.fsurw\t\[^\n\r\]*1\[\n\r\]" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.fsrw\t\[^\n\r\]*1\[\n\r\]" 1 { target { rv32 } } } } */ +#if __riscv_xlen == 64 +FSUR_REG_IMM(double, 3) +/* { dg-final { scan-assembler-times "th.fsurd\t\[^\n\r\]*3\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +/* { dg-final { scan-assembler-not "slli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c new file mode 100644 index 00000000000..0c84a651eb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_xtheadfmemidx -mabi=ilp32f" { target { rv32 } } } */ + +#include "xtheadmemidx-helpers.h" + +FLUR_REG_IMM(float, 0) +/* { dg-final { scan-assembler-times "th.flurw\t\[^\n\r\]*0\[\n\r\]" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.flrw\t\[^\n\r\]*0\[\n\r\]" 1 { target { rv32 } } } } */ +#if __riscv_xlen == 64 +FLUR_REG_IMM(double, 2) +/* { dg-final { scan-assembler-times "th.flurd\t\[^\n\r\]*2\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +FSUR_REG_IMM(float, 1) +/* { dg-final { scan-assembler-times "th.fsurw\t\[^\n\r\]*1\[\n\r\]" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.fsrw\t\[^\n\r\]*1\[\n\r\]" 1 { target { rv32 } } } } */ +#if __riscv_xlen == 64 +FSUR_REG_IMM(double, 3) +/* { dg-final { scan-assembler-times "th.fsurd\t\[^\n\r\]*3\[\n\r\]" 1 { target { rv64 } } } } */ +#endif + +/* { dg-final { scan-assembler-not "slli" } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h index a97f08c5cc1..62c4f67f968 100644 --- a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h +++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-helpers.h @@ -149,4 +149,74 @@ *rs2 = t; \ } +#define FLR_REG_IMM(T, IMM) \ + T \ + flr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2) \ + { \ + return *(T*)(rs1 + (rs2 << IMM)); \ + } + +#define FSR_REG_IMM(T, IMM) \ + void \ + sr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2, T val) \ + { \ + *(T*)(rs1 + (rs2 << IMM)) = val; \ + } + +#define FLR_REG_IMM_UPD(T, IMM) \ + T \ + flr_reg_imm_upd_ ## T ## _ ## IMM (intX_t rs1, intX_t *rs2) \ + { \ + intX_t addr = rs1 + (*rs2 << IMM); \ + T val = *(T*)addr; \ + *rs2 = addr; \ + return val; \ + } + +#define FSR_REG_IMM_UPD(T, IMM) \ + void \ + sr_reg_imm_upd_ ## T ## _ ## IMM (intX_t rs1, intX_t *rs2, T val) \ + { \ + intX_t addr = rs1 + (*rs2 << IMM); \ + *(T*)addr = val; \ + *rs2 = addr; \ + } + +#define FLUR_REG_IMM(T, IMM) \ + T \ + flr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2) \ + { \ + rs2 = (uint32_t)rs2; \ + return *(T*)(rs1 + (rs2 << IMM)); \ + } + +#define FSUR_REG_IMM(T, IMM) \ + void \ + sr_reg_imm_ ## T ## _ ## IMM (intX_t rs1, intX_t rs2, T val) \ + { \ + rs2 = (uint32_t)rs2; \ + *(T*)(rs1 + (rs2 << IMM)) = val; \ + } + +#define FLUR_REG_IMM_UPD(T, IMM) \ + T \ + flr_reg_imm_upd_ ## T ## _ ## IMM (intX_t rs1, intX_t *rs2) \ + { \ + intX_t rs2_32 = (uint32_t)*rs2; \ + intX_t addr = rs1 + (rs2_32 << IMM); \ + T val = *(T*)addr; \ + *rs2 = addr; \ + return val; \ + } + +#define FSUR_REG_IMM_UPD(T, IMM) \ + void \ + sr_reg_imm_upd_ ## T ## _ ## IMM (intX_t rs1, intX_t *rs2, T val) \ + { \ + intX_t rs2_32 = (uint32_t)*rs2; \ + intX_t addr = rs1 + (rs2_32 << IMM); \ + *(T*)addr = val; \ + *rs2 = addr; \ + } + #endif /* XTHEADMEMIDX_HELPERS_H */ -- 2.40.1