From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by sourceware.org (Postfix) with ESMTPS id 1E84F3856956 for ; Fri, 5 May 2023 15:43:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1E84F3856956 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-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3f178da21afso13945665e9.1 for ; Fri, 05 May 2023 08:43:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1683301401; x=1685893401; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=JQ88xuHG0CuDXX9L9G6zyYo5TWE461O/rWJqBi6DDCc=; b=GxUARAwD6K1kQmMH3YZVcYpxXRKQcKosrlxWky8fXC0GaVzz2PEATvFqhO5hrAdm+U yMYv/KAVyGYHkpc7Tf2l07VKoqU3jK3AeIqbhZ+LnF4WqWqjjRoX5JB7xLlchOhGysyo 8iL9mHyy1XyJi73oTM0ZQG6RJx/gl7i6ehbGAOlY7/wSwDNe21hUQHkX2zbVokFguIA3 24an5FEmTaYgtDovJRMyBqPbqTlOXCH/jBR2RpY/qhdEE3AG/lVZ9ORVZTTTm61crQ7q h+cdpa+1KOAhSfg8ZI/w9Wp81zGMqlNcI/P7VY7FkEfIJrOc8S6doW6qTyPYYCk+oKzw jk0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683301401; x=1685893401; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JQ88xuHG0CuDXX9L9G6zyYo5TWE461O/rWJqBi6DDCc=; b=TTeSkK9YUi90nijCQTMucsua5kCOELfTFK1Kf63N6F64uKQbqqWm23Y59/yFInD9aV /QghmBKhhUK4IhvR7qkpFP0PGYvx/lJu8Gyf+msQLO2+AHRHx2PGBiqP9YVUkbwMI0GY ej6Hrlbe9coInwoVSY1P2oabadVKf0xzTvBww6GoaHFdUIfNSLTSi09L4Xc3cQmg3O2P vLVj7OM91D4GMVbYm06SZ+CTStZ1LAWOuvEjCx/zLBKkj28yv6jRbX3J34676CWil3Qx FiNbTKgWRUcA6vTqAsHNtM/2rtGVrnQ2ec+xN8a5mNTr1BnGRDeX577cfEazQ6Jxs0w/ z6aQ== X-Gm-Message-State: AC+VfDweWXLuGdyB/memx3JLKusTtE9Q2vHHATOXiAX3bwfi811rmjyl IxnVOmWn93z+W4aB5ZebaT2omoDqrnPFUOdK5XQkHrmQzeTudvLwVto= X-Google-Smtp-Source: ACHHUZ52lcTqK4+W5/hPdpmAxGQzOj7eiLN/mhN2vITR+61b23I6f82ZYQlhHYHRU2Vd9oJXWXPO8ADrYzXr52qkpvk= X-Received: by 2002:adf:f4c2:0:b0:306:3382:721d with SMTP id h2-20020adff4c2000000b003063382721dmr1704778wrp.38.1683301401234; Fri, 05 May 2023 08:43:21 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: =?UTF-8?Q?Christoph_M=C3=BCllner?= Date: Fri, 5 May 2023 17:43:08 +0200 Message-ID: Subject: Re: [PATCH v8] RISC-V: Add the 'zfa' extension, version 0.2. To: Palmer Dabbelt Cc: jinma@linux.alibaba.com, gcc-patches@gcc.gnu.org, jeffreyalaw@gmail.com, kito.cheng@sifive.com, Kito Cheng , ijinma@yeah.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,JMQ_SPF_NEUTRAL,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: On Fri, May 5, 2023 at 5:13=E2=80=AFPM Palmer Dabbelt = wrote: > > On Fri, 05 May 2023 08:04:53 PDT (-0700), christoph.muellner@vrull.eu wro= te: > > What I forgot to mention: > > Zfa is frozen and in public review: > > https://groups.google.com/a/groups.riscv.org/g/isa-dev/c/SED4ntBkabg > > Thanks, I'd also forgot to send that out ;). > > I think the only blocker here on the specification side is the assembly > format for FLI? It looks like the feedback on > has been > pretty minor so far. It'd be nice to have the docs lined up before > we merge, but we could always just call it a GNU extension -- we've > already got a lot of that in assembler land, so I don't think it's that > big of a deal. I also don't think that we need to wait for that PR to land. Nelson already gave his ok on the Binutils v4 (but after ratification, not freeze): https://sourceware.org/pipermail/binutils/2023-April/127027.html FWIW, I have meanwhile sent out a v5 for Binutils as well (there were few changes requested). And the v5 has been rebased and retested as well. > > > > > On Fri, May 5, 2023 at 5:03=E2=80=AFPM Christoph M=C3=BCllner > > wrote: > >> > >> On Wed, Apr 19, 2023 at 11:58=E2=80=AFAM Jin Ma wrote: > >> > > >> > This patch adds the 'Zfa' extension for riscv, which is based on: > >> > https://github.com/riscv/riscv-isa-manual/commits/zfb > >> > https://github.com/riscv/riscv-isa-manual/commit/1f038182810727f5f= eca311072e630d6baac51da > >> > > >> > The binutils-gdb for 'Zfa' extension: > >> > https://github.com/a4lg/binutils-gdb/commits/riscv-zfa > >> > > >> > What needs special explanation is: > >> > 1, The immediate number of the instructions FLI.H/S/D is represented= in the assembly as a > >> > floating-point value, with scientific counting when rs1 is 1,2, an= d decimal numbers for > >> > the rest. > >> > > >> > Related llvm link: > >> > https://reviews.llvm.org/D145645 > >> > Related discussion link: > >> > https://github.com/riscv/riscv-isa-manual/issues/980 > >> > > >> > 2, According to riscv-spec, "The FCVTMO D.W.D instruction was added = principally to > >> > accelerate the processing of JavaScript Numbers.", so it seems tha= t no implementation > >> > is required. > >> > > >> > 3, The instructions FMINM and FMAXM correspond to C23 library functi= on fminimum and fmaximum. > >> > Therefore, this patch has simply implemented the pattern of fminm<= hf\sf\df>3 and > >> > fmaxm3 to prepare for later. > >> > > >> > gcc/ChangeLog: > >> > > >> > * common/config/riscv/riscv-common.cc: Add zfa extension ver= sion. > >> > * config/riscv/constraints.md (Zf): Constrain the floating p= oint number that the > >> > instructions FLI.H/S/D can load. > >> > ((TARGET_XTHEADFMV || TARGET_ZFA) ? FP_REGS : NO_REGS): enab= le FMVP.D.X and FMVH.X.D. > >> > * config/riscv/iterators.md (ceil): New. > >> > * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_f= or_fli): New. > >> > * config/riscv/riscv.cc (find_index_in_array): New. > >> > (riscv_float_const_rtx_index_for_fli): Get the index of the = floating-point number that > >> > the instructions FLI.H/S/D can mov. > >> > (riscv_cannot_force_const_mem): If instruction FLI.H/S/D can= be used, memory is not applicable. > >> > (riscv_const_insns): The cost of FLI.H/S/D is 3. > >> > (riscv_legitimize_const_move): Likewise. > >> > (riscv_split_64bit_move_p): If instruction FLI.H/S/D can be = used, no split is required. > >> > (riscv_output_move): Output the mov instructions in zfa exte= nsion. > >> > (riscv_print_operand): Output the floating-point value of th= e FLI.H/S/D immediate in assembly > >> > (riscv_secondary_memory_needed): Likewise. > >> > * config/riscv/riscv.h (GP_REG_RTX_P): New. > >> > * config/riscv/riscv.md (fminm3): New. > >> > > >> > gcc/testsuite/ChangeLog: > >> > > >> > * gcc.target/riscv/zfa-fleq-fltq-rv32.c: New test. > >> > * gcc.target/riscv/zfa-fleq-fltq.c: New test. > >> > * gcc.target/riscv/zfa-fli-rv32.c: New test. > >> > * gcc.target/riscv/zfa-fli-zfh-rv32.c: New test. > >> > * gcc.target/riscv/zfa-fli-zfh.c: New test. > >> > * gcc.target/riscv/zfa-fli.c: New test. > >> > * gcc.target/riscv/zfa-fmovh-fmovp-rv32.c: New test. > >> > * gcc.target/riscv/zfa-fround-rv32.c: New test. > >> > * gcc.target/riscv/zfa-fround.c: New test. > >> > --- > >> > gcc/common/config/riscv/riscv-common.cc | 4 + > >> > gcc/config/riscv/constraints.md | 11 +- > >> > gcc/config/riscv/iterators.md | 5 + > >> > gcc/config/riscv/riscv-opts.h | 3 + > >> > gcc/config/riscv/riscv-protos.h | 1 + > >> > gcc/config/riscv/riscv.cc | 168 +++++++++++++++= ++- > >> > gcc/config/riscv/riscv.h | 1 + > >> > gcc/config/riscv/riscv.md | 112 +++++++++--- > >> > .../gcc.target/riscv/zfa-fleq-fltq-rv32.c | 19 ++ > >> > .../gcc.target/riscv/zfa-fleq-fltq.c | 19 ++ > >> > gcc/testsuite/gcc.target/riscv/zfa-fli-rv32.c | 79 ++++++++ > >> > .../gcc.target/riscv/zfa-fli-zfh-rv32.c | 41 +++++ > >> > gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c | 41 +++++ > >> > gcc/testsuite/gcc.target/riscv/zfa-fli.c | 79 ++++++++ > >> > .../gcc.target/riscv/zfa-fmovh-fmovp-rv32.c | 10 ++ > >> > .../gcc.target/riscv/zfa-fround-rv32.c | 42 +++++ > >> > gcc/testsuite/gcc.target/riscv/zfa-fround.c | 42 +++++ > >> > 17 files changed, 652 insertions(+), 25 deletions(-) > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv3= 2.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fli-rv32.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fli-zfh-rv32.= c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fli.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-r= v32.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fround-rv32.c > >> > create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fround.c > >> > > >> > diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/co= nfig/riscv/riscv-common.cc > >> > index 309a52def75..f9fce6bcc38 100644 > >> > --- a/gcc/common/config/riscv/riscv-common.cc > >> > +++ b/gcc/common/config/riscv/riscv-common.cc > >> > @@ -217,6 +217,8 @@ static const struct riscv_ext_version riscv_ext_= version_table[] =3D > >> > {"zfh", ISA_SPEC_CLASS_NONE, 1, 0}, > >> > {"zfhmin", ISA_SPEC_CLASS_NONE, 1, 0}, > >> > > >> > + {"zfa", ISA_SPEC_CLASS_NONE, 0, 2}, > >> > + > >> > {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0}, > >> > > >> > {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, > >> > @@ -1260,6 +1262,8 @@ static const riscv_ext_flag_table_t riscv_ext_= flag_table[] =3D > >> > {"zfhmin", &gcc_options::x_riscv_zf_subext, MASK_ZFHMIN}, > >> > {"zfh", &gcc_options::x_riscv_zf_subext, MASK_ZFH}, > >> > > >> > + {"zfa", &gcc_options::x_riscv_zf_subext, MASK_ZFA}, > >> > + > >> > {"zmmul", &gcc_options::x_riscv_zm_subext, MASK_ZMMUL}, > >> > > >> > {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL}, > >> > diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/cons= traints.md > >> > index c448e6b37e9..62d9094f966 100644 > >> > --- a/gcc/config/riscv/constraints.md > >> > +++ b/gcc/config/riscv/constraints.md > >> > @@ -118,6 +118,13 @@ (define_constraint "T" > >> > (and (match_operand 0 "move_operand") > >> > (match_test "CONSTANT_P (op)"))) > >> > > >> > +;; Zfa constraints. > >> > + > >> > +(define_constraint "Zf" > >> > + "A floating point number that can be loaded using instruction `fl= i` in zfa." > >> > + (and (match_code "const_double") > >> > + (match_test "(riscv_float_const_rtx_index_for_fli (op) !=3D = -1)"))) > >> > + > >> > ;; Vector constraints. > >> > > >> > (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS" > >> > @@ -183,8 +190,8 @@ (define_memory_constraint "Wdm" > >> > > >> > ;; Vendor ISA extension constraints. > >> > > >> > -(define_register_constraint "th_f_fmv" "TARGET_XTHEADFMV ? FP_REGS = : NO_REGS" > >> > +(define_register_constraint "th_f_fmv" "(TARGET_XTHEADFMV || TARGET= _ZFA) ? FP_REGS : NO_REGS" > >> > "A floating-point register for XTheadFmv.") > >> > > >> > -(define_register_constraint "th_r_fmv" "TARGET_XTHEADFMV ? GR_REGS = : NO_REGS" > >> > +(define_register_constraint "th_r_fmv" "(TARGET_XTHEADFMV || TARGET= _ZFA) ? GR_REGS : NO_REGS" > >> > "An integer register for XTheadFmv.") > >> > >> These are vendor extension constraints with the prefix "th_". > >> I would avoid using them in code that targets standard extensions. > >> > >> I see two ways here: > >> a) Create two new constraints at the top of the file. E.g.: > >> - "F" - "A floating-point register (no fall-back for Zfinx)" and > >> - "rF" - "A integer register in case FP registers are available". > >> b) Move to top and rename these two constraints (and adjust > >> movdf_hardfloat_rv32 accordingly) > >> > >> I would prefer b) and would even go so far, that I would do this in a > >> separate commit that > >> comes before the Zfa support patch. > >> > >> > >> I've applied the patch on top of today's master (with --3way) and > >> successfully tested it: > >> Tested-by: Christoph M=C3=BCllner > >> > >> > diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterat= ors.md > >> > index 9b767038452..c81b08e3cc5 100644 > >> > --- a/gcc/config/riscv/iterators.md > >> > +++ b/gcc/config/riscv/iterators.md > >> > @@ -288,3 +288,8 @@ (define_int_iterator QUIET_COMPARISON [UNSPEC_FL= T_QUIET UNSPEC_FLE_QUIET]) > >> > (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE= _QUIET "le")]) > >> > (define_int_attr QUIET_PATTERN [(UNSPEC_FLT_QUIET "LT") (UNSPEC_FLE= _QUIET "LE")]) > >> > > >> > +(define_int_iterator ROUND [UNSPEC_ROUND UNSPEC_FLOOR UNSPEC_CEIL U= NSPEC_BTRUNC UNSPEC_ROUNDEVEN UNSPEC_NEARBYINT]) > >> > +(define_int_attr round_pattern [(UNSPEC_ROUND "round") (UNSPEC_FLOO= R "floor") (UNSPEC_CEIL "ceil") > >> > + (UNSPEC_BTRUNC "btrunc") (UNSPEC_ROU= NDEVEN "roundeven") (UNSPEC_NEARBYINT "nearbyint")]) > >> > +(define_int_attr round_rm [(UNSPEC_ROUND "rmm") (UNSPEC_FLOOR "rdn"= ) (UNSPEC_CEIL "rup") > >> > + (UNSPEC_BTRUNC "rtz") (UNSPEC_ROUNDEVEN "= rne") (UNSPEC_NEARBYINT "dyn")]) > >> > \ No newline at end of file > >> > diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-= opts.h > >> > index cf0cd669be4..87b72efd12e 100644 > >> > --- a/gcc/config/riscv/riscv-opts.h > >> > +++ b/gcc/config/riscv/riscv-opts.h > >> > @@ -172,6 +172,9 @@ enum stack_protector_guard { > >> > #define TARGET_ZFHMIN ((riscv_zf_subext & MASK_ZFHMIN) !=3D 0) > >> > #define TARGET_ZFH ((riscv_zf_subext & MASK_ZFH) !=3D 0) > >> > > >> > +#define MASK_ZFA (1 << 0) > >> > +#define TARGET_ZFA ((riscv_zf_subext & MASK_ZFA) !=3D 0) > >> > + > >> > #define MASK_ZMMUL (1 << 0) > >> > #define TARGET_ZMMUL ((riscv_zm_subext & MASK_ZMMUL) !=3D 0) > >> > > >> > diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/risc= v-protos.h > >> > index 5244e8dcbf0..e421244a06c 100644 > >> > --- a/gcc/config/riscv/riscv-protos.h > >> > +++ b/gcc/config/riscv/riscv-protos.h > >> > @@ -38,6 +38,7 @@ enum riscv_symbol_type { > >> > /* Routines implemented in riscv.cc. */ > >> > extern enum riscv_symbol_type riscv_classify_symbolic_expression (r= tx); > >> > extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type = *); > >> > +extern int riscv_float_const_rtx_index_for_fli (rtx); > >> > extern int riscv_regno_mode_ok_for_base_p (int, machine_mode, bool)= ; > >> > extern int riscv_address_insns (rtx, machine_mode, bool); > >> > extern int riscv_const_insns (rtx); > >> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > >> > index cdb47e81e7c..faffedffe97 100644 > >> > --- a/gcc/config/riscv/riscv.cc > >> > +++ b/gcc/config/riscv/riscv.cc > >> > @@ -799,6 +799,116 @@ static int riscv_symbol_insns (enum riscv_symb= ol_type type) > >> > } > >> > } > >> > > >> > +/* Immediate values loaded by the FLI.S instruction in Chapter 25 o= f the latest RISC-V ISA > >> > + Manual draft. For details, please see: > >> > + https://github.com/riscv/riscv-isa-manual/releases/tag/draft-202= 21217-cb3b9d1 */ > >> > + > >> > +unsigned HOST_WIDE_INT fli_value_hf[32] =3D > >> > +{ > >> > + 0xbc00, 0x400, 0x100, 0x200, 0x1c00, 0x2000, 0x2c00, 0x3000, > >> > + 0x3400, 0x3500, 0x3600, 0x3700, 0x3800, 0x3900, 0x3a00, 0x3b00, > >> > + 0x3c00, 0x3d00, 0x3e00, 0x3f00, 0x4000, 0x4100, 0x4200, 0x4400, > >> > + 0x4800, 0x4c00, 0x5800, 0x5c00, 0x7800, > >> > + /* Only used for filling, ensuring that 29 and 30 of HF are the s= ame. */ > >> > + 0x7800, > >> > + 0x7c00, 0x7e00, > >> > +}; > >> > + > >> > +unsigned HOST_WIDE_INT fli_value_sf[32] =3D > >> > +{ > >> > + 0xbf800000, 0x00800000, 0x37800000, 0x38000000, 0x3b800000, 0x3c0= 00000, 0x3d800000, 0x3e000000, > >> > + 0x3e800000, 0x3ea00000, 0x3ec00000, 0x3ee00000, 0x3f000000, 0x3f2= 00000, 0x3f400000, 0x3f600000, > >> > + 0x3f800000, 0x3fa00000, 0x3fc00000, 0x3fe00000, 0x40000000, 0x402= 00000, 0x40400000, 0x40800000, > >> > + 0x41000000, 0x41800000, 0x43000000, 0x43800000, 0x47000000, 0x478= 00000, 0x7f800000, 0x7fc00000 > >> > +}; > >> > + > >> > +unsigned HOST_WIDE_INT fli_value_df[32] =3D > >> > +{ > >> > + 0xbff0000000000000, 0x10000000000000, 0x3ef0000000000000, 0x3f000= 00000000000, > >> > + 0x3f70000000000000, 0x3f80000000000000, 0x3fb0000000000000, 0x3fc= 0000000000000, > >> > + 0x3fd0000000000000, 0x3fd4000000000000, 0x3fd8000000000000, 0x3fd= c000000000000, > >> > + 0x3fe0000000000000, 0x3fe4000000000000, 0x3fe8000000000000, 0x3fe= c000000000000, > >> > + 0x3ff0000000000000, 0x3ff4000000000000, 0x3ff8000000000000, 0x3ff= c000000000000, > >> > + 0x4000000000000000, 0x4004000000000000, 0x4008000000000000, 0x401= 0000000000000, > >> > + 0x4020000000000000, 0x4030000000000000, 0x4060000000000000, 0x407= 0000000000000, > >> > + 0x40e0000000000000, 0x40f0000000000000, 0x7ff0000000000000, 0x7ff= 8000000000000, > >> > +}; > >> > + > >> > +const char *fli_value_print[32] =3D > >> > +{ > >> > + "-1.0", "min", "1.52587890625e-05", "3.0517578125e-05", "0.003906= 25", "0.0078125", "0.0625", "0.125", > >> > + "0.25", "0.3125", "0.375", "0.4375", "0.5", "0.625", "0.75", "0.8= 75", > >> > + "1.0", "1.25", "1.5", "1.75", "2.0", "2.5", "3.0", "4.0", > >> > + "8.0", "16.0", "128.0", "256.0", "32768.0", "65536.0", "inf", "na= n" > >> > +}; > >> > + > >> > +/* Find the index of TARGET in ARRAY, and return -1 if not found. *= / > >> > + > >> > +static int > >> > +find_index_in_array (unsigned HOST_WIDE_INT target, unsigned HOST_W= IDE_INT *array, int len) > >> > +{ > >> > + if (array =3D=3D NULL) > >> > + return -1; > >> > + > >> > + for (int i =3D 0; i < len; i++) > >> > + { > >> > + if (target =3D=3D array[i]) > >> > + return i; > >> > + } > >> > + return -1; > >> > +} > >> > + > >> > +/* Return index of the FLI instruction table if rtx X is an immedia= te constant that > >> > + can be moved using a single FLI instruction in zfa extension. -1= otherwise. */ > >> > + > >> > +int > >> > +riscv_float_const_rtx_index_for_fli (rtx x) > >> > +{ > >> > + machine_mode mode =3D GET_MODE (x); > >> > + > >> > + if (!TARGET_ZFA || mode =3D=3D VOIDmode > >> > + || !CONST_DOUBLE_P(x) > >> > + || (mode =3D=3D HFmode && !TARGET_ZFH) > >> > + || (mode =3D=3D SFmode && !TARGET_HARD_FLOAT) > >> > + || (mode =3D=3D DFmode && !TARGET_DOUBLE_FLOAT)) > >> > + return -1; > >> > + > >> > + if (!SCALAR_FLOAT_MODE_P (mode) > >> > + || GET_MODE_BITSIZE (mode).to_constant () > HOST_BITS_PER_WID= E_INT > >> > + /* Only support up to DF mode. */ > >> > + || GET_MODE_BITSIZE (mode).to_constant () > GET_MODE_BITSIZE = (DFmode)) > >> > + return -1; > >> > + > >> > + unsigned HOST_WIDE_INT ival =3D 0; > >> > + > >> > + long res[2]; > >> > + real_to_target (res, > >> > + CONST_DOUBLE_REAL_VALUE (x), > >> > + REAL_MODE_FORMAT (mode)); > >> > + > >> > + if (mode =3D=3D DFmode) > >> > + { > >> > + int order =3D BYTES_BIG_ENDIAN ? 1 : 0; > >> > + ival =3D zext_hwi (res[order], 32); > >> > + ival |=3D (zext_hwi (res[1 - order], 32) << 32); > >> > + } > >> > + else > >> > + ival =3D zext_hwi (res[0], 32); > >> > + > >> > + switch (mode) > >> > + { > >> > + case SFmode: > >> > + return find_index_in_array (ival, fli_value_sf, 32); > >> > + case DFmode: > >> > + return find_index_in_array (ival, fli_value_df, 32); > >> > + case HFmode: > >> > + return find_index_in_array (ival, fli_value_hf, 32); > >> > + default: > >> > + break; > >> > + } > >> > + return -1; > >> > +} > >> > + > >> > /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ > >> > > >> > static bool > >> > @@ -826,6 +936,9 @@ riscv_cannot_force_const_mem (machine_mode mode = ATTRIBUTE_UNUSED, rtx x) > >> > if (GET_CODE (x) =3D=3D HIGH) > >> > return true; > >> > > >> > + if (riscv_float_const_rtx_index_for_fli (x) !=3D -1) > >> > + return true; > >> > + > >> > split_const (x, &base, &offset); > >> > if (riscv_symbolic_constant_p (base, &type)) > >> > { > >> > @@ -1213,6 +1326,11 @@ riscv_const_insns (rtx x) > >> > } > >> > > >> > case CONST_DOUBLE: > >> > + /* See if we can use FMV directly. */ > >> > + if (riscv_float_const_rtx_index_for_fli (x) !=3D -1) > >> > + return 3; > >> > + /* Fall through. */ > >> > + > >> > case CONST_VECTOR: > >> > /* We can use x0 to load floating-point zero. */ > >> > return x =3D=3D CONST0_RTX (GET_MODE (x)) ? 1 : 0; > >> > @@ -1749,6 +1867,12 @@ riscv_legitimize_const_move (machine_mode mod= e, rtx dest, rtx src) > >> > return; > >> > } > >> > > >> > + if (riscv_float_const_rtx_index_for_fli (src) !=3D -1) > >> > + { > >> > + riscv_emit_set (dest, src); > >> > + return; > >> > + } > >> > + > >> > /* Split moves of symbolic constants into high/low pairs. */ > >> > if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src, FALSE)= ) > >> > { > >> > @@ -2770,12 +2894,19 @@ riscv_split_64bit_move_p (rtx dest, rtx src) > >> > if (TARGET_64BIT) > >> > return false; > >> > > >> > + /* There is no need to split if the FLI instruction in the `Zfa` = extension can be used. */ > >> > + if (riscv_float_const_rtx_index_for_fli (src) !=3D -1) > >> > + return false; > >> > + > >> > /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the specia= l case > >> > of zeroing an FPR with FCVT.D.W. */ > >> > if (TARGET_DOUBLE_FLOAT > >> > && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest)) > >> > || (FP_REG_RTX_P (dest) && MEM_P (src)) > >> > || (FP_REG_RTX_P (src) && MEM_P (dest)) > >> > + || (TARGET_ZFA > >> > + && ((FP_REG_RTX_P (dest) && GP_REG_RTX_P (src)) > >> > + || (FP_REG_RTX_P (src) && GP_REG_RTX_P (dest)))) > >> > || (FP_REG_RTX_P (dest) && src =3D=3D CONST0_RTX (GET_MODE= (src))))) > >> > return false; > >> > > >> > @@ -2857,6 +2988,8 @@ riscv_output_move (rtx dest, rtx src) > >> > case 4: > >> > return "fmv.x.s\t%0,%1"; > >> > case 8: > >> > + if (!TARGET_64BIT && TARGET_ZFA) > >> > + return "fmv.x.w\t%0,%1\n\tfmvh.x.d\t%N0,%1"; > >> > return "fmv.x.d\t%0,%1"; > >> > } > >> > > >> > @@ -2916,6 +3049,8 @@ riscv_output_move (rtx dest, rtx src) > >> > case 8: > >> > if (TARGET_64BIT) > >> > return "fmv.d.x\t%0,%z1"; > >> > + else if (TARGET_ZFA && src !=3D CONST0_RTX (mode)) > >> > + return "fmvp.d.x\t%0,%1,%N1"; > >> > /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt= .d.w */ > >> > gcc_assert (src =3D=3D CONST0_RTX (mode)); > >> > return "fcvt.d.w\t%0,x0"; > >> > @@ -2968,6 +3103,14 @@ riscv_output_move (rtx dest, rtx src) > >> > case 8: > >> > return "fld\t%0,%1"; > >> > } > >> > + > >> > + if (src_code =3D=3D CONST_DOUBLE && (riscv_float_const_rtx_in= dex_for_fli (src) !=3D -1)) > >> > + switch (width) > >> > + { > >> > + case 2: return "fli.h\t%0,%1"; > >> > + case 4: return "fli.s\t%0,%1"; > >> > + case 8: return "fli.d\t%0,%1"; > >> > + } > >> > } > >> > if (dest_code =3D=3D REG && GP_REG_P (REGNO (dest)) && src_code = =3D=3D CONST_POLY_INT) > >> > { > >> > @@ -4349,6 +4492,7 @@ riscv_memmodel_needs_release_fence (enum memmo= del model) > >> > 'S' Print shift-index of single-bit mask OP. > >> > 'T' Print shift-index of inverted single-bit mask OP. > >> > '~' Print w if TARGET_64BIT is true; otherwise not print anythin= g. > >> > + 'N' Print next register. > >> > > >> > Note please keep this list and the list in riscv.md in sync. */ > >> > > >> > @@ -4533,6 +4677,9 @@ riscv_print_operand (FILE *file, rtx op, int l= etter) > >> > output_addr_const (file, newop); > >> > break; > >> > } > >> > + case 'N': > >> > + fputs (reg_names[REGNO (op) + 1], file); > >> > + break; > >> > default: > >> > switch (code) > >> > { > >> > @@ -4549,6 +4696,24 @@ riscv_print_operand (FILE *file, rtx op, int = letter) > >> > output_address (mode, XEXP (op, 0)); > >> > break; > >> > > >> > + case CONST_DOUBLE: > >> > + { > >> > + if (letter =3D=3D 'z' && op =3D=3D CONST0_RTX (GET_MODE = (op))) > >> > + { > >> > + fputs (reg_names[GP_REG_FIRST], file); > >> > + break; > >> > + } > >> > + > >> > + int fli_index =3D riscv_float_const_rtx_index_for_fli (o= p); > >> > + if (fli_index =3D=3D -1 || fli_index > 31) > >> > + { > >> > + output_operand_lossage ("invalid use of '%%%c'", let= ter); > >> > + break; > >> > + } > >> > + asm_fprintf (file, "%s", fli_value_print[fli_index]); > >> > + break; > >> > + } > >> > + > >> > default: > >> > if (letter =3D=3D 'z' && op =3D=3D CONST0_RTX (GET_MODE (o= p))) > >> > fputs (reg_names[GP_REG_FIRST], file); > >> > @@ -5897,7 +6062,8 @@ riscv_secondary_memory_needed (machine_mode mo= de, reg_class_t class1, > >> > return (!riscv_v_ext_vector_mode_p (mode) > >> > && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD > >> > && (class1 =3D=3D FP_REGS) !=3D (class2 =3D=3D FP_REGS) > >> > - && !TARGET_XTHEADFMV); > >> > + && !TARGET_XTHEADFMV > >> > + && !TARGET_ZFA); > >> > } > >> > > >> > /* Implement TARGET_REGISTER_MOVE_COST. */ > >> > diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h > >> > index 66fb07d6652..d438b281142 100644 > >> > --- a/gcc/config/riscv/riscv.h > >> > +++ b/gcc/config/riscv/riscv.h > >> > @@ -377,6 +377,7 @@ ASM_MISA_SPEC > >> > #define SIBCALL_REG_P(REGNO) \ > >> > TEST_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], REGNO) > >> > > >> > +#define GP_REG_RTX_P(X) (REG_P (X) && GP_REG_P (REGNO (X))) > >> > #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X))) > >> > > >> > /* Use s0 as the frame pointer if it is so requested. */ > >> > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > >> > index bc384d9aedf..f22e71b5a3a 100644 > >> > --- a/gcc/config/riscv/riscv.md > >> > +++ b/gcc/config/riscv/riscv.md > >> > @@ -59,6 +59,15 @@ (define_c_enum "unspec" [ > >> > UNSPEC_LROUND > >> > UNSPEC_FMIN > >> > UNSPEC_FMAX > >> > + UNSPEC_RINT > >> > + UNSPEC_ROUND > >> > + UNSPEC_FLOOR > >> > + UNSPEC_CEIL > >> > + UNSPEC_BTRUNC > >> > + UNSPEC_ROUNDEVEN > >> > + UNSPEC_NEARBYINT > >> > + UNSPEC_FMINM > >> > + UNSPEC_FMAXM > >> > > >> > ;; Stack tie > >> > UNSPEC_TIE > >> > @@ -1232,6 +1241,26 @@ (define_insn "neg2" > >> > ;; > >> > ;; .................... > >> > > >> > +(define_insn "fminm3" > >> > + [(set (match_operand:ANYF 0 "register_operand"= "=3Df") > >> > + (unspec:ANYF [(use (match_operand:ANYF 1 "register_operand" = " f")) > >> > + (use (match_operand:ANYF 2 "register_operand" = " f"))] > >> > + UNSPEC_FMINM))] > >> > + "TARGET_HARD_FLOAT && TARGET_ZFA" > >> > + "fminm.\t%0,%1,%2" > >> > + [(set_attr "type" "fmove") > >> > + (set_attr "mode" "")]) > >> > + > >> > +(define_insn "fmaxm3" > >> > + [(set (match_operand:ANYF 0 "register_operand"= "=3Df") > >> > + (unspec:ANYF [(use (match_operand:ANYF 1 "register_operand" = " f")) > >> > + (use (match_operand:ANYF 2 "register_operand" = " f"))] > >> > + UNSPEC_FMAXM))] > >> > + "TARGET_HARD_FLOAT && TARGET_ZFA" > >> > + "fmaxm.\t%0,%1,%2" > >> > + [(set_attr "type" "fmove") > >> > + (set_attr "mode" "")]) > >> > + > >> > (define_insn "fmin3" > >> > [(set (match_operand:ANYF 0 "register_operand"= "=3Df") > >> > (unspec:ANYF [(use (match_operand:ANYF 1 "register_operand" = " f")) > >> > @@ -1508,13 +1537,13 @@ (define_expand "movhf" > >> > }) > >> > > >> > (define_insn "*movhf_hardfloat" > >> > - [(set (match_operand:HF 0 "nonimmediate_operand" "=3Df,f,f,m,m,*f= ,*r, *r,*r,*m") > >> > - (match_operand:HF 1 "move_operand" " f,G,m,f,G,*r,*f= ,*G*r,*m,*r"))] > >> > + [(set (match_operand:HF 0 "nonimmediate_operand" "=3Df, f,f,f,m,m= ,*f,*r, *r,*r,*m") > >> > + (match_operand:HF 1 "move_operand" " f,Zf,G,m,f,G,*r= ,*f,*G*r,*m,*r"))] > >> > "TARGET_ZFHMIN > >> > && (register_operand (operands[0], HFmode) > >> > || reg_or_0_operand (operands[1], HFmode))" > >> > { return riscv_output_move (operands[0], operands[1]); } > >> > - [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,mo= ve,load,store") > >> > + [(set_attr "move_type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,= mfc,move,load,store") > >> > (set_attr "mode" "HF")]) > >> > > >> > (define_insn "*movhf_softfloat" > >> > @@ -1580,6 +1609,26 @@ (define_insn "l2" > >> > [(set_attr "type" "fcvt") > >> > (set_attr "mode" "")]) > >> > > >> > +(define_insn "2" > >> > + [(set (match_operand:ANYF 0 "register_operand" "=3Df") > >> > + (unspec:ANYF > >> > + [(match_operand:ANYF 1 "register_operand" " f")] > >> > + ROUND))] > >> > + "TARGET_HARD_FLOAT && TARGET_ZFA" > >> > + "fround.\t%0,%1," > >> > + [(set_attr "type" "fcvt") > >> > + (set_attr "mode" "")]) > >> > + > >> > +(define_insn "rint2" > >> > + [(set (match_operand:ANYF 0 "register_operand" "=3Df") > >> > + (unspec:ANYF > >> > + [(match_operand:ANYF 1 "register_operand" " f")] > >> > + UNSPEC_RINT))] > >> > + "TARGET_HARD_FLOAT && TARGET_ZFA" > >> > + "froundnx.\t%0,%1" > >> > + [(set_attr "type" "fcvt") > >> > + (set_attr "mode" "")]) > >> > + > >> > ;; > >> > ;; .................... > >> > ;; > >> > @@ -1839,13 +1888,13 @@ (define_expand "movsf" > >> > }) > >> > > >> > (define_insn "*movsf_hardfloat" > >> > - [(set (match_operand:SF 0 "nonimmediate_operand" "=3Df,f,f,m,m,*f= ,*r, *r,*r,*m") > >> > - (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f= ,*G*r,*m,*r"))] > >> > + [(set (match_operand:SF 0 "nonimmediate_operand" "=3Df, f,f,f,m,m= ,*f,*r, *r,*r,*m") > >> > + (match_operand:SF 1 "move_operand" " f,Zf,G,m,f,G,*r= ,*f,*G*r,*m,*r"))] > >> > "TARGET_HARD_FLOAT > >> > && (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,mo= ve,load,store") > >> > + [(set_attr "move_type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,= mfc,move,load,store") > >> > (set_attr "mode" "SF")]) > >> > > >> > (define_insn "*movsf_softfloat" > >> > @@ -1873,23 +1922,23 @@ (define_expand "movdf" > >> > ;; 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 reg= ister.) > >> > (define_insn "*movdf_hardfloat_rv32" > >> > - [(set (match_operand:DF 0 "nonimmediate_operand" "=3Df,f,f,m,m,*t= h_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"))] > >> > + [(set (match_operand:DF 0 "nonimmediate_operand" "=3Df, f,f,f,m,m= ,*th_f_fmv,*th_r_fmv, *r,*r,*m") > >> > + (match_operand:DF 1 "move_operand" " f,Zf,G,m,f,G,*t= h_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,mtc,mfc,mo= ve,load,store") > >> > + [(set_attr "move_type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,= mfc,move,load,store") > >> > (set_attr "mode" "DF")]) > >> > > >> > (define_insn "*movdf_hardfloat_rv64" > >> > - [(set (match_operand:DF 0 "nonimmediate_operand" "=3Df,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"))] > >> > + [(set (match_operand:DF 0 "nonimmediate_operand" "=3Df, f,f,f,m,m= ,*f,*r, *r,*r,*m") > >> > + (match_operand:DF 1 "move_operand" " f,Zf,G,m,f,G,*r= ,*f,*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,mtc,mfc,mo= ve,load,store") > >> > + [(set_attr "move_type" "fmove,fmove,mtc,fpload,fpstore,store,mtc,= mfc,move,load,store") > >> > (set_attr "mode" "DF")]) > >> > > >> > (define_insn "*movdf_softfloat" > >> > @@ -2494,16 +2543,23 @@ (define_expand "f_quiet4" > >> > rtx op0 =3D operands[0]; > >> > rtx op1 =3D operands[1]; > >> > rtx op2 =3D operands[2]; > >> > - rtx tmp =3D gen_reg_rtx (SImode); > >> > - rtx cmp =3D gen_rtx_ (mode, op1, op2); > >> > - rtx frflags =3D gen_rtx_UNSPEC_VOLATILE (SImode, gen_rtvec (1, co= nst0_rtx), > >> > - UNSPECV_FRFLAGS); > >> > - rtx fsflags =3D gen_rtx_UNSPEC_VOLATILE (SImode, gen_rtvec (1, tm= p), > >> > - UNSPECV_FSFLAGS); > >> > - > >> > - emit_insn (gen_rtx_SET (tmp, frflags)); > >> > - emit_insn (gen_rtx_SET (op0, cmp)); > >> > - emit_insn (fsflags); > >> > + > >> > + if (TARGET_ZFA) > >> > + emit_insn (gen_f_quiet4_zfa(o= p0, op1, op2)); > >> > + else > >> > + { > >> > + rtx tmp =3D gen_reg_rtx (SImode); > >> > + rtx cmp =3D gen_rtx_ (mode, op1, op2); > >> > + rtx frflags =3D gen_rtx_UNSPEC_VOLATILE (SImode, gen_rtvec (1= , const0_rtx), > >> > + UNSPECV_FRFLAGS); > >> > + rtx fsflags =3D gen_rtx_UNSPEC_VOLATILE (SImode, gen_rtvec (1= , tmp), > >> > + UNSPECV_FSFLAGS); > >> > + > >> > + emit_insn (gen_rtx_SET (tmp, frflags)); > >> > + emit_insn (gen_rtx_SET (op0, cmp)); > >> > + emit_insn (fsflags); > >> > + } > >> > + > >> > if (HONOR_SNANS (mode)) > >> > emit_insn (gen_rtx_UNSPEC_VOLATILE (mode, > >> > gen_rtvec (2, op1, op2), > >> > @@ -2511,6 +2567,18 @@ (define_expand "f_quiet4" > >> > DONE; > >> > }) > >> > > >> > +(define_insn "f_quiet4_zfa" > >> > + [(set (match_operand:X 0 "register_operand" "=3Dr") > >> > + (unspec:X > >> > + [(match_operand:ANYF 1 "register_operand" " f") > >> > + (match_operand:ANYF 2 "register_operand" " f")] > >> > + QUIET_COMPARISON))] > >> > + "TARGET_HARD_FLOAT && TARGET_ZFA" > >> > + "fq.\t%0,%1,%2" > >> > + [(set_attr "type" "fcmp") > >> > + (set_attr "mode" "") > >> > + (set (attr "length") (const_int 16))]) > >> > + > >> > (define_insn "*seq_zero_" > >> > [(set (match_operand:GPR 0 "register_operand" "=3Dr") > >> > (eq:GPR (match_operand:X 1 "register_operand" " r") > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv32.c b/g= cc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv32.c > >> > new file mode 100644 > >> > index 00000000000..26895b76fa4 > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv32.c > >> > @@ -0,0 +1,19 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv32imafdc_zfa -mabi=3Dilp32d -O2" } */ > >> > + > >> > +extern void abort(void); > >> > +extern float a, b; > >> > +extern double c, d; > >> > + > >> > +void > >> > +foo() > >> > +{ > >> > + if ((__builtin_isless(a, b) || __builtin_islessequal(c, d)) > >> > + && (__builtin_islessequal(a, b)|| __builtin_isless(c, d))) > >> > + abort(); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fleq.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fltq.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fleq.d" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fltq.d" 1 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.c b/gcc/te= stsuite/gcc.target/riscv/zfa-fleq-fltq.c > >> > new file mode 100644 > >> > index 00000000000..4ccd6a7dd78 > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.c > >> > @@ -0,0 +1,19 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv64imafdc_zfa -mabi=3Dlp64d -O2" } */ > >> > + > >> > +extern void abort(void); > >> > +extern float a, b; > >> > +extern double c, d; > >> > + > >> > +void > >> > +foo() > >> > +{ > >> > + if ((__builtin_isless(a, b) || __builtin_islessequal(c, d)) > >> > + && (__builtin_islessequal(a, b)|| __builtin_isless(c, d))) > >> > + abort(); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fleq.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fltq.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fleq.d" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fltq.d" 1 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fli-rv32.c b/gcc/tes= tsuite/gcc.target/riscv/zfa-fli-rv32.c > >> > new file mode 100644 > >> > index 00000000000..c4da04797aa > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fli-rv32.c > >> > @@ -0,0 +1,79 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv32imafdc_zfa -mabi=3Dilp32d -O0" } */ > >> > + > >> > +void foo_float32 () > >> > +{ > >> > + volatile float a; > >> > + a =3D -1.0; > >> > + a =3D 1.1754944e-38; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inff (); > >> > + a =3D __builtin_nanf (""); > >> > +} > >> > + > >> > +void foo_double64 () > >> > +{ > >> > + volatile double a; > >> > + a =3D -1.0; > >> > + a =3D 2.2250738585072014E-308; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inf (); > >> > + a =3D __builtin_nan (""); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fli.s" 32 } } */ > >> > +/* { dg-final { scan-assembler-times "fli.d" 32 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fli-zfh-rv32.c b/gcc= /testsuite/gcc.target/riscv/zfa-fli-zfh-rv32.c > >> > new file mode 100644 > >> > index 00000000000..bcffe9d2c82 > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fli-zfh-rv32.c > >> > @@ -0,0 +1,41 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv32imafdc_zfa_zfh -mabi=3Dilp32d -O0" } = */ > >> > + > >> > +void foo_float16 () > >> > +{ > >> > + volatile _Float16 a; > >> > + a =3D -1.0; > >> > + a =3D 6.104E-5; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inff16 (); > >> > + a =3D __builtin_nanf16 (""); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fli.h" 32 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c b/gcc/test= suite/gcc.target/riscv/zfa-fli-zfh.c > >> > new file mode 100644 > >> > index 00000000000..13aa7b5f846 > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c > >> > @@ -0,0 +1,41 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv64imafdc_zfa_zfh -mabi=3Dlp64d -O0" } *= / > >> > + > >> > +void foo_float16 () > >> > +{ > >> > + volatile _Float16 a; > >> > + a =3D -1.0; > >> > + a =3D 6.104E-5; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inff16 (); > >> > + a =3D __builtin_nanf16 (""); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fli.h" 32 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fli.c b/gcc/testsuit= e/gcc.target/riscv/zfa-fli.c > >> > new file mode 100644 > >> > index 00000000000..b6d41cf460f > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fli.c > >> > @@ -0,0 +1,79 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv64imafdc_zfa -mabi=3Dlp64d -O0" } */ > >> > + > >> > +void foo_float32 () > >> > +{ > >> > + volatile float a; > >> > + a =3D -1.0; > >> > + a =3D 1.1754944e-38; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inff (); > >> > + a =3D __builtin_nanf (""); > >> > +} > >> > + > >> > +void foo_double64 () > >> > +{ > >> > + volatile double a; > >> > + a =3D -1.0; > >> > + a =3D 2.2250738585072014E-308; > >> > + a =3D 1.0/(1 << 16); > >> > + a =3D 1.0/(1 << 15); > >> > + a =3D 1.0/(1 << 8); > >> > + a =3D 1.0/(1 << 7); > >> > + a =3D 1.0/(1 << 4); > >> > + a =3D 1.0/(1 << 3); > >> > + a =3D 1.0/(1 << 2); > >> > + a =3D 0.3125; > >> > + a =3D 0.375; > >> > + a =3D 0.4375; > >> > + a =3D 0.5; > >> > + a =3D 0.625; > >> > + a =3D 0.75; > >> > + a =3D 0.875; > >> > + a =3D 1.0; > >> > + a =3D 1.25; > >> > + a =3D 1.5; > >> > + a =3D 1.75; > >> > + a =3D 2.0; > >> > + a =3D 2.5; > >> > + a =3D 3.0; > >> > + a =3D 1.0*(1 << 2); > >> > + a =3D 1.0*(1 << 3); > >> > + a =3D 1.0*(1 << 4); > >> > + a =3D 1.0*(1 << 7); > >> > + a =3D 1.0*(1 << 8); > >> > + a =3D 1.0*(1 << 15); > >> > + a =3D 1.0*(1 << 16); > >> > + a =3D __builtin_inf (); > >> > + a =3D __builtin_nan (""); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fli.s" 32 } } */ > >> > +/* { dg-final { scan-assembler-times "fli.d" 32 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-rv32.c b= /gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-rv32.c > >> > new file mode 100644 > >> > index 00000000000..5a52adce36a > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-rv32.c > >> > @@ -0,0 +1,10 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv32g_zfa -mabi=3Dilp32 -O0" } */ > >> > + > >> > +double foo(long long a) > >> > +{ > >> > + return (double)(a + 3); > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fmvp.d.x" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "fmvh.x.d" 1 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fround-rv32.c b/gcc/= testsuite/gcc.target/riscv/zfa-fround-rv32.c > >> > new file mode 100644 > >> > index 00000000000..b53601d6e1f > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fround-rv32.c > >> > @@ -0,0 +1,42 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv32imafdc_zfa -mabi=3Dilp32d -O2" } */ > >> > + > >> > +extern float a; > >> > +extern double b; > >> > + > >> > +void foo (float *x, double *y) > >> > +{ > >> > + { > >> > + *x =3D __builtin_roundf (a); > >> > + *y =3D __builtin_round (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_floorf (a); > >> > + *y =3D __builtin_floor (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_ceilf (a); > >> > + *y =3D __builtin_ceil (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_truncf (a); > >> > + *y =3D __builtin_trunc (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_roundevenf (a); > >> > + *y =3D __builtin_roundeven (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_nearbyintf (a); > >> > + *y =3D __builtin_nearbyint (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_rintf (a); > >> > + *y =3D __builtin_rint (b); > >> > + } > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fround.s" 6 } } */ > >> > +/* { dg-final { scan-assembler-times "fround.d" 6 } } */ > >> > +/* { dg-final { scan-assembler-times "froundnx.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "froundnx.d" 1 } } */ > >> > diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fround.c b/gcc/tests= uite/gcc.target/riscv/zfa-fround.c > >> > new file mode 100644 > >> > index 00000000000..c10de82578e > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.target/riscv/zfa-fround.c > >> > @@ -0,0 +1,42 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-march=3Drv64imafdc_zfa -mabi=3Dlp64d -O2" } */ > >> > + > >> > +extern float a; > >> > +extern double b; > >> > + > >> > +void foo (float *x, double *y) > >> > +{ > >> > + { > >> > + *x =3D __builtin_roundf (a); > >> > + *y =3D __builtin_round (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_floorf (a); > >> > + *y =3D __builtin_floor (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_ceilf (a); > >> > + *y =3D __builtin_ceil (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_truncf (a); > >> > + *y =3D __builtin_trunc (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_roundevenf (a); > >> > + *y =3D __builtin_roundeven (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_nearbyintf (a); > >> > + *y =3D __builtin_nearbyint (b); > >> > + } > >> > + { > >> > + *x =3D __builtin_rintf (a); > >> > + *y =3D __builtin_rint (b); > >> > + } > >> > +} > >> > + > >> > +/* { dg-final { scan-assembler-times "fround.s" 6 } } */ > >> > +/* { dg-final { scan-assembler-times "fround.d" 6 } } */ > >> > +/* { dg-final { scan-assembler-times "froundnx.s" 1 } } */ > >> > +/* { dg-final { scan-assembler-times "froundnx.d" 1 } } */ > >> > -- > >> > 2.17.1 > >> >