From patchwork Fri Feb 24 05:51:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christoph_M=C3=BCllner?= X-Patchwork-Id: 65568 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8AC953896C1A for ; Fri, 24 Feb 2023 05:53:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id AA72F385B514 for ; Fri, 24 Feb 2023 05:51:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AA72F385B514 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-wr1-x42b.google.com with SMTP id bw19so2145894wrb.13 for ; Thu, 23 Feb 2023 21:51:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZXrvIxAS/0isWykuDtiY4lK5I+aXvifkXe6HGI7JlVM=; b=Unj4WULdjqcJ63Ph/UwtdBR92n1VJgoiZTzfnkJn+PtdI/aCkwIilP3bCj/vWzzhwo XiDUob4RFLQLRCr5lZg5eD5GHHPuUX18W8tafm1z0bZ+pnNwYOP3M+5AyxYlDyTLuFl/ w8dz0zMmbpYmh3vpbJPlZXbMpkxqvu6XQGy4D4JTCzuwO4sHEq/fBPRg3CXKKEobYgSZ T54JvFEnj7g5VuE1XVPh8EIqbEw8PvdLpCWwvzmbXlOW1T2d8xo1tIcSDQDoAO2zKlx7 YoFFMdjV24XIhAM0JrHF3FU4JLi9jKgeCBfYPOuKjdh1ZZ3kl3+LpE6MZMnOCnHdDuZ8 f77g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZXrvIxAS/0isWykuDtiY4lK5I+aXvifkXe6HGI7JlVM=; b=r2eE6yCOLhBP33Geep769aqiGr+yVzkRg4nn6n/w6Je30Q6oPUzxIX/KY+2sQWKxbv TZad04oQ0nPVcDzBppSy8eFBYdYFIJPzYsKnI5YOPliiWoaCmRzNICTBHkx1pb0HYYq0 eQeYbwSpbECELfscLdMz57DQl4zKH/62oaxsZCOv2J7VifMc171BZBKS9l/SAK2a5p07 gN8AwnjZMEmQKYbYmyW1ZGl8bX/1ew4GaB8Dqxu+QTt3eWx3gElzB0cP5DGmP8nZ0xrE m8bBX8ViqgkrvSdoGGNRtCmlVX49pQe8iRuyqBrzuzBJ9bQXPXklXuTJa7XPsMpr5Y2k YfRg== X-Gm-Message-State: AO0yUKUS/yzG8LYbGTbD18GhyrAhlQ3P6SkrqdcJMPVjza7ehnAEsC0c Y/h1HexuhMHgCEYONC+aEsOVKyMRG5fpKFm2 X-Google-Smtp-Source: AK7set/k7qWX+o+bZMu8Sv40DofqahegUp99/+4W2rduYquuivCAW9/iVpln+QOwvOf/USTkdBlV4g== X-Received: by 2002:a5d:6d8c:0:b0:2c7:e48:8ca3 with SMTP id l12-20020a5d6d8c000000b002c70e488ca3mr6260746wrs.0.1677217909790; Thu, 23 Feb 2023 21:51:49 -0800 (PST) Received: from beast.fritz.box (62-178-148-172.cable.dynamic.surfer.at. [62.178.148.172]) by smtp.gmail.com with ESMTPSA id f18-20020adffcd2000000b002c59e001631sm11704055wrs.77.2023.02.23.21.51.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Feb 2023 21:51:49 -0800 (PST) From: Christoph Muellner To: gcc-patches@gcc.gnu.org, Kito Cheng , Jim Wilson , Palmer Dabbelt , Andrew Waterman , Philipp Tomsich , Jeff Law , Cooper Qu , Lifang Xia , Yunhai Shang , Zhiwei Liu Cc: "moiz.hussain" , =?utf-8?q?Christoph_M=C3=BCl?= =?utf-8?q?lner?= Subject: [PATCH v3 11/11] riscv: thead: Add support for the XTheadFMemIdx ISA extension Date: Fri, 24 Feb 2023 06:51:27 +0100 Message-Id: <20230224055127.2500953-12-christoph.muellner@vrull.eu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230224055127.2500953-1-christoph.muellner@vrull.eu> References: <20230224055127.2500953-1-christoph.muellner@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_MANYTO, KAM_SHORT, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: "moiz.hussain" The XTheadFMemIdx ISA extension provides register-indexed addressing modes to floating-point load and store instructions. gcc/ChangeLog: * config/riscv/constraints.md (Qmx): New constraint. * config/riscv/riscv-protos.h (riscv_output_move_index_float): New prototyp. * config/riscv/riscv.cc (riscv_classify_address_index): Adjust for XTheadFMemIdx. (riscv_classify_address_modify): Likewise. (riscv_output_move_index_float): New function. (riscv_rtx_costs): Adjust for XTheadFMemIdx. (riscv_split_64bit_move_p): Likewise. (riscv_output_move): Likewise. * config/riscv/riscv.h (INDEX_REG_CLASS): Likewise. (REGNO_OK_FOR_INDEX_P): Likewise. * config/riscv/riscv.md (*movsf_hardfloat): New pattern. (*movdf_hardfloat_rv32): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadfmemidx-fldr-fstr.c: New test. Signed-off-by: M. Moiz Hussain Signed-off-by: Christoph Müllner --- gcc/config/riscv/constraints.md | 7 ++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv.cc | 70 ++++++++++++++++++- gcc/config/riscv/riscv.h | 4 +- gcc/config/riscv/riscv.md | 28 ++++++++ .../riscv/xtheadfmemidx-fldr-fstr.c | 58 +++++++++++++++ 6 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index a007cf0b4f5..711268d05f6 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -202,3 +202,10 @@ (define_memory_constraint "Qmu" (and (match_code "mem") (match_test "riscv_legitimize_address_index_p ( XEXP (op, 0), GET_MODE (op), true)"))) + +(define_memory_constraint "Qmx" + "@internal + An address valid for GPR." + (and (match_code "mem") + (match_test "!riscv_legitimize_address_index_p ( + XEXP (op, 0), GET_MODE (op), false)"))) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 019a0e08285..ba53bf710d7 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -77,6 +77,8 @@ extern const char * riscv_output_move_index (rtx x, machine_mode mode, bool ldr); extern const char * riscv_output_move_modify (rtx x, machine_mode mode, bool ldi); +extern const char * +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr); extern bool riscv_legitimize_address_index_p (rtx x, machine_mode mode, bool uindex); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 2980dbd69f9..caa30eed8d6 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1316,7 +1316,7 @@ riscv_classify_address_index (struct riscv_address_info *info, rtx x, rtx index; int shift = 0; - if (!TARGET_XTHEADMEMIDX) + if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) return false; if (!TARGET_64BIT && mode == DImode) @@ -1326,6 +1326,8 @@ riscv_classify_address_index (struct riscv_address_info *info, rtx x, { if (!TARGET_HARD_FLOAT) return false; + if (!(TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX)) + return false; if (GET_MODE_SIZE (mode).to_constant () == 2) return false; } @@ -1422,7 +1424,7 @@ riscv_classify_address_modify (struct riscv_address_info *info, rtx x, ? (SHIFT) + 1 \ : 0) - if (!TARGET_XTHEADMEMIDX) + if (!(TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) return false; if (!(INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode).to_constant () <= 8)) @@ -1562,6 +1564,42 @@ riscv_output_move_index (rtx x, machine_mode mode, bool ldr) return buf; } +const char * +riscv_output_move_index_float (rtx x, machine_mode mode, bool ldr) +{ + static char buf[128] = {0}; + + int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()); + if (!IN_RANGE (index, 2, 3)) + return NULL; + + if (!riscv_legitimize_address_index_p (x, mode, false)) + return NULL; + + bool uindex = riscv_legitimize_address_index_p (x, mode, true); + + /* Not using index, 0, 1, as they are not implemented + for xtheadfmemidx yet. */ + const char *const insn[][4] = { + { + "th.fs%srb\t%%z1,%%0", + "th.fs%srh\t%%z1,%%0", + "th.fs%srw\t%%z1,%%0", + "th.fs%srd\t%%z1,%%0" + }, + { + "th.fl%srb\t%%0,%%1", + "th.fl%srh\t%%0,%%1", + "th.fl%srw\t%%0,%%1", + "th.fl%srd\t%%0,%%1" + } + }; + + snprintf (buf, sizeof (buf), insn[ldr][index], uindex ? "u" : ""); + + return buf; +} + /* Emit an instruction of the form (set TARGET SRC). */ static rtx @@ -2739,7 +2777,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN } /* bit extraction pattern (xtheadmemidx, xtheadfmemidx). */ if (outer_code == SET - && TARGET_XTHEADMEMIDX) + && (TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX)) { *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; @@ -3071,6 +3109,20 @@ riscv_split_64bit_move_p (rtx dest, rtx src) if (TARGET_64BIT) return false; + if (TARGET_XTHEADFMEMIDX) + { + if (MEM_P (src) && SCALAR_FLOAT_MODE_P (GET_MODE (src)) + && riscv_legitimize_address_index_p (XEXP (src, 0), + GET_MODE (src), false) + && FP_REG_RTX_P (dest)) + return false; + if (MEM_P (dest) && SCALAR_FLOAT_MODE_P (GET_MODE (dest)) + && riscv_legitimize_address_index_p (XEXP (dest, 0), + GET_MODE (dest), false) + && FP_REG_RTX_P (src)) + return false; + } + /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case of zeroing an FPR with FCVT.D.W. */ if (TARGET_DOUBLE_FLOAT @@ -3269,6 +3321,12 @@ riscv_output_move (rtx dest, rtx src) if (dest_code == MEM) { + const char *insn = NULL; + insn = riscv_output_move_index_float (XEXP (dest, 0), + GET_MODE (dest), false); + if (insn) + return insn; + switch (width) { case 2: @@ -3284,6 +3342,12 @@ riscv_output_move (rtx dest, rtx src) { if (src_code == MEM) { + const char *insn = NULL; + insn = riscv_output_move_index_float (XEXP (src, 0), + GET_MODE (src), true); + if (insn) + return insn; + switch (width) { case 2: diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 199bb30162e..13764d60257 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -535,7 +535,7 @@ enum reg_class factor or added to another register (as well as added to a displacement). */ -#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX) ? \ +#define INDEX_REG_CLASS ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \ GR_REGS : NO_REGS) /* We generally want to put call-clobbered registers ahead of @@ -707,7 +707,7 @@ typedef struct { /* Addressing modes, and classification of registers for them. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ - ((TARGET_XTHEADMEMIDX) ? \ + ((TARGET_XTHEADMEMIDX || TARGET_XTHEADFMEMIDX) ? \ riscv_regno_mode_ok_for_base_p (REGNO, VOIDmode, 1) : 0) #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index df31a1fffff..9d0207b8d6f 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1866,6 +1866,20 @@ (define_insn "*movsf_hardfloat" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "SF")]) +(define_insn "*movsf_hardfloat" + [(set (match_operand:SF 0 + "nonimmediate_operand" "=f,f,f,m,Qmx,*f,*r, *r,*r,*Qmx") + (match_operand:SF 1 + "move_operand" " f,G,m,f,G,*r,*f,*G*r,*Qmx,*r"))] + "!TARGET_64BIT + && TARGET_XTHEADFMEMIDX + && (register_operand (operands[0], SFmode) + || reg_or_0_operand (operands[1], SFmode))" + { return riscv_output_move (operands[0], operands[1]); } + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") + (set_attr "mode" "SF")]) + (define_insn "*movsf_softfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m") (match_operand:SF 1 "move_operand" " Gr,m,r"))] @@ -1900,6 +1914,20 @@ (define_insn "*movdf_hardfloat_rv32" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) +(define_insn "*movdf_hardfloat_rv32" + [(set (match_operand:DF 0 + "nonimmediate_operand" "=f,f,f,m,Qmx, *r,*r,*Qmx") + (match_operand:DF 1 + "move_operand" " f,G,m,f,G,*r*G,*Qmx,*r"))] + "!TARGET_64BIT && TARGET_DOUBLE_FLOAT + && TARGET_XTHEADFMEMIDX + && (register_operand (operands[0], DFmode) + || reg_or_0_operand (operands[1], DFmode))" + { return riscv_output_move (operands[0], operands[1]); } + [(set_attr "move_type" + "fmove,mtc,fpload,fpstore,store,move,load,store") + (set_attr "mode" "DF")]) + (define_insn "*movdf_hardfloat_rv64" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))] diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c new file mode 100644 index 00000000000..006038ce3c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-fldr-fstr.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os"} } */ +/* { dg-options "-march=rv64gc_xtheadfmemidx --save-temps -O2" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadfmemidx --save-temps -O2" { target { rv32 } } } */ + +float func_f(float *a, int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flrw" } } */ + +double func_d(double *a, int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flrd" } } */ + +float func_sf(float *a, int b, float c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsrw" } } */ + +double func_sd(double *a, int b, double c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsrd" } } */ + +float func_uf(float *a, unsigned int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flurw" { target { rv64 } } } } */ + +double func_ud(double *a, unsigned int b) +{ + return a[b]; +} +/* { dg-final { scan-assembler "th.flurd" { target { rv64 } } } } */ + +float func_usf(float *a, unsigned int b, float c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsurw" { target { rv64 } } } } */ + +double func_usd(double *a, unsigned int b, double c) +{ + a[b] = c; + return a[b]; +} +/* { dg-final { scan-assembler "th.fsurd" { target { rv64 } } } } */ + +/* { dg-final { cleanup-saved-temps } } */