Re: Re: [RE] [v2] RISC-V: Add Zfbfmin extension
Great news, thanks for the quick reply. BR, Jin -- From:wangf...@eswincomputing.com Send Time:2024 Jun. 19 (Wed.) 08:18 To:Jin Ma Cc:"kito.cheng"; "juzhe.zhong"; "jinma.contrib"; zengxiao; "gcc-patches"; gaofei Subject:Re: Re: [RE] [v2] RISC-V: Add Zfbfmin extension Hi Jin, Will submit patch after internal review,maybe today. wangf...@eswincomputing.com From: Jin Ma Date: 2024-06-18 18:25 To: wangfeng CC: Kito Cheng; juzhe.zhong; jinma.contrib; zengxiao; gcc-patches; Fei Gao Subject: Re: [RE] [v2] RISC-V: Add Zfbfmin extension Hi, Feng Any new developments here on zvfbfmin and zvfbfwma? BR, Jin -- From:Fei Gao Send Time:2024 Jun. 7 (Fri.) 17:34 To:jinma; "gcc-patches"; zengxiao; wangfeng Cc:jeffreyalaw; Kito Cheng; "juzhe.zhong"; "jinma.contrib"; jinma Subject:Re: [RE] [v2] RISC-V: Add Zfbfmin extension Hi Jin We have completed zvfbfmin and zvfbfwma in GCC. Wang Feng will post after dragon boat festival. BR, Fei From: Jin Ma Date: 2024-06-07 15:35 To: gcc-patches; zengxiao CC: jeffreyalaw; kito.cheng; juzhe.zhong; jinma.contrib; Jin Ma Subject: [RE] [v2] RISC-V: Add Zfbfmin extension Hi, Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the relevant patches in advance for testing? By the way, The LLVM seems to be fully implemented now :-) Ref: https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293 https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc Thanks, Jin
Re: [RE] [v2] RISC-V: Add Zfbfmin extension
Hi, Feng Any new developments here on zvfbfmin and zvfbfwma? BR, Jin -- From:Fei Gao Send Time:2024 Jun. 7 (Fri.) 17:34 To:jinma; "gcc-patches"; zengxiao; wangfeng Cc:jeffreyalaw; Kito Cheng; "juzhe.zhong"; "jinma.contrib"; jinma Subject:Re: [RE] [v2] RISC-V: Add Zfbfmin extension Hi Jin We have completed zvfbfmin and zvfbfwma in GCC. Wang Feng will post after dragon boat festival. BR, Fei From: Jin Ma Date: 2024-06-07 15:35 To: gcc-patches; zengxiao CC: jeffreyalaw; kito.cheng; juzhe.zhong; jinma.contrib; Jin Ma Subject: [RE] [v2] RISC-V: Add Zfbfmin extension Hi, Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the relevant patches in advance for testing? By the way, The LLVM seems to be fully implemented now :-) Ref: https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293 https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc Thanks, Jin
[RE] [v2] RISC-V: Add Zfbfmin extension
Hi, Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the relevant patches in advance for testing? By the way, The LLVM seems to be fully implemented now :-) Ref: https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293 https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc Thanks, Jin
Re:[PATCH] haifa-sched: Avoid the fusion priority of the fused insn to affect the subsequent insn sequence.
I am very sorry that I did not check the commit information carefully. The statement is somewhat inaccurate. > When the insn 1 and 2, 3 and 4 can be fusioned, then there is the > following sequence: > > ;; insn | > ;; 1 | sp=sp-0x18 > ;; + 2 | [sp+0x10]=ra > ;; 3 | [sp+0x8]=s0 > ;; 4 | [sp+0x0]=s1 > The fusion priority of the insn 2, 3, and 4 are the same. According to > the current algorithm, since abs(0x10-0x8) is followed by the insn 3. It is obviously unreasonable to do so. > > Therefore, when we issue the insn 3 and 4, we should consider the fusion > priority of the insn 1 instead of the insn 2. And the final instruction > sequence is as follows: > ;; insn | > ;; 1 | sp=sp-0x18 > ;; + 2 | [sp+0x10]=ra > ;; 4 | [sp+0x8]=s1 > ;; + 3 | [sp+0x0]=s0 > > gcc/ChangeLog: > * haifa-sched.cc (rank_for_schedule): Likewise. When the insn 1 and 2, 4 and 3 can be fusioned, then there is the following sequence: ;; insn | ;; 1 | sp=sp-0x18 ;; + 2 | [sp+0x10]=ra ;; 3 | [sp+0x8]=s0 ;; 4 | [sp+0x0]=s1 The fusion priority of the insn 2, 3, and 4 are the same. According to the current algorithm, since abs(0x10-0x8)
Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16
> On 12/20/23 4:17 AM, Jin Ma wrote: > > We don't have SI -> BF library functions, use SI -> SF -> BF > > instead. Although this can also be implemented in a target > > machine description, it is more appropriate to move > > into target independent code. > > > > gcc/ChangeLog: > > > > * optabs.cc (expand_float): Split SI -> BF into SI -> SF -> BF. > > --- > > gcc/optabs.cc | 13 + > > 1 file changed, 13 insertions(+) > > > > diff --git a/gcc/optabs.cc b/gcc/optabs.cc > > index 6a34276c239..c58a0321bbd 100644 > > --- a/gcc/optabs.cc > > +++ b/gcc/optabs.cc > > @@ -5727,6 +5727,19 @@ expand_float (rtx to, rtx from, int unsignedp) > > if (is_narrower_int_mode (GET_MODE (from), SImode)) > > from = convert_to_mode (SImode, from, unsignedp); > > > > +#ifdef HAVE_SFmode > > + if (REAL_MODE_FORMAT (GET_MODE (to)) == _bfloat_half_format > > + && REAL_MODE_FORMAT (SFmode) == _single_format > > + && GET_MODE (from) == SImode) > > + /* We don't have SI -> BF library functions, use SI -> SF -> BF > > + instead. */ > > + { > > + target = gen_reg_rtx (SFmode); > > + expand_float (target, from, unsignedp); > > + goto done; > > + } > > +#endif > Why do you have the #ifdef HAVE_SFmode? That seems odd, I think the > only place we do anything like that is in targhooks. Why did you add > those cpp conditionals? Hi, jeff I'm sorry I haven't noticed this email for so long. For this patch, my original idea was to use SF to complete the SI to BF conversion. This is because RSICV did not support that when the patch was submitted, and the relevant soft floating point library '__floatsibf' was not defined, so I used a new pattern to do this. The soft floating-point library '__floatsibf' has been added now, which seems to be the most correct approach. So this patch is no longer meaningful in this respect. Ref: https://patchwork.ozlabs.org/project/gcc/patch/2023091908.2089-1-ji...@linux.alibaba.com/ BR, Jin > > Bring the comment "We don't have SI -> BF ..." inside the open curly and > indent it two more spaces. That should be more consistent with GCC style. > > So generally OK. I suspect this can move forward once we figure out why > you added those cpp conditionals and fix the formatting nit. > > jeff
[PATCH] haifa-sched: Avoid the fusion priority of the fused insn to affect the subsequent insn sequence.
When the insn 1 and 2, 3 and 4 can be fusioned, then there is the following sequence: ;;insn | ;; 1 | sp=sp-0x18 ;; + 2 | [sp+0x10]=ra ;; 3 | [sp+0x8]=s0 ;; 4 | [sp+0x0]=s1 The fusion priority of the insn 2, 3, and 4 are the same. According to the current algorithm, since abs(0x10-0x8)
Re:[PATCH v2 1/1] [RISC-V] Add support for _Bfloat16
> gcc/testsuite/ChangeLog: > > * gcc.target/riscv/bf16_arithmetic.c: New test. > * gcc.target/riscv/bf16_call.c: New test. > * gcc.target/riscv/bf16_comparison.c: New test. > * gcc.target/riscv/bf16_float_libcall_convert.c: New test. > * gcc.target/riscv/bf16_integer_libcall_convert.c: New test. Hi, I have test this patch and it is very good. I think we need to add some runable tests to ensure that the results are right for various types of conversions, operations, and libfuncs. BR, Jin
[PATCH v2] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.
When using '%ld' to print 'long long int' variable, 'fprintf' will produce messy output on a 32-bit system, in an incorrect instruction being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the following error occurred during compilation: Assembler messages: Error: improper immediate value (18446744073709551615) gcc/ChangeLog: * config/riscv/thead.cc (th_print_operand_address): Change %ld to %lld. --- gcc/config/riscv/thead.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index 2955bc5f8a9..e4b8c37bc28 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x) return true; case ADDRESS_REG_WB: - fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)], + fprintf (file, "(%s),"HOST_WIDE_INT_PRINT_DEC",%u", reg_names[REGNO (addr.reg)], INTVAL (addr.offset) >> addr.shift, addr.shift); return true; -- 2.17.1
Re:[PATCH] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.
>On Mon, Jan 29, 2024 at 1:21=E2=80=AFAM Jin Ma wr= >ote: >> >> When using '%ld' to print 'long long int' variable, 'fprintf' will >> produce messy output on a 32-bit system, in an incorrect instruction >> being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the >> following error occurred during compilation: >> >> Assembler messages: >> Error: improper immediate value (18446744073709551615) >> >> gcc/ChangeLog: >> >> * config/riscv/thead.cc (th_print_operand_address): Change %ld >> to %lld. >> --- >> gcc/config/riscv/thead.cc | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc >> index 2955bc5f8a9..9ee6444b627 100644 >> --- a/gcc/config/riscv/thead.cc >> +++ b/gcc/config/riscv/thead.cc >> @@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode = >mode, rtx x) >>return true; >> >> case ADDRESS_REG_WB: >> - fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)], >> + fprintf (file, "(%s),%lld,%u", reg_names[REGNO (addr.reg)], >>INTVAL (addr.offset) >> addr.shift, addr.shift); >This is wrong, you should instead use HOST_WIDE_INT_PRINT_DEC or >HOST_WIDE_INT_PRINT_UNSIGNED. >Thanks, >Andrew Pinski Yes, thank you very much for your guidance. It will be better to use HOST_WIDE_INT_PRINT_DEC. I will make changes later :) BR Jin >> return true;
[PATCH] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.
When using '%ld' to print 'long long int' variable, 'fprintf' will produce messy output on a 32-bit system, in an incorrect instruction being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the following error occurred during compilation: Assembler messages: Error: improper immediate value (18446744073709551615) gcc/ChangeLog: * config/riscv/thead.cc (th_print_operand_address): Change %ld to %lld. --- gcc/config/riscv/thead.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc index 2955bc5f8a9..9ee6444b627 100644 --- a/gcc/config/riscv/thead.cc +++ b/gcc/config/riscv/thead.cc @@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x) return true; case ADDRESS_REG_WB: - fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)], + fprintf (file, "(%s),%lld,%u", reg_names[REGNO (addr.reg)], INTVAL (addr.offset) >> addr.shift, addr.shift); return true; -- 2.17.1
[PATCH] RISC-V: THEAD: Fix ICE caused by split optimizations for XTheadFMemIdx.
Due to the premature split optimizations for XTheadFMemIdx, GPR is allocated when reload allocates registers, resulting in the following insn. (insn 66 21 64 5 (set (reg:DF 14 a4 [orig:136 ] [136]) (mem:DF (plus:SI (reg/f:SI 15 a5 [141]) (ashift:SI (reg/v:SI 10 a0 [orig:137 i ] [137]) (const_int 3 [0x3]))) [0 S8 A64])) 218 {*movdf_hardfloat_rv32} (nil)) Since we currently do not support adjustments to th_m_mir/th_m_miu, which will trigger ICE. So it is recommended to place the split optimizations after reload to ensure FPR when registers are allocated. gcc/ChangeLog: * config/riscv/thead.md: Add limits for splits. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadfmemidx-medany.c: New test. --- gcc/config/riscv/thead.md | 22 --- .../gcc.target/riscv/xtheadfmemidx-medany.c | 38 +++ 2 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index e370774d518..5c7d4beb1b6 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -933,14 +933,17 @@ (define_insn_and_split "*th_fmemidx_I_a" && pow2p_hwi (INTVAL (operands[2])) && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:X (match_dup 3) (ashift:X (match_dup 1) (match_dup 2)] { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2]))); } -) + [(set_attr "move_type" "fpload") + (set_attr "mode" "") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_I_c" [(set (mem:TH_M_ANYF (plus:X @@ -977,7 +980,7 @@ (define_insn_and_split "*th_fmemidx_US_a" && CONST_INT_P (operands[3]) && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0x" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:DI (match_dup 4) @@ -985,7 +988,10 @@ (define_insn_and_split "*th_fmemidx_US_a" { operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2]))); } -) + [(set_attr "move_type" "fpload") + (set_attr "mode" "") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_US_c" [(set (mem:TH_M_ANYF (plus:DI @@ -1020,12 +1026,16 @@ (define_insn_and_split "*th_fmemidx_UZ_a" "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX && (!HARD_REGISTER_NUM_P (REGNO (operands[0])) || HARDFP_REG_P (REGNO (operands[0])))" "#" - "&& 1" + "&& reload_completed" [(set (match_dup 0) (mem:TH_M_NOEXTF (plus:DI (match_dup 2) (zero_extend:DI (match_dup 1)] -) + "" + [(set_attr "move_type" "fpload") + (set_attr "mode" "") + (set_attr "type" "fmove") + (set (attr "length") (const_int 16))]) (define_insn_and_split "*th_fmemidx_UZ_c" [(set (mem:TH_M_ANYF (plus:DI diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c new file mode 100644 index 000..0c8060d0632 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" "-Os" "-Oz"} } */ +/* { dg-options "-march=rv32gc_xtheadfmemidx_xtheadfmv_xtheadmemidx -mabi=ilp32d -mcmodel=medany -O2" } */ + +typedef union { + double v; + unsigned w; +} my_t; + +double z; + +double foo (int i, int j) +{ + + if (j) +{ + switch (i) + { + case 0: + return 1; + case 1: + return 0; + case 2: + return 3.0; + } +} + + if (i == 1) +{ + my_t u; + u.v = z; + u.w = 1; + z = u.v; +} + return z; +} + +/* { dg-final { scan-assembler-times {\mth\.flrd\M} 1 } } */ -- 2.17.1
Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16
I apologize for not attaching a reference link. Ref: https://patchwork.ozlabs.org/project/gcc/patch/2023091908.2089-1-ji...@linux.alibaba.com/ https://gcc.gnu.org/pipermail/gcc-patches/2023-December/641119.html BR Jin
Re:[PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
ping Ref: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636932.html
Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16
ping
[PATCH] Support libcall __float{, un}sibf by SF when it is not supported for _bf16
We don't have SI -> BF library functions, use SI -> SF -> BF instead. Although this can also be implemented in a target machine description, it is more appropriate to move into target independent code. gcc/ChangeLog: * optabs.cc (expand_float): Split SI -> BF into SI -> SF -> BF. --- gcc/optabs.cc | 13 + 1 file changed, 13 insertions(+) diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 6a34276c239..c58a0321bbd 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -5727,6 +5727,19 @@ expand_float (rtx to, rtx from, int unsignedp) if (is_narrower_int_mode (GET_MODE (from), SImode)) from = convert_to_mode (SImode, from, unsignedp); +#ifdef HAVE_SFmode + if (REAL_MODE_FORMAT (GET_MODE (to)) == _bfloat_half_format + && REAL_MODE_FORMAT (SFmode) == _single_format + && GET_MODE (from) == SImode) + /* We don't have SI -> BF library functions, use SI -> SF -> BF + instead. */ + { + target = gen_reg_rtx (SFmode); + expand_float (target, from, unsignedp); + goto done; + } +#endif + libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from)); gcc_assert (libfunc); -- 2.17.1
[PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
The XTheadInt ISA extension provides acceleration interruption instructions as defined in T-Head-specific: * th.ipush * th.ipop Ref: https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf gcc/ChangeLog: * config/riscv/riscv-protos.h (th_int_get_mask): New prototype. (th_int_get_save_adjustment): Likewise. (th_int_adjust_cfi_prologue): Likewise. * config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro. (riscv_expand_prologue): Add the processing of XTheadInt. (riscv_expand_epilogue): Likewise. * config/riscv/riscv.md: New unspec. * config/riscv/thead.cc (BITSET_P): New macro. * config/riscv/thead.md (th_int_push): New pattern. (th_int_pop): New pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadint-push-pop.c: New test. --- gcc/config/riscv/riscv-protos.h | 3 + gcc/config/riscv/riscv.cc | 61 ++- gcc/config/riscv/riscv.h | 3 + gcc/config/riscv/riscv.md | 4 + gcc/config/riscv/thead.cc | 77 +++ gcc/config/riscv/thead.md | 67 .../gcc.target/riscv/xtheadint-push-pop.c | 36 + 7 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 196b53f10f3..91d1e99f672 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -633,6 +633,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool, int, HOST_WIDE_INT, int, HOST_WIDE_INT); extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode); +extern unsigned int th_int_get_mask (unsigned int); +extern unsigned int th_int_get_save_adjustment (void); +extern rtx th_int_adjust_cfi_prologue (unsigned int); #ifdef RTX_CODE extern const char* th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index c2bd1c2ed29..6ff6f4789a4 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -94,15 +94,22 @@ along with GCC; see the file COPYING3. If not see #define UNSPEC_ADDRESS_TYPE(X) \ ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST)) -/* True if bit BIT is set in VALUE. */ -#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0) - /* Extract the backup dynamic frm rtl. */ #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm) /* True the mode switching has static frm, or false. */ #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p) +/* True if we can use the instructions in the XTheadInt extension + to handle interrupts, or false. */ +#define TH_INT_INTERRUPT(c)\ + (TARGET_XTHEADINT\ + /* The XTheadInt extension only supports rv32. */ \ + && !TARGET_64BIT\ + && (c)->machine->interrupt_handler_p \ + /* The XTheadInt instructions can only be executed in M-mode. */ \ + && (c)->machine->interrupt_mode == MACHINE_MODE) + /* Information about a function's frame layout. */ struct GTY(()) riscv_frame_info { /* The size of the frame in bytes. */ @@ -6737,6 +6744,7 @@ riscv_expand_prologue (void) unsigned fmask = frame->fmask; int spimm, multi_push_additional, stack_adj; rtx insn, dwarf = NULL_RTX; + unsigned th_int_mask = 0; if (flag_stack_usage_info) current_function_static_stack_size = constant_lower_bound (remaining_size); @@ -6805,6 +6813,28 @@ riscv_expand_prologue (void) REG_NOTES (insn) = dwarf; } + th_int_mask = th_int_get_mask (frame->mask); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) +{ + frame->mask &= ~th_int_mask; + + /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for +interrupts, such as fcsr. */ + if ((TARGET_HARD_FLOAT && frame->fmask) + || (TARGET_ZFINX && frame->mask)) + frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM); + + unsigned save_adjustment = th_int_get_save_adjustment (); + frame->gp_sp_offset -= save_adjustment; + remaining_size -= save_adjustment; + + insn = emit_insn (gen_th_int_push ()); + + rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask); + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = dwarf; +} + /* Save the GP, FP registers. */ if ((frame->mask | frame->fmask) != 0) { @@ -7033,6 +7063,7 @@ riscv_expand_epilogue (int style) = use_multi_pop ? frame->multi_push_adj_base +
Re: [PATCH v2] In the pipeline, USE or CLOBBER should delay execution if it starts a new live range.
> > > > Unfortunately this patch has triggered a bootstrap comparison failure on > > loongarch64-linux-gnu: https://gcc.gnu.org/PR112497. > It's also causing simple build failures on other targets. For example > c6x-elf aborts when compiling gcc.c-torture/execute/pr82210 (and others) > with -O2 with that patch applied. > > I've reverted it for now. I'm not going to have time to investigate > this week. I'm sorry to have caused this and had a bad effect. This patch has been a long time since I verified it, so I don't know what happened, I will check it out :) BR Jin > Jeff > >
[PATCH v2] RISC-V: Fixbug for that XTheadMemPair causes interrupt to fail.
The t0 register is used as a temporary register for interrupts, so it needs special treatment. It is necessary to avoid using "th.ldd" in the interrupt program to stop the subsequent operation of the t0 register, so they need to exchange positions in the function "riscv_for_each_saved_reg". gcc/ChangeLog: * config/riscv/riscv.cc (riscv_for_each_saved_reg): Place the interrupt operation before the XTheadMemPair. --- gcc/config/riscv/riscv.cc | 56 +-- .../riscv/xtheadmempair-interrupt-fcsr.c | 18 ++ 2 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e25692b86fc..fa2d4d4b779 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6346,6 +6346,34 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, && riscv_is_eh_return_data_register (regno)) continue; + /* In an interrupt function, save and restore some necessary CSRs in the stack +to avoid changes in CSRs. */ + if (regno == RISCV_PROLOGUE_TEMP_REGNUM + && cfun->machine->interrupt_handler_p + && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask) + || (TARGET_ZFINX + && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) + { + unsigned int fcsr_size = GET_MODE_SIZE (SImode); + if (!epilogue) + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset, riscv_save_reg); + } + else + { + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset - fcsr_size, riscv_restore_reg); + emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + } + continue; + } + if (TARGET_XTHEADMEMPAIR) { /* Get the next reg/offset pair. */ @@ -6376,34 +6404,6 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } - /* In an interrupt function, save and restore some necessary CSRs in the stack -to avoid changes in CSRs. */ - if (regno == RISCV_PROLOGUE_TEMP_REGNUM - && cfun->machine->interrupt_handler_p - && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask) - || (TARGET_ZFINX - && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) - { - unsigned int fcsr_size = GET_MODE_SIZE (SImode); - if (!epilogue) - { - riscv_save_restore_reg (word_mode, regno, offset, fn); - offset -= fcsr_size; - emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode))); - riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, - offset, riscv_save_reg); - } - else - { - riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, - offset - fcsr_size, riscv_restore_reg); - emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode))); - riscv_save_restore_reg (word_mode, regno, offset, fn); - offset -= fcsr_size; - } - continue; - } - riscv_save_restore_reg (word_mode, regno, offset, fn); } diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c new file mode 100644 index 000..d06f05f5c7c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c @@ -0,0 +1,18 @@ +/* Verify that fcsr instructions emitted. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906 -funwind-tables" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906 -funwind-tables" { target { rv32 } } } */ + + +extern int foo (void); + +void __attribute__ ((interrupt)) +sub (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-times "frcsr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fscsr\t" 1 } } */ base-commit: e7f4040d9d6ec40c48ada940168885d7dde03af9 -- 2.17.1
[PATCH] RISC-V: Fix bug that XTheadMemPair extension caused fcsr not to be saved and restored before and after interrupt.
The t0 register is used as a temporary register for interrupts, so it needs special treatment. It is necessary to avoid using "th.ldd" in the interrupt program to stop the subsequent operation of the t0 register, so they need to exchange positions in the function "riscv_for_each_saved_reg". gcc/ChangeLog: * config/riscv/riscv.cc (riscv_for_each_saved_reg): Place the interrupt operation before the XTheadMemPair. --- gcc/config/riscv/riscv.cc | 56 +-- .../riscv/xtheadmempair-interrupt-fcsr.c | 18 ++ 2 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e25692b86fc..fa2d4d4b779 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6346,6 +6346,34 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, && riscv_is_eh_return_data_register (regno)) continue; + /* In an interrupt function, save and restore some necessary CSRs in the stack +to avoid changes in CSRs. */ + if (regno == RISCV_PROLOGUE_TEMP_REGNUM + && cfun->machine->interrupt_handler_p + && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask) + || (TARGET_ZFINX + && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) + { + unsigned int fcsr_size = GET_MODE_SIZE (SImode); + if (!epilogue) + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset, riscv_save_reg); + } + else + { + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset - fcsr_size, riscv_restore_reg); + emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + } + continue; + } + if (TARGET_XTHEADMEMPAIR) { /* Get the next reg/offset pair. */ @@ -6376,34 +6404,6 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } - /* In an interrupt function, save and restore some necessary CSRs in the stack -to avoid changes in CSRs. */ - if (regno == RISCV_PROLOGUE_TEMP_REGNUM - && cfun->machine->interrupt_handler_p - && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask) - || (TARGET_ZFINX - && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) - { - unsigned int fcsr_size = GET_MODE_SIZE (SImode); - if (!epilogue) - { - riscv_save_restore_reg (word_mode, regno, offset, fn); - offset -= fcsr_size; - emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode))); - riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, - offset, riscv_save_reg); - } - else - { - riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, - offset - fcsr_size, riscv_restore_reg); - emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode))); - riscv_save_restore_reg (word_mode, regno, offset, fn); - offset -= fcsr_size; - } - continue; - } - riscv_save_restore_reg (word_mode, regno, offset, fn); } diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c new file mode 100644 index 000..d06f05f5c7c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c @@ -0,0 +1,18 @@ +/* Verify that fcsr instructions emitted. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */ +/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906 -funwind-tables" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906 -funwind-tables" { target { rv32 } } } */ + + +extern int foo (void); + +void __attribute__ ((interrupt)) +sub (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-times "frcsr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fscsr\t" 1 } } */ base-commit: e7f4040d9d6ec40c48ada940168885d7dde03af9 -- 2.17.1
[PATCH] RISC-V: Fix the illegal operands for the XTheadMemidx extension.
The pattern "*extend2_bitmanip" and "*zero_extendhi2_bitmanip" in bitmanip.md are similar to the pattern "*th_memidx_bb_extendqi2" and "*th_memidx_bb_zero_extendhi2" in thead.md, which will cause the wrong instruction to be generated and report the following error in binutils: Assembler messages: Error: illegal operands `lb a5,(a0),1,0' In fact, the correct instruction is "th.lbia a5,(a0),1,0". gcc/ChangeLog: * config/riscv/bitmanip.md: Avoid the conflict between zbb and xtheadmemidx in patterns. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadfmemidx-uindex-zbb.c: New test. --- gcc/config/riscv/bitmanip.md | 4 +-- .../riscv/xtheadfmemidx-uindex-zbb.c | 30 +++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index a9c8275fca7..878395c3ffa 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -290,7 +290,7 @@ (define_insn "*di2" (define_insn "*zero_extendhi2_bitmanip" [(set (match_operand:GPR 0 "register_operand" "=r,r") (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))] - "TARGET_ZBB" + "TARGET_ZBB && !TARGET_XTHEADMEMIDX" "@ zext.h\t%0,%1 lhu\t%0,%1" @@ -301,7 +301,7 @@ (define_insn "*extend2_bitmanip" [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] - "TARGET_ZBB" + "TARGET_ZBB && !TARGET_XTHEADMEMIDX" "@ sext.\t%0,%1 l\t%0,%1" diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c new file mode 100644 index 000..a05bc220cba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc_zbb_xtheadmemidx -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32imafc_zbb_xtheadmemidx -mabi=ilp32f" { target { rv32 } } } */ + +const unsigned char * +read_uleb128(const unsigned char *p, unsigned long *val) +{ + unsigned int shift = 0; + unsigned char byte; + unsigned long result; + + result = 0; + do + { +byte = *p++; +result |= ((unsigned long)byte & 0x7f) << shift; +shift += 7; + } while (byte & 0x80); + + *val = result; + return p; +} + +void test(const unsigned char *p, unsigned long utmp) +{ + p = read_uleb128(p, ); +} + +/* { dg-final { scan-assembler-not {\mlb\ta[0-9],\(a[0-9]\),1,0\M} } } */ base-commit: 04d8a47608dcae7f61805e3566e3a1571b574405 -- 2.17.1
[PATCH] riscv: thead: Add support for the XTheadInt ISA extension
The XTheadInt ISA extension provides acceleration interruption instructions as defined in T-Head-specific: * th.ipush * th.ipop gcc/ChangeLog: * config/riscv/riscv-protos.h (th_int_get_mask): New prototype. (th_int_get_save_adjustment): Likewise. (th_int_adjust_cfi_prologue): Likewise. * config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro. (riscv_expand_prologue): Add the processing of XTheadInt. (riscv_expand_epilogue): Likewise. * config/riscv/riscv.md: New unspec. * config/riscv/thead.cc (BITSET_P): New macro. * config/riscv/thead.md (th_int_push): New pattern. (th_int_pop): New pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadint-push-pop.c: New test. --- gcc/config/riscv/riscv-protos.h | 3 + gcc/config/riscv/riscv.cc | 58 +- gcc/config/riscv/riscv.md | 4 + gcc/config/riscv/thead.cc | 78 +++ gcc/config/riscv/thead.md | 67 .../gcc.target/riscv/xtheadint-push-pop.c | 36 + 6 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 85d4f6ed9ea..05d1fc2b3a0 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -627,6 +627,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool, int, HOST_WIDE_INT, int, HOST_WIDE_INT); extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode); +extern unsigned int th_int_get_mask(unsigned int); +extern unsigned int th_int_get_save_adjustment(); +extern rtx th_int_adjust_cfi_prologue (unsigned int); #ifdef RTX_CODE extern const char* th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 08ff05dcc3f..c623101b05e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -101,6 +101,16 @@ along with GCC; see the file COPYING3. If not see /* True the mode switching has static frm, or false. */ #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p) +/* True if we can use the instructions in the XTheadInt extension + to handle interrupts, or false. */ +#define TH_INT_INTERRUPT(c)\ + (TARGET_XTHEADINT\ + /* The XTheadInt extension only supports rv32. */ \ + && !TARGET_64BIT\ + && (c)->machine->interrupt_handler_p\ + /* This instruction can be executed in M-mode only.*/ \ + && (c)->machine->interrupt_mode == MACHINE_MODE) + /* Information about a function's frame layout. */ struct GTY(()) riscv_frame_info { /* The size of the frame in bytes. */ @@ -6703,6 +6713,7 @@ riscv_expand_prologue (void) unsigned fmask = frame->fmask; int spimm, multi_push_additional, stack_adj; rtx insn, dwarf = NULL_RTX; + unsigned th_int_mask = 0; if (flag_stack_usage_info) current_function_static_stack_size = constant_lower_bound (remaining_size); @@ -6771,6 +6782,28 @@ riscv_expand_prologue (void) REG_NOTES (insn) = dwarf; } + th_int_mask = th_int_get_mask(frame->mask); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) +{ + frame->mask &= ~th_int_mask; + + /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for +interrupts, such as fcsr. */ + if ((TARGET_HARD_FLOAT && frame->fmask) + || (TARGET_ZFINX && frame->mask)) + frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM); + + unsigned save_adjustment = th_int_get_save_adjustment (); + frame->gp_sp_offset -= save_adjustment; + remaining_size -= save_adjustment; + + insn = emit_insn (gen_th_int_push ()); + + rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask); + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = dwarf; +} + /* Save the GP, FP registers. */ if ((frame->mask | frame->fmask) != 0) { @@ -6999,6 +7032,7 @@ riscv_expand_epilogue (int style) = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi : 0; rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + unsigned th_int_mask = 0; rtx insn; /* We need to add memory barrier to prevent read from deallocated stack. */ @@ -7161,12 +7195,32 @@ riscv_expand_epilogue (int style) else if (use_restore_libcall) frame->mask = 0; /* Temporarily fib that we need not restore GPRs. */ + th_int_mask = th_int_get_mask(frame->mask); + if (th_int_mask && TH_INT_INTERRUPT (cfun)) +{ + frame->mask &= ~th_int_mask; + + /*
[RE] [7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt
Hi, I see that XTheadInt is not implemented in the compiler. Is there any plan here? If there is no patch for it, can I try to implement it with you? Thanks Jin
Re: [RFC 1/2] RISC-V: Add support for _Bfloat16.
> >>> +;; The conversion of DF to BF needs to be done with SF if there is a > >>> +;; chance to generate at least one instruction, otherwise just using > >>> +;; libfunc __truncdfbf2. > >>> +(define_expand "truncdfbf2" > >>> + [(set (match_operand:BF 0 "register_operand" "=f") > >>> + (float_truncate:BF > >>> + (match_operand:DF 1 "register_operand" " f")))] > >>> + "TARGET_DOUBLE_FLOAT || TARGET_ZDINX" > >>> + { > >>> +convert_move (operands[0], > >>> + convert_modes (SFmode, DFmode, operands[1], 0), 0); > >>> +DONE; > >>> + }) > >> So for conversions to/from BFmode, doesn't generic code take care of > >> this for us? Search for convert_mode_scalar in expr.cc. That code will > >> utilize SFmode as an intermediate step just like your expander. Is > >> there some reason that generic code is insufficient? > >> > >> Similarly for the the other conversions. > > > > As far as I can see, the function 'convert_mode_scalar' doesn't seem to be > > perfect for > > dealing with the conversions to/from BFmode. It can only handle BF to HF, > > SF, DF and > > SF to BF well, but the rest of the conversion without any processing, > > directly using > > the libcall. > > > > Maybe I should choose to enhance its functionality? This seems to be a > > good choice, I'm not sure.My recollection was that BF could be converted > > to/from SF trivially and > if we wanted BF->DF we'd first convert to SF, then to DF. > > Direct BF<->DF conversions aren't actually important from a performance > standpoint. So it's OK if they have an extra step IMHO. Thank you very much for your review and detailed reply. Maybe there are some problems with my expression and I am a little confused about your guidance. My understanding is that you also think that it is reasonable to convert through SF, right? In fact, this is what I did. In this patch, my thoughts are as follows: The general principle is to use the real instructions instead of libcall as much as possible for conversions, while minimizing the definition of libcall(only reusing which has been defined by other architectures such as aarch64). If SF can be used as a transit, it is preferred to convert to SF, otherwise libcall is directly used. 1. For the conversions between floating points For BF->DF, as you said, the function 'convert_mode_scalar' in the general code has been well implemented, which will be expressed as BF->SF->DF. And the generated instruction list may be as follows: 'call __extendbfsf2' + 'call __extendsfdf2' (when only soft floating point support); 'call __extendbfsf2' + 'fcvt.d.s' (when (TARGET_DOUBLE_FLOAT || TARGET_ZDINX) is true); 'fcvt.s.bf16'+ 'fcvt.d.s' (when ((TARGET_DOUBLE_FLOAT || TARGET_ZDINX) && TARGET_ZFBFMIN) is true) For DF->BF, if any of fcvt.s.d and fcvt.bf16.s cannot be generated, the 'call __truncdfbf2' is directly generated by the function 'convert_mode_scalar'. Otherwise the new pattern(define_expand "truncdfbf2") is used. This makes it possible to implement DF->BF by 'fcvt.s.d' + 'fcvt.bf16.s', which cannot be generated by the function 'convert_mode_scala'. 2. For the conversions between integer and BF, it seems that gcc only uses libcall to implement it, but this is obviously wrong. For example, the conversion BF->SI directly calls the unimplemented libcall __fixunsbfsi. So I added some new pattern to handle these transformations with SF. Thanks, Jin > > jeff
Re: [RFC 1/2] RISC-V: Add support for _Bfloat16.
> On 9/19/23 02:44, Jin Ma wrote: > > gcc/ChangeLog: > > > > * config/riscv/iterators.md (HFBF): New. > > * config/riscv/riscv-builtins.cc (riscv_init_builtin_types): > > Initialize data type_Bfloat16. > > * config/riscv/riscv-modes.def (FLOAT_MODE): New. > > (ADJUST_FLOAT_FORMAT): New. > > * config/riscv/riscv.cc (riscv_mangle_type): Support for BFmode. > > (riscv_scalar_mode_supported_p): Ditto. > > (riscv_libgcc_floating_mode_supported_p): Ditto. > > (riscv_block_arith_comp_libfuncs_for_mode): New. > > (riscv_init_libfuncs): Opening and closing some libfuncs for BFmode. > > * config/riscv/riscv.md (mode" ): Add BF. > > (truncdfbf2): New. > > (movhf): Support for BFmode. > > (mov): Ditto. > > (*mov_softfloat): Ditto. > > (fix_truncbf2): New. > > (fixuns_truncbf2): New. > > (floatbf2): New. > > (floatunsbf2): New. > > > > libgcc/ChangeLog: > > > > * config/riscv/sfp-machine.h (_FP_NANFRAC_B): New. > > (_FP_NANSIGN_B): New. > > * config/riscv/t-softfp32: Add support for BF libfuncs. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.target/riscv/bf16_arithmetic.c: New test. > > * gcc.target/riscv/bf16_call.c: New test. > > * gcc.target/riscv/bf16_comparisons.c: New test. > > * gcc.target/riscv/bf16_convert-1.c: New test. > > * gcc.target/riscv/bf16_convert-2.c: New test. > > * gcc.target/riscv/bf16_convert_run.c: New test. > So this can't go in the tree until the extension has moved into a frozen > state. Hopefully that'll happen before we close stage1 development in Nov. Ok, this is very reasonable. > > > > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > > index e00b8ee3579..5048628c784 100644 > > --- a/gcc/config/riscv/riscv.md > > +++ b/gcc/config/riscv/riscv.md > > @@ -1631,6 +1631,20 @@ (define_insn "truncdfhf2" > > [(set_attr "type" "fcvt") > > (set_attr "mode" "HF")]) > > > > +;; The conversion of DF to BF needs to be done with SF if there is a > > +;; chance to generate at least one instruction, otherwise just using > > +;; libfunc __truncdfbf2. > > +(define_expand "truncdfbf2" > > + [(set (match_operand:BF 0 "register_operand" "=f") > > + (float_truncate:BF > > + (match_operand:DF 1 "register_operand" " f")))] > > + "TARGET_DOUBLE_FLOAT || TARGET_ZDINX" > > + { > > +convert_move (operands[0], > > + convert_modes (SFmode, DFmode, operands[1], 0), 0); > > +DONE; > > + }) > So for conversions to/from BFmode, doesn't generic code take care of > this for us? Search for convert_mode_scalar in expr.cc. That code will > utilize SFmode as an intermediate step just like your expander. Is > there some reason that generic code is insufficient? > > Similarly for the the other conversions. As far as I can see, the function 'convert_mode_scalar' doesn't seem to be perfect for dealing with the conversions to/from BFmode. It can only handle BF to HF, SF, DF and SF to BF well, but the rest of the conversion without any processing, directly using the libcall. Maybe I should choose to enhance its functionality? This seems to be a good choice, I'm not sure. Jin > > Otherwise it looks pretty good. > > Jeff
[RFC 2/2] RISC-V: Add 'Zfbfmin' extension.
This patch adds the 'Zfbfmin' extension for riscv, which is based on spec of bfloat16: https://github.com/riscv/riscv-bfloat16/commit/5578e34e15a44e9ad13246072a29f51274b4d999 The 'Zfbfmin' extension of binutils-gdb (REVIEW ONLY): https://sourceware.org/pipermail/binutils/2023-August/128773.html The 'Zfbfmin' extension of qemu: https://github.com/qemu/qemu/commit/5d1270caac2ef7b8c887d4cb5a2444ba6d237516 Because the binutils does not yet support the 'Zfbfmin' extension, test case zfbfmin_convert_run.c is invalidated with '#if 0' and '#endif'. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add 'Zfbfmin' extension. * config/riscv/riscv-opts.h (MASK_ZFBFMIN): New. (TARGET_ZFBFMIN): New. * config/riscv/riscv.cc (riscv_output_move): Enable FMV.X.H, and FMV.H.X for 'Zfbfmin' extension. (riscv_excess_precision): Likewise. * config/riscv/riscv.md (truncsfbf2): New. (extendbfsf2): New. (*mov_hardfloat): Support for BFmode. (*mov_softfloat): Disable for BFmode when 'Zfbfmin' extension is enabled. gcc/testsuite/ChangeLog: * gcc.target/riscv/zfbfmin_arithmetic.c: New test. * gcc.target/riscv/zfbfmin_call.c: New test. * gcc.target/riscv/zfbfmin_comparisons.c: New test. * gcc.target/riscv/zfbfmin_convert.c: New test. * gcc.target/riscv/zfbfmin_convert_run.c: New test. * gcc.target/riscv/zfbfmin_fsh_and_flh.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 3 + gcc/config/riscv/riscv-opts.h | 2 + gcc/config/riscv/riscv.cc | 4 +- gcc/config/riscv/riscv.md | 40 ++-- .../gcc.target/riscv/zfbfmin_arithmetic.c | 31 gcc/testsuite/gcc.target/riscv/zfbfmin_call.c | 17 ++ .../gcc.target/riscv/zfbfmin_comparisons.c| 22 +++ .../gcc.target/riscv/zfbfmin_convert.c| 38 .../gcc.target/riscv/zfbfmin_convert_run.c| 173 ++ .../gcc.target/riscv/zfbfmin_fsh_and_flh.c| 12 ++ 10 files changed, 329 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_arithmetic.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_call.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_comparisons.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_convert.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_convert_run.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_fsh_and_flh.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 9a0a68fe5db..1fcbb862aa4 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -123,6 +123,7 @@ static const riscv_implied_info_t riscv_implied_info[] = {"zfh", "zfhmin"}, {"zfhmin", "f"}, + {"zfbfmin", "f"}, {"zfa", "f"}, @@ -284,6 +285,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zfhmin",ISA_SPEC_CLASS_NONE, 1, 0}, {"zvfhmin", ISA_SPEC_CLASS_NONE, 1, 0}, {"zvfh", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zfbfmin", ISA_SPEC_CLASS_NONE, 0, 8}, {"zfa", ISA_SPEC_CLASS_NONE, 0, 1}, @@ -1461,6 +1463,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zfh", _options::x_riscv_zf_subext, MASK_ZFH}, {"zvfhmin", _options::x_riscv_zf_subext, MASK_ZVFHMIN}, {"zvfh", _options::x_riscv_zf_subext, MASK_ZVFH}, + {"zfbfmin", _options::x_riscv_zf_subext, MASK_ZFBFMIN}, {"zfa", _options::x_riscv_zfa_subext, MASK_ZFA}, diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index a525f679683..900a46fcae0 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -256,11 +256,13 @@ enum riscv_entity #define MASK_ZFH (1 << 1) #define MASK_ZVFHMIN (1 << 2) #define MASK_ZVFH (1 << 3) +#define MASK_ZFBFMIN (1 << 4) #define TARGET_ZFHMIN ((riscv_zf_subext & MASK_ZFHMIN) != 0) #define TARGET_ZFH ((riscv_zf_subext & MASK_ZFH) != 0) #define TARGET_ZVFHMIN ((riscv_zf_subext & MASK_ZVFHMIN) != 0) #define TARGET_ZVFH((riscv_zf_subext & MASK_ZVFH) != 0) +#define TARGET_ZFBFMIN((riscv_zf_subext & MASK_ZFBFMIN) != 0) #define MASK_ZMMUL (1 << 0) #define TARGET_ZMMUL((riscv_zm_subext & MASK_ZMMUL) != 0) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 910523ee2b9..6362c3f83c8 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3372,7 +3372,7 @@ riscv_output_move (rtx dest, rtx src) switch (width) { case 2: - if (TARGET_ZFHMIN) + if (TARGET_ZFHMIN || TARGET_ZFBFMIN) return "fmv.x.h\t%0,%1"; /* Using fmv.x.s + sign-extend to emulate fmv.x.h. */ return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16"; @@ -3428,7 +3428,7 @@ riscv_output_move (rtx dest, rtx src)
[RFC 1/2] RISC-V: Add support for _Bfloat16.
gcc/ChangeLog: * config/riscv/iterators.md (HFBF): New. * config/riscv/riscv-builtins.cc (riscv_init_builtin_types): Initialize data type_Bfloat16. * config/riscv/riscv-modes.def (FLOAT_MODE): New. (ADJUST_FLOAT_FORMAT): New. * config/riscv/riscv.cc (riscv_mangle_type): Support for BFmode. (riscv_scalar_mode_supported_p): Ditto. (riscv_libgcc_floating_mode_supported_p): Ditto. (riscv_block_arith_comp_libfuncs_for_mode): New. (riscv_init_libfuncs): Opening and closing some libfuncs for BFmode. * config/riscv/riscv.md (mode" ): Add BF. (truncdfbf2): New. (movhf): Support for BFmode. (mov): Ditto. (*mov_softfloat): Ditto. (fix_truncbf2): New. (fixuns_truncbf2): New. (floatbf2): New. (floatunsbf2): New. libgcc/ChangeLog: * config/riscv/sfp-machine.h (_FP_NANFRAC_B): New. (_FP_NANSIGN_B): New. * config/riscv/t-softfp32: Add support for BF libfuncs. gcc/testsuite/ChangeLog: * gcc.target/riscv/bf16_arithmetic.c: New test. * gcc.target/riscv/bf16_call.c: New test. * gcc.target/riscv/bf16_comparisons.c: New test. * gcc.target/riscv/bf16_convert-1.c: New test. * gcc.target/riscv/bf16_convert-2.c: New test. * gcc.target/riscv/bf16_convert_run.c: New test. --- gcc/config/riscv/iterators.md | 2 + gcc/config/riscv/riscv-builtins.cc| 16 ++ gcc/config/riscv/riscv-modes.def | 4 + gcc/config/riscv/riscv.cc | 93 -- gcc/config/riscv/riscv.md | 94 -- .../gcc.target/riscv/bf16_arithmetic.c| 36 gcc/testsuite/gcc.target/riscv/bf16_call.c| 17 ++ .../gcc.target/riscv/bf16_comparisons.c | 25 +++ .../gcc.target/riscv/bf16_convert-1.c | 39 + .../gcc.target/riscv/bf16_convert-2.c | 38 .../gcc.target/riscv/bf16_convert_run.c | 163 ++ libgcc/config/riscv/sfp-machine.h | 3 + libgcc/config/riscv/t-softfp32| 7 +- 13 files changed, 503 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_arithmetic.c create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_call.c create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_comparisons.c create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert_run.c diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index ecf033f2fa7..73523b73fdd 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -84,6 +84,8 @@ (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")]) ;; instruction. (define_mode_attr size [(QI "b") (HI "h")]) +(define_mode_iterator HFBF [HF BF]) + ;; Mode attributes for loads. (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") (SF "flw") (DF "fld")]) diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc index 3fe3a89dcc2..b7bb89794f7 100644 --- a/gcc/config/riscv/riscv-builtins.cc +++ b/gcc/config/riscv/riscv-builtins.cc @@ -192,6 +192,7 @@ static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES]; riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]] tree riscv_float16_type_node = NULL_TREE; +tree riscv_bfloat16_type_node = NULL_TREE; /* Return the function type associated with function prototype TYPE. */ @@ -235,6 +236,21 @@ riscv_init_builtin_types (void) if (!maybe_get_identifier ("_Float16")) lang_hooks.types.register_builtin_type (riscv_float16_type_node, "_Float16"); + + /* Provide the _Bfloat16 type and bfloat16_type_node if needed. */ + if (!bfloat16_type_node) +{ + riscv_bfloat16_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (riscv_bfloat16_type_node) = 16; + SET_TYPE_MODE (riscv_bfloat16_type_node, BFmode); + layout_type (riscv_bfloat16_type_node); +} + else +riscv_bfloat16_type_node = bfloat16_type_node; + + if (!maybe_get_identifier ("_Bfloat16")) +lang_hooks.types.register_builtin_type (riscv_bfloat16_type_node, + "_Bfloat16"); } /* Implement TARGET_INIT_BUILTINS. */ diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def index e3c6ccb2809..723bfaee42d 100644 --- a/gcc/config/riscv/riscv-modes.def +++ b/gcc/config/riscv/riscv-modes.def @@ -22,6 +22,10 @@ along with GCC; see the file COPYING3. If not see FLOAT_MODE (HF, 2, ieee_half_format); FLOAT_MODE (TF, 16, ieee_quad_format); +FLOAT_MODE (BF, 2, 0); +/* Reuse definition from arm. */ +ADJUST_FLOAT_FORMAT (BF, _bfloat_half_format); + /* Vector modes. */ /* Encode the ratio of
Re: [PATCH v2] In the pipeline, USE or CLOBBER should delay execution if it starts a new live range.
ping Ref: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627341.html https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621296.html
[PATCH] RISC-V: Added zvfh support for zfa extensions.
This is a follow-up for the zfa extension, added according to the recommendations for zvfh and patch of Tsukasa OI . At the same time, zfa-fli-5.c of which is also based on the patch. Ref: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627284.html https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628492.html gcc/ChangeLog: * config/riscv/riscv.cc (riscv_float_const_rtx_index_for_fli): zvfh can generate zfa extended instruction fli.h, just like zfh. gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fli-7.c: Change fa0 to fa\[0-9\] to avoid assigning register numbers that are non-zero. * gcc.target/riscv/zfa-fli-8.c: Ditto. * gcc.target/riscv/zfa-fli-5.c: New test. --- gcc/config/riscv/riscv.cc | 2 +- gcc/testsuite/gcc.target/riscv/zfa-fli-5.c | 99 ++ gcc/testsuite/gcc.target/riscv/zfa-fli-7.c | 6 +- gcc/testsuite/gcc.target/riscv/zfa-fli-8.c | 2 +- 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fli-5.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 1d6e278ea90..e839367c0c1 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -865,7 +865,7 @@ riscv_float_const_rtx_index_for_fli (rtx x) if (!TARGET_ZFA || !CONST_DOUBLE_P(x) || mode == VOIDmode - || (mode == HFmode && !TARGET_ZFH) + || (mode == HFmode && !(TARGET_ZFH || TARGET_ZVFH)) || (mode == SFmode && !TARGET_HARD_FLOAT) || (mode == DFmode && !TARGET_DOUBLE_FLOAT)) return -1; diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fli-5.c b/gcc/testsuite/gcc.target/riscv/zfa-fli-5.c new file mode 100644 index 000..f6ec8f6d99d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zfa-fli-5.c @@ -0,0 +1,99 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64imf_zfa_zvfh -mabi=lp64f" { target { rv64 } } } */ +/* { dg-options "-march=rv32imf_zfa_zvfh -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Oz"} } */ + +/* Even if 'Zfh' is disabled, "fli.h" is usable when + both 'Zfa' and 'Zvfh' are available. */ +#ifdef __riscv_zfh +#error Invalid feature macro defined +#endif + +#define TYPE_h _Float16 + +#define DECL_TYPE(TYPE_SHORT) TYPE_##TYPE_SHORT + +#define DECL_FUNC(TYPE_SHORT, N, VALUE) \ + DECL_TYPE (TYPE_SHORT) const_##TYPE_SHORT##_##N (void) \ +{ \ + return VALUE; \ +} + +#define DECL_FINITE_FUNCS(TYPE_SHORT) \ + DECL_FUNC (TYPE_SHORT, 00, -1) \ + DECL_FUNC (TYPE_SHORT, 02, 0.152587890625) \ + DECL_FUNC (TYPE_SHORT, 03, 0.30517578125) \ + DECL_FUNC (TYPE_SHORT, 04, 0.00390625) \ + DECL_FUNC (TYPE_SHORT, 05, 0.0078125) \ + DECL_FUNC (TYPE_SHORT, 06, 0.0625) \ + DECL_FUNC (TYPE_SHORT, 07, 0.125) \ + DECL_FUNC (TYPE_SHORT, 08, 0.25)\ + DECL_FUNC (TYPE_SHORT, 09, 0.3125) \ + DECL_FUNC (TYPE_SHORT, 10, 0.375) \ + DECL_FUNC (TYPE_SHORT, 11, 0.4375) \ + DECL_FUNC (TYPE_SHORT, 12, 0.5) \ + DECL_FUNC (TYPE_SHORT, 13, 0.625) \ + DECL_FUNC (TYPE_SHORT, 14, 0.75)\ + DECL_FUNC (TYPE_SHORT, 15, 0.875) \ + DECL_FUNC (TYPE_SHORT, 16, 1) \ + DECL_FUNC (TYPE_SHORT, 17, 1.25)\ + DECL_FUNC (TYPE_SHORT, 18, 1.5) \ + DECL_FUNC (TYPE_SHORT, 19, 1.75)\ + DECL_FUNC (TYPE_SHORT, 20, 2) \ + DECL_FUNC (TYPE_SHORT, 21, 2.5) \ + DECL_FUNC (TYPE_SHORT, 22, 3) \ + DECL_FUNC (TYPE_SHORT, 23, 4) \ + DECL_FUNC (TYPE_SHORT, 24, 8) \ + DECL_FUNC (TYPE_SHORT, 25, 16) \ + DECL_FUNC (TYPE_SHORT, 26, 128) \ + DECL_FUNC (TYPE_SHORT, 27, 256) \ + DECL_FUNC (TYPE_SHORT, 28, 32768)
Re: [2/2] RISC-V: Constant FP Optimization with 'Zfa'
On 2023/08/15 12:38, Tsukasa OI wrote: > > On 2023/08/14 21:51, Jin Ma wrote: > >> Hi Tsukasa, > >> What a coincidence, I also implemented zfa extension, which also > >> includes fli related instructions :) > > > > Hi, I'm glad to know that someone is working on this extension more > > comprehensively (especially when "someone" is an experienced GCC > > contributor). I prefer your patch set in general and glad to learn from > > your patch set and your response that my approach was not *that* bad as > > I expected. > > > > When a new extension gets available, I will be more confident making a > > patch set for GCC (as I already do in GNU Binutils). > > > >> > >> links: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627294.html > >> > >>> + if (!TARGET_HARD_FLOAT || !TARGET_ZFA) > >>> +return result; > >>> + switch (GET_MODE (x)) > >>> +{ > >>> +case HFmode: > >>> + /* Not only 'Zfhmin', either 'Zfh' or 'Zvfh' is required. */ > >>> + if (!TARGET_ZFH && !TARGET_ZVFH) > >> > >> When Zvfh means that zfh is also on, so there may be no need to judge > >> the TARGET_ZVFH here. By the way,the format here seems wrong, maybe 'tab' > >> is needed for alignment? > > > > For indentation, I believe this is okay considering 3 indent (soft tab) > > from the top (meaning 6 spaces). > > > > For specification requirements, I think I'm correct. > > > > The spec says that 'Zvfh' depends on 'Zve32f' and 'Zfhmin'. 'Zfhmin' is > > a conversion-only 'Zfh' subset ('Zve32f' doesn't require any > > FP16-related extensions). > > > > Note that "fli.h" requires 'Zfa' and ('Zfh' and/or 'Zvfh'). > > > > So, 'Zfh' alone will not be sufficient to check requirements to the > > "fli.h" instruction. So, checking TARGET_ZFH || TARGET_ZVFH (for > > existence of the "fli.h") should be correct and I think your patch needs > > to be changed "in the long term". > > > > "In the long term" means that, current GNU Binutils has a bug which > > "fli.h" requires 'Zfa' and 'Zfh' ('Zfa' and 'Zvfh' does not work). > > My initial 'Zfa' proposal (improved by Christoph Müllner and upstreamed > > into master) intentionally ignored this case because I assumed that > > approval/ratification of 'Zvfh' will take some time and we have a time > > to fix before a release of Binutils following approval of both 'Zfa' and > > 'Zvfh' (it turned out to be wrong). > > > > cf. <https://sourceware.org/pipermail/binutils/2023-August/129006.html> > > > > So, "fixing" this part (on your patch) alone will not make the program > > work (on the simulator) because current buggy GNU Binutils won't accept > > it. I'm working on it on the GNU Binutils side. > > Okay, the bug is fixed on GNU Binutils (master) and waiting approval > from the release maintainer (for binutils-2_41-branch). > > Thanks, > Tsukasa > Yes, you are right. I did not notice that zfh and zvfh are relatively independent.
RE: [2/2] RISC-V: Constant FP Optimization with 'Zfa'
Hi Tsukasa, What a coincidence, I also implemented zfa extension, which also includes fli related instructions :) links: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627294.html > + if (!TARGET_HARD_FLOAT || !TARGET_ZFA) > +return result; > + switch (GET_MODE (x)) > +{ > +case HFmode: > + /* Not only 'Zfhmin', either 'Zfh' or 'Zvfh' is required. */ > + if (!TARGET_ZFH && !TARGET_ZVFH) When Zvfh means that zfh is also on, so there may be no need to judge the TARGET_ZVFH here. By the way,the format here seems wrong, maybe 'tab' is needed for alignment? > + return result; > + break; > +case SFmode: break; > +case DFmode: break; Maybe we still have to judge TARGET_DOUBLE_FLOAT? > +default: return result; > +} > + > + if (!CONST_DOUBLE_P (x)) > +return result; I think it might be better to judge whether x satisfies the CONST_DOUBLE_P before switch (GET_MODE (x)) above. > + > + r = *CONST_DOUBLE_REAL_VALUE (x); > + > + if (REAL_VALUE_ISNAN (r)) > +{ > + long reprs[2] = { 0 }; > + /* Compare with canonical NaN. */ > + switch (GET_MODE (x)) > + { > + case HFmode: > + reprs[0] = real_to_target (NULL, , > + float_mode_for_size (16).require ()); > + /* 0x7e00: Canonical NaN for binary16. */ > + if (reprs[0] != 0x7e00) > + return result; > + break; > + case SFmode: > + reprs[0] = real_to_target (NULL, , > + float_mode_for_size (32).require ()); > + /* 0x7fc0: Canonical NaN for binary32. */ > + if (reprs[0] != 0x7fc0) > + return result; > + break; > + case DFmode: > + real_to_target (reprs, , float_mode_for_size (64).require ()); > + if (FLOAT_WORDS_BIG_ENDIAN) > + std::swap (reprs[0], reprs[1]); > + /* 0x7ff8_: Canonical NaN for binary64. */ > + if (reprs[0] != 0 || reprs[1] != 0x7ff8) > + return result; > + break; > + default: > + gcc_unreachable (); > + } > + result.type = RISCV_FLOAT_CONST_NAN; > + result.valid = true; > + return result; > +} > + else if (REAL_VALUE_ISINF (r)) > +{ > + if (REAL_VALUE_NEGATIVE (r)) > + return result; > + result.type = RISCV_FLOAT_CONST_INF; > + result.valid = true; > + return result; > +} > + > + bool sign = REAL_VALUE_NEGATIVE (r); > + result.sign = sign; > + > + r = real_value_abs (); > + /* GCC internally does not use IEEE754-like encoding (where normalized > + significands are in the range [1, 2). GCC uses [0.5, 1) (see real.cc). > + So, this exponent_p1 variable equals IEEE754 unbiased exponent + 1. */ > + int exponent_p1 = REAL_EXP (); > + > + /* For the mantissa, we expand into two HOST_WIDE_INTS, apart from the > + highest (sign) bit, with a fixed binary point at bit point_pos. > + m1 holds the low part of the mantissa, m2 the high part. > + WARNING: If we ever have a representation using more than 2 * H_W_I - 1 > + bits for the mantissa, this can fail (low bits will be lost). */ > + bool fail = false; > + real_ldexp (, , (2 * HOST_BITS_PER_WIDE_INT - 1) - exponent_p1); > + wide_int w = real_to_integer (, , HOST_BITS_PER_WIDE_INT * 2); > + if (fail) > +return result; > + > + /* If the low part of the mantissa has bits set we cannot represent > + the value. */ > + if (w.ulow () != 0) > +return result; > + /* We have rejected the lower HOST_WIDE_INT, so update our > + understanding of how many bits lie in the mantissa and > + look only at the high HOST_WIDE_INT. */ > + unsigned HOST_WIDE_INT mantissa = w.elt (1); > + > + /* We cannot represent the value 0.0. */ > + if (mantissa == 0) > +return result; > + > + /* We can only represent values with a mantissa of the form 1.xx. */ > + unsigned HOST_WIDE_INT mask > + = ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 4)) - 1; > + if ((mantissa & mask) != 0) > +return result; > + mantissa >>= HOST_BITS_PER_WIDE_INT - 4; > + /* Now the lowest 3-bits of mantissa should form (1.xx)b. */ > + gcc_assert (mantissa & (1u << 2)); > + /* Mask out the highest bit. */ > + mantissa &= ~(1u << 2); > + > + if (mantissa == 0) > +{ > + /* We cannot represent any values but -1.0. */ > + if (exponent_p1 != 1 && sign) > + return result; > + switch (exponent_p1) > + { > + case -15: /* 1.0 * 2^(-16) */ > + case -14: /* 1.0 * 2^(-15) */ > + case -7: /* 1.0 * 2^(- 8) */ > + case -6: /* 1.0 * 2^(- 7) */ > + case 8: /* 1.0 * 2^(+ 7) */ > + case 9: /* 1.0 * 2^(+ 8) */ > + case 16: /* 1.0 * 2^(+15) */ > + case 17: /* 1.0 * 2^(+16) */ > + break; > + default: > + if (exponent_p1 >= -3 && exponent_p1 <= 5) > + /* 1.0 * 2^[-4,4] */ > + break; > + switch (GET_MODE (x)) > +
[PATCH v2] In the pipeline, USE or CLOBBER should delay execution if it starts a new live range.
CLOBBER and USE does not represent real instructions, but in the process of pipeline optimization, they will wait for transmission in ready list like other insns, without considering resource conflicts and cycles. This results in a multi-issue CPU architecture that can be issued at any time if other regular insns have resource conflicts or cannot be launched for other reasons. As a result, its position is advanced in the generated insns sequence, which will affect register allocation and often lead to more redundant mov instructions. A simple example: https://github.com/majin2020/gcc-test/blob/master/test.c This is a function in the dhrystone benchmark. https://github.com/majin2020/gcc-test/blob/0b08c1a13de9663d7d9aba7539b960ec0607ca24/test.c.299r.sched1 This is a log of the pass 'sched1' When -mtune=rocket but issue_rate == 2. The pipeline is: ;; | insn | prio | ;; | 17 | 3 | r142=a0 alu ;; | 14 | 0 | clobber r136 nothing ;; | 13 | 0 | clobber a0 nothing ;; | 18 | 2 | r143=a1 alu ... ;; | 12 | 0 | a0=r136 alu ;; | 15 | 0 | use a0 nothing In this log, insn 13 and 14 are much ahead of schedule, which risks generating redundant mov instructions, which seems unreasonable. Therefore, I submit patch again on the basis of the last review opinions to try to solve this problem. https://github.com/majin2020/gcc-test/commit/efcb43e3369e771bde702955048bfe3f501263dd#diff-805031b1be5092a2322852a248d0b0f92eef7cad5784a8209f4dfc6221407457L189 This is the diff log of shed1 after patch is added. The new pipeline is: ;; | insn | prio | ;; | 17 | 3 | r142=a0 alu ... ;; | 10 | 0 | [r144]=r141 alu ;; | 13 | 0 | clobber a0 nothing ;; | 14 | 0 | clobber r136 nothing ;; | 12 | 0 | a0=r136 alu ;; | 15 | 0 | use a0 nothing gcc/ChangeLog: * haifa-sched.cc (use_or_clobber_starts_range_p): New. (prune_ready_list): USE or CLOBBER should delay execution if it starts a new live range. --- gcc/haifa-sched.cc | 55 +- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 8e8add709b3..47ad09457c7 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -765,6 +765,23 @@ real_insn_for_shadow (rtx_insn *insn) return pair->i1; } +/* Return TRUE if INSN (a USE or CLOBBER) starts a new live +range, FALSE otherwise. */ + +static bool +use_or_clobber_starts_range_p (rtx_insn *insn) +{ + gcc_assert (insn); + + if ((GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == USE) + && !sd_lists_empty_p (insn, SD_LIST_FORW) + && sd_lists_empty_p (insn, SD_LIST_BACK)) +return true; + + return false; +} + /* For a pair P of insns, return the fixed distance in cycles from the first insn after which the second must be scheduled. */ static int @@ -6320,11 +6337,39 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p, } else if (recog_memoized (insn) < 0) { - if (!first_cycle_insn_p - && (GET_CODE (PATTERN (insn)) == ASM_INPUT - || asm_noperands (PATTERN (insn)) >= 0)) - cost = 1; - reason = "asm"; + if (GET_CODE (PATTERN (insn)) == ASM_INPUT + || asm_noperands (PATTERN (insn)) >= 0) + { + reason = "asm"; + if (!first_cycle_insn_p) + cost = 1; + } + else if (use_or_clobber_starts_range_p (insn)) + { + /* If USE or CLOBBER opens an active range, its execution should +be delayed so as to be closer to the relevant instructions and +avoid the generation of some redundant mov instructions. +Otherwise, it should be executed as soon as possible. */ + reason = "unrecog insn"; + if (!first_cycle_insn_p) + /* If USE or CLOBBER is not in the first cycle, simply delay it + by one cycle. */ + cost = 1; + else + { + /* If the USE or CLOBBER is in the first cycle and there are no +other non-USE or non-CLOBBER instructions after it, we need +to execute it immediately, otherwise we need to execute the +non-USE or non-CLOBBER instructions first and postpone the +execution of the USE or CLOBBER instructions. */ + int j = i; + while (n > ++j) + if (!use_or_clobber_starts_range_p (ready_element (, j))) + break; + + cost = (j == n) ? 0 : 1; + } + } } else if (sched_pressure != SCHED_PRESSURE_NONE) {
Re: [PATCH v9] RISC-V: Add the 'zfa' extension, version 0.2
Additional links: v10, the patch that needs to be reviewed again: http://patchwork.ozlabs.org/project/gcc/patch/20230814055033.1995-1-ji...@linux.alibaba.com/ v9 and the previous review comments: http://patchwork.ozlabs.org/project/gcc/patch/20230515131628.953-1-ji...@linux.alibaba.com/ Zfa patch in master branch of binutils-gdb https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=1f3fc45bddc7147a2e59346a59290094137ef1e1
Re: [PATCH v9] RISC-V: Add the 'zfa' extension, version 0.2
> > Hi Jin Ma, > > > > On 5/16/23 00:06, jinma via Gcc-patches wrote: > > > On 5/15/23 07:16, Jin Ma wrote: > > >> > > >> Do we also need to check Z[FDH]INX too? > > >> > > >> Otherwise it looks pretty good. We just need to wait for everything to > > >> freeze and finalization on the assembler interface. > > >> > > >> jeff > > > Yes, you are right, we also need to check Z[FDH]INX. I will send a patch > > > again to fix it after others give some review comments. > > > > Can we please revisit this and get this merged upstream. > > Seems like gcc is supporting frozen but not ratified extensions. > > > > Thx, > > -Vineet > > OK, I will check and resend a patch about this in a few days. > > Thanks, > Jin Done, and please review again. Compared with the v9 version two months ago, the previous review comments have been modified. At the same time, the variable riscv_zfa_subext have been added to riscv.opt to enable zfa extension.
[PATCH v10] RISC-V: Add support for the Zfa extension
This patch adds the 'Zfa' extension for riscv, which is based on: https://github.com/riscv/riscv-isa-manual/commits/zfb The binutils-gdb for 'Zfa' extension: https://sourceware.org/pipermail/binutils/2023-April/127060.html What needs special explanation is: 1, According to riscv-spec, "The FCVTMO D.W.D instruction was added principally to accelerate the processing of JavaScript Numbers.", so it seems that no implementation is required. 2, The instructions FMINM and FMAXM correspond to C23 library function fminimum and fmaximum. Therefore, this patch has simply implemented the pattern of fminm3 and fmaxm3 to prepare for later. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add zfa extension version, which depends on the F extension. * config/riscv/constraints.md (zfli): Constrain the floating point number that the instructions FLI.H/S/D can load. * config/riscv/iterators.md (ceil): New. * config/riscv/riscv-opts.h (MASK_ZFA): New. (TARGET_ZFA): New. * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_fli): New. * config/riscv/riscv.cc (riscv_float_const_rtx_index_for_fli): New. (riscv_cannot_force_const_mem): If instruction FLI.H/S/D can be used, memory is not applicable. (riscv_const_insns): Likewise. (riscv_legitimize_const_move): Likewise. (riscv_split_64bit_move_p): If instruction FLI.H/S/D can be used, no split is required. (riscv_split_doubleword_move): Likewise. (riscv_output_move): Output the mov instructions in zfa extension. (riscv_print_operand): Output the floating-point value of the FLI.H/S/D immediate in assembly. (riscv_secondary_memory_needed): Likewise. * config/riscv/riscv.md (fminm3): New. (fmaxm3): New. (movsidf2_low_rv32): New. (movsidf2_high_rv32): New. (movdfsisi3_rv32): New. (f_quiet4_zfa): New. * config/riscv/riscv.opt: New. gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fleq-fltq.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.c: New test. * gcc.target/riscv/zfa-fround.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 7 + gcc/config/riscv/constraints.md | 21 +- 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 | 205 +- gcc/config/riscv/riscv.md | 145 +++-- gcc/config/riscv/riscv.opt| 3 + .../gcc.target/riscv/zfa-fleq-fltq.c | 20 ++ gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c | 42 gcc/testsuite/gcc.target/riscv/zfa-fli.c | 80 +++ .../gcc.target/riscv/zfa-fmovh-fmovp.c| 10 + gcc/testsuite/gcc.target/riscv/zfa-fround.c | 43 13 files changed, 549 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.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.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/config/riscv/riscv-common.cc index 21f83f26371..c16986e1762 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -123,6 +123,9 @@ static const riscv_implied_info_t riscv_implied_info[] = {"zfh", "zfhmin"}, {"zfhmin", "f"}, + + {"zfa", "f"}, + {"zvfhmin", "zve32f"}, {"zvfh", "zve32f"}, {"zvfh", "zfhmin"}, @@ -262,6 +265,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zvfhmin", ISA_SPEC_CLASS_NONE, 1, 0}, {"zvfh", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zfa", ISA_SPEC_CLASS_NONE, 0, 1}, + {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0}, {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1405,6 +1410,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zvfhmin", _options::x_riscv_zf_subext, MASK_ZVFHMIN}, {"zvfh", _options::x_riscv_zf_subext, MASK_ZVFH}, + {"zfa", _options::x_riscv_zfa_subext, MASK_ZFA}, + {"zmmul", _options::x_riscv_zm_subext, MASK_ZMMUL}, {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL}, diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 44525b2da49..3f52bc76f67 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -118,6 +118,19 @@ (define_constraint "T" (and (match_operand 0 "move_operand") (match_test "CONSTANT_P (op)"))) +;; Zfa constraints. + +(define_constraint "zfli" + "A floating point number
Re: [PATCH v9] RISC-V: Add the 'zfa' extension, version 0.2
> Hi Jin Ma, > > On 5/16/23 00:06, jinma via Gcc-patches wrote: > > On 5/15/23 07:16, Jin Ma wrote: > >> > >> Do we also need to check Z[FDH]INX too? > >> > >> Otherwise it looks pretty good. We just need to wait for everything to > >> freeze and finalization on the assembler interface. > >> > >> jeff > > Yes, you are right, we also need to check Z[FDH]INX. I will send a patch > > again to fix it after others give some review comments. > > Can we please revisit this and get this merged upstream. > Seems like gcc is supporting frozen but not ratified extensions. > > Thx, > -Vineet OK, I will check and resend a patch about this in a few days. Thanks, Jin
Re: [PATCH] RISC-V: Handle no_insn in TARGET_SCHED_VARIABLE_ISSUE.
> On 5/29/23 06:46, Jeff Law wrote: > > > > > > On 5/29/23 05:01, Jin Ma wrote: > >> Reference: > >> https://github.com/gcc-mirror/gcc/commit/d0bc0cb66bcb0e6a5a5a31a9e900e8ccc98e34e5 > >> > >> RISC-V should also be implemented to handle no_insn patterns for > >> pipelining. > >> > >> gcc/ChangeLog: > >> > >> * config/riscv/riscv.cc (riscv_sched_variable_issue): New function. > >> (TARGET_SCHED_VARIABLE_ISSUE): New macro. > >> --- > >> gcc/config/riscv/riscv.cc | 21 + > >> 1 file changed, 21 insertions(+) > >> > >> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > >> index 3954fc07a8b..559fa9cd7e0 100644 > >> --- a/gcc/config/riscv/riscv.cc > >> +++ b/gcc/config/riscv/riscv.cc > >> @@ -6225,6 +6225,24 @@ riscv_issue_rate (void) > >> return tune_param->issue_rate; > >> } > >> +/* Implement TARGET_SCHED_VARIABLE_ISSUE. */ > >> + > >> +static int > >> +riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more) > >> +{ > >> + if (DEBUG_INSN_P (insn)) > >> +return more; > >> + > >> + rtx_code code = GET_CODE (PATTERN (insn)); > >> + if (code == USE || code == CLOBBER) > >> +return more; > >> + > >> + if (get_attr_type (insn) == TYPE_UNKNOWN) > >> +return more; > >> + > >> + return more - 1; > >> +} > > The problem is that INSN is *much* more likely to be a real instruction > > that takes real resources, even if it is TYPE_UNKNOWN. > > TYPE_UNKNOWN here is actually an indicator of what I would consider a > > bug in the backend, specifically that we have INSNs that do not provide > > a mapping for the schedulers to suitable types. > > > > With that in mind I'd much rather get to the point where we can do > > something like this for TYPE_UNKNOWN: > > > > type = get_attr_type (insn); > > gcc_assert (type != TYPE_UNKNOWN); > > > > That way if we ever encounter a TYPE_UNKNOWN during development, we can > > fix it in the md files in a sensible manner. I don't know if we are > > close to being able to do that. We fixed a ton of stuff in bitmanip.md, > > but I don't think there's been a thorough review of the port to find > > other instances of TYPE_UNKNOWN INSNs. > > > > > > The other thing if this code probably wants to handle GHOST type > > instructions. While GHOST is used for instructions which generate no > > code, it might seem they should return "more" as those INSNs take no > > resources. But GHOST is actually used for things like the blockage insn > > which should end a cycle from an issue standpoint. So the right > > handling of a GHOST is something like this: > > > > if (type == TYPE_GHOST) > >return 0; > So there wasn't ever any follow-up. Given this was something Ventana > was also carrying locally (with very minor differences) I went ahead and > merged up the implementations and pushed the final result to the trunk. > > > Attached is the patch that was actually committed. > > Jeff My fault, I'm very sorry for not replying to the patch follow-up, I just forgot this :)
[PATCH v4] RISC-V: Fixbug for fsflags instruction error using immediate.
The pattern mistakenly believes that fsflags can use immediate numbers, but in fact it does not support it. Immediate numbers should use fsflagsi. For example: __builtin_riscv_fsflags(4); The following error occurred. /tmp/ccoWdWqT.s: Assembler messages: /tmp/ccoWdWqT.s:14: Error: illegal operands `fsflags 4' gcc/ChangeLog: * config/riscv/riscv.md: Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/fsflags.c: New test. --- gcc/config/riscv/riscv.md| 4 ++-- gcc/testsuite/gcc.target/riscv/fsflags.c | 16 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/fsflags.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4615e811947..24515bcf706 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3074,7 +3074,7 @@ (define_insn "riscv_frcsr" "frcsr\t%0") (define_insn "riscv_fscsr" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_FSCSR)] "TARGET_HARD_FLOAT || TARGET_ZFINX" "fscsr\t%0") @@ -3087,7 +3087,7 @@ (define_insn "riscv_frflags" (define_insn "riscv_fsflags" [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] "TARGET_HARD_FLOAT || TARGET_ZFINX" - "fsflags\t%0") + "fsflags%i0\t%0") (define_insn "*riscv_fsnvsnan2" [(unspec_volatile [(match_operand:ANYF 0 "register_operand" "f") diff --git a/gcc/testsuite/gcc.target/riscv/fsflags.c b/gcc/testsuite/gcc.target/riscv/fsflags.c new file mode 100644 index 000..74a97b8a7c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fsflags.c @@ -0,0 +1,16 @@ +/* Verify that fsflags is using the correct register or immediate. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-options "-O" } */ + +void foo1 (int a) +{ + __builtin_riscv_fsflags(a); +} +void foo2 () +{ + __builtin_riscv_fsflags(4); +} + +/* { dg-final { scan-assembler-times "fsflags\t" 1 } } */ +/* { dg-final { scan-assembler-times "fsflagsi\t" 1 } } */ -- 2.17.1
Re: Re: [PATCH v3] RISC-V: Fixbug for fsflags instruction error using immediate.
> So I guess you should change `fscsr` to `fscsr%i0` instead of dropping > K from the constraint list? > Sorry, you are right. I thought you were talking about fsflags, but I didn't notice it was fscsr. I'll correct it right away. > On Wed, Jul 26, 2023 at 11:42 AM juzhe.zh...@rivai.ai > wrote: > > > > I don't understand: > > (define_insn "riscv_fscsr" > > - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] > > UNSPECV_FSCSR)] > > + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] > > UNSPECV_FSCSR)] > >"TARGET_HARD_FLOAT || TARGET_ZFINX" > >"fscsr\t%0") > > > > This pattern never allows immediate in the constraint. Why still make > > predicate allow immediate? > > > > > > > > > > juzhe.zh...@rivai.ai > > > > From: Jin Ma > > Date: 2023-07-26 11:33 > > To: gcc-patches; juzhe.zh...@rivai.ai > > CC: jeffreyalaw; palmer; richard.sandiford; kito.cheng; philipp.tomsich; > > christoph.muellner; Robin Dapp; jinma.contrib > > Subject: Re: [PATCH v3] RISC-V: Fixbug for fsflags instruction error using > > immediate. > > > - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] > > > UNSPECV_FSCSR)] > > > + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] > > > UNSPECV_FSCSR)] > > > > > > If you don't allow immediate value in range 0 ~ 31, it should be > > > "register_operand" instead of "csr_operand". > > > > > > > > > > I think directives that support the immediate pattern might be better, on > > the one > > hand fsflagsi are supported in the manual, on the other hand fsflagsi can be > > slightly faster than fsflags. > > > > Regards > > Jin > > > > > > > > juzhe.zh...@rivai.ai > > >
Re: [PATCH v3] RISC-V: Fixbug for fsflags instruction error using immediate.
> - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] > + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] UNSPECV_FSCSR)] > > If you don't allow immediate value in range 0 ~ 31, it should be > "register_operand" instead of "csr_operand". > > I think directives that support the immediate pattern might be better, on the one hand fsflagsi are supported in the manual, on the other hand fsflagsi can be slightly faster than fsflags. Regards Jin > > juzhe.zh...@rivai.ai >
[PATCH v3] RISC-V: Fixbug for fsflags instruction error using immediate.
The pattern mistakenly believes that fsflags can use immediate numbers, but in fact it does not support it. Immediate numbers should use fsflagsi. For example: __builtin_riscv_fsflags(4); The following error occurred. /tmp/ccoWdWqT.s: Assembler messages: /tmp/ccoWdWqT.s:14: Error: illegal operands `fsflags 4' gcc/ChangeLog: * config/riscv/riscv.md: Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/fsflags.c: New test. --- gcc/config/riscv/riscv.md| 4 ++-- gcc/testsuite/gcc.target/riscv/fsflags.c | 16 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/fsflags.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4615e811947..74ff9ccc968 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3074,7 +3074,7 @@ (define_insn "riscv_frcsr" "frcsr\t%0") (define_insn "riscv_fscsr" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] UNSPECV_FSCSR)] "TARGET_HARD_FLOAT || TARGET_ZFINX" "fscsr\t%0") @@ -3087,7 +3087,7 @@ (define_insn "riscv_frflags" (define_insn "riscv_fsflags" [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] "TARGET_HARD_FLOAT || TARGET_ZFINX" - "fsflags\t%0") + "fsflags%i0\t%0") (define_insn "*riscv_fsnvsnan2" [(unspec_volatile [(match_operand:ANYF 0 "register_operand" "f") diff --git a/gcc/testsuite/gcc.target/riscv/fsflags.c b/gcc/testsuite/gcc.target/riscv/fsflags.c new file mode 100644 index 000..74a97b8a7c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fsflags.c @@ -0,0 +1,16 @@ +/* Verify that fsflags is using the correct register or immediate. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-options "-O" } */ + +void foo1 (int a) +{ + __builtin_riscv_fsflags(a); +} +void foo2 () +{ + __builtin_riscv_fsflags(4); +} + +/* { dg-final { scan-assembler-times "fsflags\t" 1 } } */ +/* { dg-final { scan-assembler-times "fsflagsi\t" 1 } } */ -- 2.17.1
Re: [PATCH] RISC-V: Fixbug for fsflags instruction error using immediate.
> Hi Jin, > > this looks reasonable. Would you mind adding (small) test cases > still to make sure we don't accidentally reintroduce the problem? > > Regards > Robin Ok, I have already sent the v2 version, please review it again, thanks. Link: https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625390.html
[PATCH v2] RISC-V: Fixbug for fsflags instruction error using immediate.
The pattern mistakenly believes that fsflags can use immediate numbers, but in fact it does not support it. Immediate numbers should use fsflagsi. For example: __builtin_riscv_fsflags(4); The following error occurred. /tmp/ccoWdWqT.s: Assembler messages: /tmp/ccoWdWqT.s:14: Error: illegal operands `fsflags 4' gcc/ChangeLog: * config/riscv/riscv.md: Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/fsflags.c: New test. --- gcc/config/riscv/riscv.md| 8 +--- gcc/testsuite/gcc.target/riscv/fsflags.c | 16 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/fsflags.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4615e811947..1ec85e30d7e 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3074,7 +3074,7 @@ (define_insn "riscv_frcsr" "frcsr\t%0") (define_insn "riscv_fscsr" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] UNSPECV_FSCSR)] "TARGET_HARD_FLOAT || TARGET_ZFINX" "fscsr\t%0") @@ -3085,9 +3085,11 @@ (define_insn "riscv_frflags" "frflags\t%0") (define_insn "riscv_fsflags" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r,K")] UNSPECV_FSFLAGS)] "TARGET_HARD_FLOAT || TARGET_ZFINX" - "fsflags\t%0") + "@ + fsflags\t%0 + fsflagsi\t%0") (define_insn "*riscv_fsnvsnan2" [(unspec_volatile [(match_operand:ANYF 0 "register_operand" "f") diff --git a/gcc/testsuite/gcc.target/riscv/fsflags.c b/gcc/testsuite/gcc.target/riscv/fsflags.c new file mode 100644 index 000..74a97b8a7c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fsflags.c @@ -0,0 +1,16 @@ +/* Verify that fsflags is using the correct register or immediate. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-options "-O" } */ + +void foo1 (int a) +{ + __builtin_riscv_fsflags(a); +} +void foo2 () +{ + __builtin_riscv_fsflags(4); +} + +/* { dg-final { scan-assembler-times "fsflags\t" 1 } } */ +/* { dg-final { scan-assembler-times "fsflagsi\t" 1 } } */ -- 2.17.1
[PATCH] RISC-V: Fixbug for fsflags instruction error using immediate.
The pattern mistakenly believes that fsflags can use immediate numbers, but in fact it does not support it. Immediate numbers should use fsflagsi. For example: __builtin_riscv_fsflags(4); The following error occurred: /tmp/ccoWdWqT.s: Assembler messages: /tmp/ccoWdWqT.s:14: Error: illegal operands `fsflags 4' gcc/ChangeLog: * config/riscv/riscv.md: Likewise. --- gcc/config/riscv/riscv.md | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4615e811947..1ec85e30d7e 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3074,7 +3074,7 @@ (define_insn "riscv_frcsr" "frcsr\t%0") (define_insn "riscv_fscsr" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r")] UNSPECV_FSCSR)] "TARGET_HARD_FLOAT || TARGET_ZFINX" "fscsr\t%0") @@ -3085,9 +3085,11 @@ (define_insn "riscv_frflags" "frflags\t%0") (define_insn "riscv_fsflags" - [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "r,K")] UNSPECV_FSFLAGS)] "TARGET_HARD_FLOAT || TARGET_ZFINX" - "fsflags\t%0") + "@ + fsflags\t%0 + fsflagsi\t%0") (define_insn "*riscv_fsnvsnan2" [(unspec_volatile [(match_operand:ANYF 0 "register_operand" "f") -- 2.17.1
Re: [RFC] RISC-V: Support risc-v bfloat16 This patch support bfloat16 in riscv like x86_64 and arm.
> diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md > index 5b70ab20758..6349f032bc8 100644 > --- a/gcc/config/riscv/iterators.md > +++ b/gcc/config/riscv/iterators.md > @@ -61,10 +61,15 @@ > ;; Iterator for hardware-supported floating-point modes. > (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX") > (DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX") > - (HF "TARGET_ZFH || TARGET_ZHINX")]) > + (HF "TARGET_ZFH || TARGET_ZHINX") > +(BF "TARGET_ZFBFMIN")]) > + > +;; Iterator for HImode constant generation. > +(define_mode_iterator BFHF [BF HF]) > > ;; Iterator for floating-point modes that can be loaded into X registers. > -(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")]) > +(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN") > +(BF "TARGET_ZFBFMIN")]) > > > ;; --- > @@ -76,27 +81,27 @@ > (define_mode_attr size [(QI "b") (HI "h")]) > > ;; Mode attributes for loads. > -(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") > (SF "flw") (DF "fld")]) > +(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (BF "flh") > (HF "flh") (SF "flw") (DF "fld")]) > > ;; Instruction names for integer loads that aren't explicitly sign or zero > ;; extended. See riscv_output_move and LOAD_EXTEND_OP. > (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")]) > > ;; Mode attribute for FP loads into integer registers. > -(define_mode_attr softload [(HF "lh") (SF "lw") (DF "ld")]) > +(define_mode_attr softload [(BF "lh") (HF "lh") (SF "lw") (DF "ld")]) > > ;; Instruction names for stores. > -(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (HF "fsh") > (SF "fsw") (DF "fsd")]) > +(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (BF "fsh") > (HF "fsh") (SF "fsw") (DF "fsd")]) > > ;; Instruction names for FP stores from integer registers. > -(define_mode_attr softstore [(HF "sh") (SF "sw") (DF "sd")]) > +(define_mode_attr softstore [(BF "sh") (HF "sh") (SF "sw") (DF "sd")]) > > ;; This attribute gives the best constraint to use for registers of > ;; a given mode. > (define_mode_attr reg [(SI "d") (DI "d") (CC "d")]) > > ;; This attribute gives the format suffix for floating-point operations. > -(define_mode_attr fmt [(HF "h") (SF "s") (DF "d")]) > +(define_mode_attr fmt [(BF "h") (HF "h") (SF "s") (DF "d")]) > > ;; This attribute gives the integer suffix for floating-point conversions. > (define_mode_attr ifmt [(SI "w") (DI "l")]) > @@ -106,7 +111,7 @@ > > ;; This attribute gives the upper-case mode name for one unit of a > ;; floating-point mode. > -(define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")]) > +(define_mode_attr UNITMODE [(BF "BF") (HF "HF") (SF "SF") (DF "DF")]) > There are also some problems here, which cannot be simply handled like HF. Many instructions support HF but do not support BF. For example, fadd.h can be used for HF but cannot be used for BF. I guess it may need to be converted to SF first, then fadd.s, and finally converted to BF. I'm not so sure.
Re: [RFC] RISC-V: Support risc-v bfloat16 This patch support bfloat16 in riscv like x86_64 and arm.
> diff --git a/gcc/common/config/riscv/riscv-common.cc > b/gcc/common/config/riscv/riscv-common.cc > index ebc1ed7d7e4..2b3ff1f5b8e 100644 > --- a/gcc/common/config/riscv/riscv-common.cc > +++ b/gcc/common/config/riscv/riscv-common.cc > @@ -102,6 +102,8 @@ static const riscv_implied_info_t riscv_implied_info[] = > {"zvl32768b", "zvl16384b"}, > {"zvl65536b", "zvl32768b"}, > > + {"zfbfmin", "zfhmin"}, > + > {"zfh", "zfhmin"}, > {"zfhmin", "f"}, > > @@ -1239,6 +1241,8 @@ static const riscv_ext_flag_table_t > riscv_ext_flag_table[] = > {"zvl16384b", _options::x_riscv_zvl_flags, MASK_ZVL16384B}, > {"zvl32768b", _options::x_riscv_zvl_flags, MASK_ZVL32768B}, > {"zvl65536b", _options::x_riscv_zvl_flags, MASK_ZVL65536B}, > + > + {"zfbfmin", _options::x_riscv_zf_subext, MASK_ZFBFMIN}, > > {"zfhmin", _options::x_riscv_zf_subext, MASK_ZFHMIN}, > {"zfh", _options::x_riscv_zf_subext, MASK_ZFH}, As kito says, there is no version information for the extension. > diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md > index 5b70ab20758..6349f032bc8 100644 > --- a/gcc/config/riscv/iterators.md > +++ b/gcc/config/riscv/iterators.md > @@ -61,10 +61,15 @@ > ;; Iterator for hardware-supported floating-point modes. > (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX") > (DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX") > - (HF "TARGET_ZFH || TARGET_ZHINX")]) > + (HF "TARGET_ZFH || TARGET_ZHINX") > + (BF "TARGET_ZFBFMIN")]) > + > +;; Iterator for HImode constant generation. > +(define_mode_iterator BFHF [BF HF]) > > ;; Iterator for floating-point modes that can be loaded into X registers. > -(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")]) > +(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN") > + (BF "TARGET_ZFBFMIN")]) > > > ;; --- > @@ -76,27 +81,27 @@ > (define_mode_attr size [(QI "b") (HI "h")]) > > ;; Mode attributes for loads. > -(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") > (SF "flw") (DF "fld")]) > +(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (BF "flh") > (HF "flh") (SF "flw") (DF "fld")]) > > ;; Instruction names for integer loads that aren't explicitly sign or zero > ;; extended. See riscv_output_move and LOAD_EXTEND_OP. > (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")]) > > ;; Mode attribute for FP loads into integer registers. > -(define_mode_attr softload [(HF "lh") (SF "lw") (DF "ld")]) > +(define_mode_attr softload [(BF "lh") (HF "lh") (SF "lw") (DF "ld")]) > > ;; Instruction names for stores. > -(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (HF "fsh") > (SF "fsw") (DF "fsd")]) > +(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (BF "fsh") > (HF "fsh") (SF "fsw") (DF "fsd")]) > > ;; Instruction names for FP stores from integer registers. > -(define_mode_attr softstore [(HF "sh") (SF "sw") (DF "sd")]) > +(define_mode_attr softstore [(BF "sh") (HF "sh") (SF "sw") (DF "sd")]) > > ;; This attribute gives the best constraint to use for registers of > ;; a given mode. > (define_mode_attr reg [(SI "d") (DI "d") (CC "d")]) > > ;; This attribute gives the format suffix for floating-point operations. > -(define_mode_attr fmt [(HF "h") (SF "s") (DF "d")]) > +(define_mode_attr fmt [(BF "h") (HF "h") (SF "s") (DF "d")]) > > ;; This attribute gives the integer suffix for floating-point conversions. > (define_mode_attr ifmt [(SI "w") (DI "l")]) > @@ -106,7 +111,7 @@ > > ;; This attribute gives the upper-case mode name for one unit of a > ;; floating-point mode. > -(define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")]) > +(define_mode_attr UNITMODE [(BF "BF") (HF "HF") (SF "SF") (DF "DF")]) > > ;; This attribute gives the integer mode that has half the size of > ;; the controlling mode. > diff --git a/gcc/config/riscv/riscv-builtins.cc > b/gcc/config/riscv/riscv-builtins.cc > index 25ca407f9a9..e0c6f6834a5 100644 > --- a/gcc/config/riscv/riscv-builtins.cc > +++ b/gcc/config/riscv/riscv-builtins.cc > @@ -163,6 +163,7 @@ static GTY(()) int > riscv_builtin_decl_index[NUM_INSN_CODES]; > riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]] > > tree riscv_float16_type_node = NULL_TREE; > +tree riscv_bfloat16_type_node = NULL_TREE; > > /* Return the function type associated with function prototype TYPE. */ > > @@ -190,7 +191,7 @@ riscv_build_function_type (enum riscv_function_type type) > } > > static void > -riscv_init_builtin_types (void) > +riscv_fp16_builtin_type (void) > { > /* Provide the _Float16 type and float16_type_node if needed. */ > if (!float16_type_node) > @@ -208,6 +209,32 @@ riscv_init_builtin_types (void) > "_Float16"); > } > > +static void > +riscv_bf16_builtin_type (void) > +{ > + /* Provide the _bf16 type and bfloat16_type_node if needed. */ > + if (!bfloat16_type_node) > + { > + riscv_bfloat16_type_node = make_node (REAL_TYPE);
[PATCH v2] RISC-V: Save and restore FCSR in interrupt functions to avoid program errors.
In order to avoid interrupt functions to change the FCSR, it needs to be saved and restored at the beginning and end of the function. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_compute_frame_info): Allocate frame for FCSR. (riscv_for_each_saved_reg): Save and restore FCSR in interrupt functions. * config/riscv/riscv.md (riscv_frcsr): New patterns. (riscv_fscsr): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/interrupt-fcsr-1.c: New test. * gcc.target/riscv/interrupt-fcsr-2.c: New test. * gcc.target/riscv/interrupt-fcsr-3.c: New test. --- gcc/config/riscv/riscv.cc | 48 +-- gcc/config/riscv/riscv.md | 13 + .../gcc.target/riscv/interrupt-fcsr-1.c | 15 ++ .../gcc.target/riscv/interrupt-fcsr-2.c | 15 ++ .../gcc.target/riscv/interrupt-fcsr-3.c | 14 ++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-3.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index dd5361c2bd2..9d71e5c9f72 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -5095,12 +5095,15 @@ riscv_compute_frame_info (void) frame = >machine->frame; - /* In an interrupt function, if we have a large frame, then we need to - save/restore t0. We check for this before clearing the frame struct. */ + /* In an interrupt function, there are two cases in which t0 needs to be used: + 1, If we have a large frame, then we need to save/restore t0. We check for + this before clearing the frame struct. + 2, Need to save and restore some CSRs in the frame. */ if (cfun->machine->interrupt_handler_p) { HOST_WIDE_INT step1 = riscv_first_stack_step (frame, frame->total_size); - if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1))) + if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1)) + || (TARGET_HARD_FLOAT || TARGET_ZFINX)) interrupt_save_prologue_temp = true; } @@ -5147,6 +5150,17 @@ riscv_compute_frame_info (void) } } + /* In an interrupt function, we need extra space for the initial saves of CSRs. */ + if (cfun->machine->interrupt_handler_p + && ((TARGET_HARD_FLOAT && frame->fmask) + || (TARGET_ZFINX + /* Except for RISCV_PROLOGUE_TEMP_REGNUM. */ + && (frame->mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) +/* Save and restore FCSR. */ +/* TODO: When P or V extensions support interrupts, some of their CSRs + may also need to be saved and restored. */ +x_save_size += riscv_stack_align (1 * UNITS_PER_WORD); + /* At the bottom of the frame are any outgoing stack arguments. */ offset = riscv_stack_align (crtl->outgoing_args_size); /* Next are local stack variables. */ @@ -5392,6 +5406,34 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } + /* In an interrupt function, save and restore some necessary CSRs in the stack +to avoid changes in CSRs. */ + if (regno == RISCV_PROLOGUE_TEMP_REGNUM + && cfun->machine->interrupt_handler_p + && ((TARGET_HARD_FLOAT && cfun->machine->frame.fmask) + || (TARGET_ZFINX + && (cfun->machine->frame.mask & ~(1 << RISCV_PROLOGUE_TEMP_REGNUM) + { + unsigned int fcsr_size = GET_MODE_SIZE (SImode); + if (!epilogue) + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset, riscv_save_reg); + } + else + { + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, + offset - fcsr_size, riscv_restore_reg); + emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode))); + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + } + continue; + } + riscv_save_restore_reg (word_mode, regno, offset, fn); } diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d8e935cb934..565e8cd27cd 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -78,6 +78,8 @@ (define_c_enum "unspecv" [ UNSPECV_GPR_RESTORE ;; Floating-point unspecs. + UNSPECV_FRCSR + UNSPECV_FSCSR UNSPECV_FRFLAGS UNSPECV_FSFLAGS UNSPECV_FSNVSNAN @@ -3056,6 +3058,17 @@ (define_insn "gpr_restore_return" "" "") +(define_insn "riscv_frcsr" + [(set (match_operand:SI 0 "register_operand" "=r") +
[PATCH] RISC-V: Save and restore FCSR in interrupt functions to avoid program errors.
gcc/ChangeLog: * config/riscv/riscv.cc (riscv_compute_frame_info): Allocate frame for FCSR. (riscv_for_each_saved_reg): Save and restore FCSR in interrupt functions. * config/riscv/riscv.md (riscv_frcsr): New patterns. (riscv_fscsr): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/interrupt-fcsr-1.c: New test. * gcc.target/riscv/interrupt-fcsr-2.c: New test. * gcc.target/riscv/interrupt-fcsr-3.c: New test. --- gcc/config/riscv/riscv.cc | 33 ++- gcc/config/riscv/riscv.md | 13 .../gcc.target/riscv/interrupt-fcsr-1.c | 14 .../gcc.target/riscv/interrupt-fcsr-2.c | 14 .../gcc.target/riscv/interrupt-fcsr-3.c | 13 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-fcsr-3.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index de30bf4e567..4ef9692b4db 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4990,7 +4990,8 @@ riscv_compute_frame_info (void) if (cfun->machine->interrupt_handler_p) { HOST_WIDE_INT step1 = riscv_first_stack_step (frame, frame->total_size); - if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1))) + if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1)) + || TARGET_HARD_FLOAT) interrupt_save_prologue_temp = true; } @@ -5035,6 +5036,13 @@ riscv_compute_frame_info (void) frame->save_libcall_adjustment = x_save_size; } + + if (TARGET_HARD_FLOAT + && cfun->machine->interrupt_handler_p + && frame->fmask) + /* In an interrupt function, we need extra space + for the initial saves of FCSR. */ + x_save_size += riscv_stack_align (1 * UNITS_PER_WORD); } /* At the bottom of the frame are any outgoing stack arguments. */ @@ -5282,6 +5290,29 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } + if (regno == RISCV_PROLOGUE_TEMP_REGNUM + && TARGET_HARD_FLOAT + && cfun->machine->interrupt_handler_p + && cfun->machine->frame.fmask) + { + unsigned int fcsr_size = GET_MODE_SIZE (SImode); + if (!epilogue) + { + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + emit_insn (gen_riscv_frcsr (gen_rtx_REG (SImode, RISCV_PROLOGUE_TEMP_REGNUM))); + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, offset, riscv_save_reg); + } + else + { + riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM, offset - fcsr_size, riscv_restore_reg); + emit_insn (gen_riscv_fscsr (gen_rtx_REG (SImode, RISCV_PROLOGUE_TEMP_REGNUM))); + riscv_save_restore_reg (word_mode, regno, offset, fn); + offset -= fcsr_size; + } + continue; + } + riscv_save_restore_reg (word_mode, regno, offset, fn); } diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d8e935cb934..565e8cd27cd 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -78,6 +78,8 @@ (define_c_enum "unspecv" [ UNSPECV_GPR_RESTORE ;; Floating-point unspecs. + UNSPECV_FRCSR + UNSPECV_FSCSR UNSPECV_FRFLAGS UNSPECV_FSFLAGS UNSPECV_FSNVSNAN @@ -3056,6 +3058,17 @@ (define_insn "gpr_restore_return" "" "") +(define_insn "riscv_frcsr" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile [(const_int 0)] UNSPECV_FRCSR))] + "TARGET_HARD_FLOAT || TARGET_ZFINX" + "frcsr\t%0") + +(define_insn "riscv_fscsr" + [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)] + "TARGET_HARD_FLOAT || TARGET_ZFINX" + "fscsr\t%0") + (define_insn "riscv_frflags" [(set (match_operand:SI 0 "register_operand" "=r") (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))] diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-fcsr-1.c b/gcc/testsuite/gcc.target/riscv/interrupt-fcsr-1.c new file mode 100644 index 000..fe49007c936 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/interrupt-fcsr-1.c @@ -0,0 +1,14 @@ +/* Verify that fcsr instructions emitted. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +extern int foo (void); + +void __attribute__ ((interrupt)) +sub (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-times "frcsr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fscsr\t" 1 } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-fcsr-2.c b/gcc/testsuite/gcc.target/riscv/interrupt-fcsr-2.c new file mode 100644 index 000..189d10654e9 --- /dev/null +++
Re: [PATCH] In the pipeline, UNRECOG INSN is not executed in advance if it starts a live range.
> On 5/29/23 04:51, Jin Ma wrote: > >Unrecog insns (such as CLOBBER, USE) does not represent real > > instructions, but in the > > process of pipeline optimization, they will wait for transmission in ready > > list like > > other insns, without considering resource conflicts and cycles. This > > results in a > > multi-issue CPU architecture that can be issued at any time if other > > regular insns > > have resource conflicts or cannot be launched for other reasons. As a > > result, its > > position is advanced in the generated insns sequence, which will affect > > register > > allocation and often lead to more redundant mov instructions. > > > > A simple example: > > https://github.com/majin2020/gcc-test/blob/master/test.c > > This is a function in the dhrystone benchmark. > > > > https://github.com/majin2020/gcc-test/blob/0b08c1a13de9663d7d9aba7539b960ec0607ca24/test.c.299r.sched1 > > This is a log of the pass 'sched1' When issue_rate == 2. Among them, insn > > 13 and 14 are > > much ahead of schedule, which risks generating redundant mov instructions, > > which seems > > unreasonable. > > > > Therefore, I submit patch again on the basis of the last review opinions to > > try to solve > > this problem. > > > > This is the new log of shed1 after patch is added. > > https://github.com/majin2020/gcc-test/commit/efcb43e3369e771bde702955048bfe3f501263dd > > > > gcc/ChangeLog: > > > > * haifa-sched.cc (unrecog_insn_for_forw_only_p): New. > > (prune_ready_list): UNRECOG INSN is not executed in advance if it > > starts a > > live range. > > --- > > gcc/haifa-sched.cc | 44 +++- > > 1 file changed, 39 insertions(+), 5 deletions(-) > > > > diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc > > index 2c881ede0ec..205680a4936 100644 > > --- a/gcc/haifa-sched.cc > > +++ b/gcc/haifa-sched.cc > > @@ -765,6 +765,23 @@ real_insn_for_shadow (rtx_insn *insn) > > return pair->i1; > > } > > > > +/* Return true if INSN is unrecog that starts a live range. */ > I would rewrite this as > > /* Return TRUE if INSN (a USE or CLOBBER) starts a new live > range, FALSE otherwise. */ Ok. > > + > > +static bool > > +unrecog_insn_for_forw_only_p (rtx_insn *insn) > I would call this "use_or_clobber_starts_range_p" or something like that. Ok. > > +{ > > + if (insn && !INSN_P (insn) && recog_memoized (insn) >= 0) > > +return false; > I would drop the test that INSN is not NULL in this test. There's no > way it can ever be NULL here. > > If you really want to check that, then I'd do something like > > gcc_assert (INSN); > > Instead of checking it in that condition. Ok. > > @@ -6320,11 +6337,28 @@ prune_ready_list (state_t temp_state, bool > > first_cycle_insn_p, > > } > > else if (recog_memoized (insn) < 0) > > { > > - if (!first_cycle_insn_p > > - && (GET_CODE (PATTERN (insn)) == ASM_INPUT > > - || asm_noperands (PATTERN (insn)) >= 0)) > > - cost = 1; > > - reason = "asm"; > > + if (GET_CODE (PATTERN (insn)) == ASM_INPUT > > + || asm_noperands (PATTERN (insn)) >= 0) > > + { > > + reason = "asm"; > > + if (!first_cycle_insn_p) > > + cost = 1; > > + } > > + else if (unrecog_insn_for_forw_only_p (insn)) > > + { > > + reason = "unrecog insn"; > > + if (!first_cycle_insn_p) > > + cost = 1; > > + else > > + { > > + int j = i; > > + while (n > ++j) > > + if (!unrecog_insn_for_forw_only_p (ready_element > > (, j))) > > + break; > > + > > + cost = (j == n) ? 0 : 1; > > + } > Why do you need a different cost based on what's in the ready list? > Isn't the only property we're looking for whether or not the USE/CLOBBER > opens a live range? > > Jeff For this, I found that if I only look for the USE/CLOBBER that opens a live range, when there is only the USE/CLOBBERs left in the ready list, there will be an infinite loop, because we will always postpone it to the next cycle(cost = 1), causing it to never be emitted and always be in the ready list. So I think (may not be correct) when there is only the USE/CLOBBERs left in the ready list, the cost should be set to 0, and the USE/CLOBBER can be emitted immediately. Maybe there's a better way?
Re: [PATCH] In the pipeline, UNRECOG INSN is not executed in advance if it starts a live range.
ping: https://gcc.gnu.org/pipermail/gcc-patches/2023-May/619951.html Ref: http://patchwork.ozlabs.org/project/gcc/patch/20230323080734.423-1-ji...@linux.alibaba.com/
[RFC] RISC-V: Support risc-v bfloat16 This patch support bfloat16 in riscv like x86_64 and arm.
hi, Are there any new developments about Zfb? Are there any plans to implement the Zvfbfmin and Zvfbfwma expansion? I see that Zfb is being reviewed in llvm, maybe we should do the same on gcc. Ref: https://reviews.llvm.org/D151313 https://reviews.llvm.org/D150929
[PATCH] RISC-V: Handle no_insn in TARGET_SCHED_VARIABLE_ISSUE.
Reference: https://github.com/gcc-mirror/gcc/commit/d0bc0cb66bcb0e6a5a5a31a9e900e8ccc98e34e5 RISC-V should also be implemented to handle no_insn patterns for pipelining. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_sched_variable_issue): New function. (TARGET_SCHED_VARIABLE_ISSUE): New macro. --- gcc/config/riscv/riscv.cc | 21 + 1 file changed, 21 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3954fc07a8b..559fa9cd7e0 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6225,6 +6225,24 @@ riscv_issue_rate (void) return tune_param->issue_rate; } +/* Implement TARGET_SCHED_VARIABLE_ISSUE. */ + +static int +riscv_sched_variable_issue (FILE *, int, rtx_insn *insn, int more) +{ + if (DEBUG_INSN_P (insn)) +return more; + + rtx_code code = GET_CODE (PATTERN (insn)); + if (code == USE || code == CLOBBER) +return more; + + if (get_attr_type (insn) == TYPE_UNKNOWN) +return more; + + return more - 1; +} + /* Auxiliary function to emit RISC-V ELF attribute. */ static void riscv_emit_attribute () @@ -7671,6 +7689,9 @@ riscv_vectorize_related_mode (machine_mode vector_mode, scalar_mode element_mode #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE riscv_issue_rate +#undef TARGET_SCHED_VARIABLE_ISSUE +#define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue + #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall -- 2.17.1
[PATCH] In the pipeline, UNRECOG INSN is not executed in advance if it starts a live range.
Unrecog insns (such as CLOBBER, USE) does not represent real instructions, but in the process of pipeline optimization, they will wait for transmission in ready list like other insns, without considering resource conflicts and cycles. This results in a multi-issue CPU architecture that can be issued at any time if other regular insns have resource conflicts or cannot be launched for other reasons. As a result, its position is advanced in the generated insns sequence, which will affect register allocation and often lead to more redundant mov instructions. A simple example: https://github.com/majin2020/gcc-test/blob/master/test.c This is a function in the dhrystone benchmark. https://github.com/majin2020/gcc-test/blob/0b08c1a13de9663d7d9aba7539b960ec0607ca24/test.c.299r.sched1 This is a log of the pass 'sched1' When issue_rate == 2. Among them, insn 13 and 14 are much ahead of schedule, which risks generating redundant mov instructions, which seems unreasonable. Therefore, I submit patch again on the basis of the last review opinions to try to solve this problem. This is the new log of shed1 after patch is added. https://github.com/majin2020/gcc-test/commit/efcb43e3369e771bde702955048bfe3f501263dd gcc/ChangeLog: * haifa-sched.cc (unrecog_insn_for_forw_only_p): New. (prune_ready_list): UNRECOG INSN is not executed in advance if it starts a live range. --- gcc/haifa-sched.cc | 44 +++- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 2c881ede0ec..205680a4936 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -765,6 +765,23 @@ real_insn_for_shadow (rtx_insn *insn) return pair->i1; } +/* Return true if INSN is unrecog that starts a live range. */ + +static bool +unrecog_insn_for_forw_only_p (rtx_insn *insn) +{ + if (insn && !INSN_P (insn) && recog_memoized (insn) >= 0) +return false; + + if ((GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == USE) + && !sd_lists_empty_p (insn, SD_LIST_FORW) + && sd_lists_empty_p (insn, SD_LIST_BACK)) +return true; + + return false; +} + /* For a pair P of insns, return the fixed distance in cycles from the first insn after which the second must be scheduled. */ static int @@ -6320,11 +6337,28 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p, } else if (recog_memoized (insn) < 0) { - if (!first_cycle_insn_p - && (GET_CODE (PATTERN (insn)) == ASM_INPUT - || asm_noperands (PATTERN (insn)) >= 0)) - cost = 1; - reason = "asm"; + if (GET_CODE (PATTERN (insn)) == ASM_INPUT + || asm_noperands (PATTERN (insn)) >= 0) + { + reason = "asm"; + if (!first_cycle_insn_p) + cost = 1; + } + else if (unrecog_insn_for_forw_only_p (insn)) + { + reason = "unrecog insn"; + if (!first_cycle_insn_p) + cost = 1; + else + { + int j = i; + while (n > ++j) + if (!unrecog_insn_for_forw_only_p (ready_element (, j))) + break; + + cost = (j == n) ? 0 : 1; + } + } } else if (sched_pressure != SCHED_PRESSURE_NONE) { -- 2.17.1
Re: [PATCH] RISC-V: Add the option "-mdisable-multilib-check" to avoid multilib checks breaking the compilation.
> > > > When testing a extension, it is often necessary for a certain program > > > > not to > > > > need some kind of extension, such as the bitmanip extension, to > > > > evaluate the > > > > performance or codesize of the extension. However, the current multilib > > > > rules > > > > will report an error when it is not a superset of the MULTILIB_REQUIRED > > > > list, > > > > which will cause the program to be unable to link normally, thus > > > > failing to > > > > achieve the expected purpose. > > > > > > Hmm, I have troubles understanding what is going on here. What do you > > > refer to by saying: "it is not a superset of the MULTILIB_REQUIRED list"? > > > > This is a new matching rule added by kito for the multilib of riscv: > > https://github.com/gcc-mirror/gcc/commit/d72ca12b846a9f5c01674b280b1817876c77888f > > > > > There should be no problem with linking compiled modules together that > > > make use of different extensions, with the static linker figuring out the > > > combined set of extensions actually required at run time for the program > > > loader to consider, as long as the modules do not have contradicting > > > requirements, e.g. big vs little endianness or RV32 vs RV64. > > > > > > Can you give me a specific example (compilation options and multilibs > > > available) of a failure you refer to? > > > > A simple example: > > 1. Use "--disable-multilib --with-abi =lp64d --with-arch > > =rv64imafdc_zba_zbb_zbc_zbs" > > to build the toolchain". > > 2. Use the toolchain to test the impact of zba_zbb_zbc_zbs extensions on the > > performance and codesize of some functions or files in the program. > > > > In this case, I may need to use the command "-mabi=lp64d -march=rv64imafdc" > > for > > the compilation of a specific .c file in the program, which will cause the > > link to > > fail and throw the following error: "FATAL ERROR: Can't find suitable > > multilib set for > > '-march=rv64imafdc'/'-mabi=lp64d'". This does not satisfy the purpose of > > the test. > > I feel this case should be build with --with-arch =rv64imafdc and test > with -march=rv64imafdc and -march=rv64imafdc_zba_zbb_zbc_zbs, > but anyway I am OK with option :P Yes, but with "--with-arch=rv64imafdc" building toolchains, the library will not contain zba_zbb_zbc_zbs extensions, so how can we quickly and easily eliminate the impact of not using zba_zbb_zbc_zbs extensions in a certain program on program performance and codesize? Although-mno-multilib-check is unsafe, it is useful during the development and testing phases. > > > > > I think this needs an option to turn off this check. Users sometimes, just > > as > > gcc uses the default multilib when it does not match the appropriate > > multilib, > > do not need the `security lock`, and should already understand the risks > > of using this option. > > > > > Is this something that could be solved without resorting to a possibly > > > dangerous hack, by making use of MULTILIB_REUSE? > > > > Regarding the use of MULTILIB_REUSE, I think kito's patch has already been > > explained > > and is currently implemented according to the new rules. > > https://github.com/gcc-mirror/gcc/commit/5ca9980fc86242505ffdaaf62bca1fd5db26550b > > > > > > > > Maciej > > > > Thanks, > > Jin
Re: [PATCH] RISC-V: Add the option "-mdisable-multilib-check" to avoid multilib checks breaking the compilation.
> > When testing a extension, it is often necessary for a certain program not to > > need some kind of extension, such as the bitmanip extension, to evaluate the > > performance or codesize of the extension. However, the current multilib > > rules > > will report an error when it is not a superset of the MULTILIB_REQUIRED > > list, > > which will cause the program to be unable to link normally, thus failing to > > achieve the expected purpose. > > Hmm, I have troubles understanding what is going on here. What do you > refer to by saying: "it is not a superset of the MULTILIB_REQUIRED list"? This is a new matching rule added by kito for the multilib of riscv: https://github.com/gcc-mirror/gcc/commit/d72ca12b846a9f5c01674b280b1817876c77888f > There should be no problem with linking compiled modules together that > make use of different extensions, with the static linker figuring out the > combined set of extensions actually required at run time for the program > loader to consider, as long as the modules do not have contradicting > requirements, e.g. big vs little endianness or RV32 vs RV64. > > Can you give me a specific example (compilation options and multilibs > available) of a failure you refer to? A simple example: 1. Use "--disable-multilib --with-abi =lp64d --with-arch =rv64imafdc_zba_zbb_zbc_zbs" to build the toolchain". 2. Use the toolchain to test the impact of zba_zbb_zbc_zbs extensions on the performance and codesize of some functions or files in the program. In this case, I may need to use the command "-mabi=lp64d -march=rv64imafdc" for the compilation of a specific .c file in the program, which will cause the link to fail and throw the following error: "FATAL ERROR: Can't find suitable multilib set for '-march=rv64imafdc'/'-mabi=lp64d'". This does not satisfy the purpose of the test. I think this needs an option to turn off this check. Users sometimes, just as gcc uses the default multilib when it does not match the appropriate multilib, do not need the `security lock`, and should already understand the risks of using this option. > Is this something that could be solved without resorting to a possibly > dangerous hack, by making use of MULTILIB_REUSE? Regarding the use of MULTILIB_REUSE, I think kito's patch has already been explained and is currently implemented according to the new rules. https://github.com/gcc-mirror/gcc/commit/5ca9980fc86242505ffdaaf62bca1fd5db26550b > > Maciej Thanks, Jin
[PATCH] RISC-V: Add the option "-mno-multilib-check" to disable multilib checks.
When testing a extension, it is often necessary for a certain program not to need some kind of extension, such as the bitmanip extension, to evaluate the performance or codesize of the extension. However, the current multilib rules will report an error when it is not a superset of the MULTILIB_REQUIRED list, which will cause the program to be unable to link normally, thus failing to achieve the expected purpose. Therefore, the compilation option is added to avoi interruption of compilation by multilib checks. gcc/ChangeLog: * config/riscv/elf.h (LIB_SPEC): Do not run riscv_multi_lib_check() when -mno-multilib-check * config/riscv/riscv.opt: New. * doc/invoke.texi: New. --- gcc/config/riscv/elf.h | 2 +- gcc/config/riscv/riscv.opt | 5 + gcc/doc/invoke.texi| 9 - 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h index 4b7e5c988ca..cb3ac903a3d 100644 --- a/gcc/config/riscv/elf.h +++ b/gcc/config/riscv/elf.h @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #undef LIB_SPEC #define LIB_SPEC \ "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group " \ - "%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()" + "%{!mno-multilib-check:%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()}" #undef STARTFILE_SPEC #define STARTFILE_SPEC "crt0%O%s crtbegin%O%s" diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 63d4710cb15..41a817eb774 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -295,3 +295,8 @@ Enum(riscv_autovec_lmul) String(m8) Value(RVV_M8) -param=riscv-autovec-lmul= Target RejectNegative Joined Enum(riscv_autovec_lmul) Var(riscv_autovec_lmul) Init(RVV_M1) -param=riscv-autovec-lmul= Set the RVV LMUL of auto-vectorization in the RISC-V port. + +mno-multilib-check +Target RejectNegative +Disable multilib checking; use the default multilib if a compatible +one is not found. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ee78591c73e..bc1ab34d5a7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1228,7 +1228,8 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} -mstack-protector-guard-offset=@var{offset} -mcsr-check -mno-csr-check --minline-atomics -mno-inline-atomics} +-minline-atomics -mno-inline-atomics +-mno-multilib-check} @emph{RL78 Options} @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @@ -29131,6 +29132,12 @@ which register to use as base register for reading the canary, and from what offset from that base register. There is no default register or offset as this is entirely for use within the Linux kernel. + +@opindex mno-multilib-check +@item -mno-multilib-check +Disable the check on the correctness of multilib. When the correct multilib +is notmatched, the default multilib will be used. This has certain risks +and is not recommended in a production environment. @end table @node RL78 Options -- 2.17.1
[PATCH] RISC-V: In pipeline scheduling, insns should not be fusion in different BB blocks.
When the last insn1 of BB1 and the first insn2 of BB2 are fusion, insn2 will clear all dependencies in the function chain_to_prev_insn, resulting in insn2 may mov to any BB, and the program calculation result is wrong. gcc/ChangeLog: * sched-deps.cc (sched_macro_fuse_insns): Insns should not be fusion in different BB blocks --- gcc/sched-deps.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/sched-deps.cc b/gcc/sched-deps.cc index 2aa6623ad2e..998fe930804 100644 --- a/gcc/sched-deps.cc +++ b/gcc/sched-deps.cc @@ -2833,7 +2833,7 @@ sched_macro_fuse_insns (rtx_insn *insn) compile time complexity. */ if (DEBUG_INSN_P (insn)) return; - prev = prev_nonnote_nondebug_insn (insn); + prev = prev_nonnote_nondebug_insn_bb (insn); if (!prev) return; -- 2.17.1
Re: [PATCH] Fix type error of 'switch (SUBREG_BYTE (op)).'
> > On 5/17/23 03:03, Jin Ma wrote: > >> For example: > >> (define_insn "mov_lowpart_sidi2" > >>[(set (match_operand:SI0 "register_operand" "=r") > >> (subreg:SI (match_operand:DI 1 "register_operand" " r") 0))] > >>"TARGET_64BIT" > >>"mov\t%0,%1") > >> > >> (define_insn "mov_highpart_sidi2" > >>[(set (match_operand:SI0 "register_operand" "=r") > >> (subreg:SI (match_operand:DI 1 "register_operand" " r") 1))] > >>"TARGET_64BIT" > >>"movh\t%0,%1") > >> > >> When defining the above patterns, the generated file insn-recog.cc will > >> appear 'switch (SUBREG_BYTE (op))', but since the return value of > >> SUBREG_BYTE is poly_uint16_pod, the following error will occur: > >> "error: switch quantity not an integer". > >> > >> gcc/ChangeLog: > >> > >> * genrecog.cc (print_nonbool_test): Fix type error of > >> 'switch (SUBREG_BYTE (op))'. > > Thanks. Installed. > > We shouldn't add to_constant just because it's a convenient > way of getting rid of errors :) There has to be a good reason > in principle why the value is known at compile time. > > So I think this should be reverted. Nothing guarantees that > SUBREG_BYTEs are constant on AArch64 and RISC-V. And for SVE > it's common for them not to be. > > If we want to support the above, I think we need to make the > generator use known_eq instead. > > The patterns don't look right though. An SI subreg of a DI > can't have a SUBREG_BYTE of 1. And the lowpart SUBREG_BYTE > depends on endianness. So I think a better way of writing > the lowpart pattern above is to use subreg_lowpart_operator > (which riscv already has). > > The high part can't be done using subregs though. > > Thanks, > Richard I'm trying to understand what you mean. The return value of the SUBREG_BYTE is poly_uint16_pod. When the value of the NUM_POLY_INT_COEFFS is 2, using to_constant () to convert to a constant may lose coeffs[1], right? I agree with this, we can revert this first, but this problem always exists, and it seems that we need to find other suitable ways to solve this error. Thanks, Jin
[PATCH] RISC-V: Add the option "-mdisable-multilib-check" to avoid multilib checks breaking the compilation.
When testing a extension, it is often necessary for a certain program not to need some kind of extension, such as the bitmanip extension, to evaluate the performance or codesize of the extension. However, the current multilib rules will report an error when it is not a superset of the MULTILIB_REQUIRED list, which will cause the program to be unable to link normally, thus failing to achieve the expected purpose. Therefore, the compilation option is added to avoid riscv_multi_lib_check() interruption of compilation. gcc/ChangeLog: * config/riscv/elf.h (LIB_SPEC): Do not run riscv_multi_lib_check() when -mdisable-multilib-check. * config/riscv/riscv.opt: New. --- gcc/config/riscv/elf.h | 2 +- gcc/config/riscv/riscv.opt | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h index 4b7e5c988ca..afde1b12d36 100644 --- a/gcc/config/riscv/elf.h +++ b/gcc/config/riscv/elf.h @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #undef LIB_SPEC #define LIB_SPEC \ "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group " \ - "%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()" + "%{!mdisable-multilib-check:%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()}" #undef STARTFILE_SPEC #define STARTFILE_SPEC "crt0%O%s crtbegin%O%s" diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 63d4710cb15..9940a24a7f9 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -295,3 +295,7 @@ Enum(riscv_autovec_lmul) String(m8) Value(RVV_M8) -param=riscv-autovec-lmul= Target RejectNegative Joined Enum(riscv_autovec_lmul) Var(riscv_autovec_lmul) Init(RVV_M1) -param=riscv-autovec-lmul= Set the RVV LMUL of auto-vectorization in the RISC-V port. + +mdisable-multilib-check +Target Bool Var(riscv_disable_multilib_check) Init(0) +Disable multilib checking by riscv_multi_lib_check(). -- 2.17.1
[PATCH] RISC-V: Remove trailing spaces on lines.
gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Remove trailing spaces on lines. * config/riscv/riscv.cc (riscv_legitimize_move): Likewise. * config/riscv/riscv.h (enum reg_class): Likewise. * config/riscv/riscv.md: Likewise. --- gcc/common/config/riscv/riscv-common.cc | 2 +- gcc/config/riscv/riscv.cc | 6 +++--- gcc/config/riscv/riscv.h| 2 +- gcc/config/riscv/riscv.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 3a285dfbff0..e46ddf78132 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -104,7 +104,7 @@ static const riscv_implied_info_t riscv_implied_info[] = {"zfh", "zfhmin"}, {"zfhmin", "f"}, - + {"zhinx", "zhinxmin"}, {"zhinxmin", "zfinx"}, diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index b52e613c629..1eb3e142905 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2166,8 +2166,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) } return true; } - /* Expand - (set (reg:QI target) (mem:QI (address))) + /* Expand + (set (reg:QI target) (mem:QI (address))) to (set (reg:DI temp) (zero_extend:DI (mem:QI (address (set (reg:QI target) (subreg:QI (reg:DI temp) 0)) @@ -2182,7 +2182,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) temp_reg = gen_reg_rtx (word_mode); zero_extend_p = (LOAD_EXTEND_OP (mode) == ZERO_EXTEND); - emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode, + emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode, zero_extend_p)); riscv_emit_move (dest, gen_lowpart (mode, temp_reg)); return true; diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index f74b70de562..70087d011f4 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -575,7 +575,7 @@ enum reg_class #define POLY_SMALL_OPERAND_P(POLY_VALUE) \ (POLY_VALUE.is_constant () ? \ SMALL_OPERAND (POLY_VALUE.to_constant ()) : false) - + /* True if VALUE can be loaded into a register using LUI. */ #define LUI_OPERAND(VALUE) \ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index c5cf3af9868..f47ebb3a829 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -222,7 +222,7 @@ (define_attr "ext" "base,f,d,vector" (define_attr "ext_enabled" "no,yes" (cond [(eq_attr "ext" "base") (const_string "yes") - + (and (eq_attr "ext" "f") (match_test "TARGET_HARD_FLOAT")) (const_string "yes") @@ -258,7 +258,7 @@ (define_attr "enabled" "no,yes" ;; logical integer logical instructions ;; shift integer shift instructions ;; slt set less than instructions -;; imulinteger multiply +;; imulinteger multiply ;; idivinteger divide ;; moveinteger register move (addi rd, rs1, 0) ;; fmove floating point register move -- 2.17.1
[PATCH] Fix type error of 'switch (SUBREG_BYTE (op)).'
For example: (define_insn "mov_lowpart_sidi2" [(set (match_operand:SI0 "register_operand" "=r") (subreg:SI (match_operand:DI 1 "register_operand" " r") 0))] "TARGET_64BIT" "mov\t%0,%1") (define_insn "mov_highpart_sidi2" [(set (match_operand:SI0 "register_operand" "=r") (subreg:SI (match_operand:DI 1 "register_operand" " r") 1))] "TARGET_64BIT" "movh\t%0,%1") When defining the above patterns, the generated file insn-recog.cc will appear 'switch (SUBREG_BYTE (op))', but since the return value of SUBREG_BYTE is poly_uint16_pod, the following error will occur: "error: switch quantity not an integer". gcc/ChangeLog: * genrecog.cc (print_nonbool_test): Fix type error of 'switch (SUBREG_BYTE (op))'. --- gcc/genrecog.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/genrecog.cc b/gcc/genrecog.cc index 6dd375da5e3..04a5533ca4b 100644 --- a/gcc/genrecog.cc +++ b/gcc/genrecog.cc @@ -4619,6 +4619,7 @@ print_nonbool_test (output_state *os, const rtx_test ) printf ("SUBREG_BYTE ("); print_test_rtx (os, test); printf (")"); + printf (".to_constant ()"); break; case rtx_test::WIDE_INT_FIELD: -- 2.17.1
[PATCH v9] RISC-V: Add the 'zfa' extension, version 0.2
This patch adds the 'Zfa' extension for riscv, which is based on: https://github.com/riscv/riscv-isa-manual/commits/zfb The binutils-gdb for 'Zfa' extension: https://sourceware.org/pipermail/binutils/2023-April/127060.html 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 2,3, and 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 that no implementation is required. 3, The instructions FMINM and FMAXM correspond to C23 library function fminimum and fmaximum. Therefore, this patch has simply implemented the pattern of fminm3 and fmaxm3 to prepare for later. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add zfa extension version. * config/riscv/constraints.md (zfli): Constrain the floating point number that the instructions FLI.H/S/D can load. * config/riscv/iterators.md (ceil): New. (rup): New. * config/riscv/riscv-opts.h (MASK_ZFA): New. (TARGET_ZFA): New. * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_fli): New. * config/riscv/riscv.cc (riscv_float_const_rtx_index_for_fli): New. (riscv_cannot_force_const_mem): If instruction FLI.H/S/D can be used, memory is not applicable. (riscv_const_insns): Likewise. (riscv_legitimize_const_move): Likewise. (riscv_split_64bit_move_p): If instruction FLI.H/S/D can be used, no split is required. (riscv_split_doubleword_move): Likewise. (riscv_output_move): Output the mov instructions in zfa extension. (riscv_print_operand): Output the floating-point value of the FLI.H/S/D immediate in assembly (riscv_secondary_memory_needed): Likewise. * config/riscv/riscv.md (fminm3): New. (fmaxm3): New. (movsidf2_low_rv32): New. (movsidf2_high_rv32): New. (movdfsisi3_rv32): New. (f_quiet4_zfa): Likewise. 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 | 21 +- 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 | 204 +- gcc/config/riscv/riscv.md | 145 +++-- .../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 16 files changed, 719 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv32.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-rv32.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/config/riscv/riscv-common.cc index 3a285dfbff0..550f6796e98 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[] = {"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
Re: [PATCH v8] RISC-V: Add the 'zfa' extension, version 0.2.
On 4/19/23 03:57, 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/1f038182810727f5feca311072e630d6baac51da > > 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, and 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 Right. I think the goal right now is to get the bulk of this reviewed now. Ideally we'll get to the point where the only outstanding issue is the interface between the assembler & gcc. I will send a new version referring to the latest binutils(v5) in the near future: https://sourceware.org/pipermail/binutils/2023-April/127060.html > > 2, According to riscv-spec, "The FCVTMO D.W.D instruction was added principally to >accelerate the processing of JavaScript Numbers.", so it seems that no implementation >is required. Fair enough. There's seems to be a general desire to wire up builtins for many things that aren't directly usable by the compiler. So consider such a change as a follow-up. I don't think something like this should hold up the blk of Zfa. > > 3, The instructions FMINM and FMAXM correspond to C23 library function fminimum and fmaximum. >Therefore, this patch has simply implemented the pattern of fminm3 and >fmaxm3 to prepare for later. Sounds good. > > gcc/ChangeLog: > > * common/config/riscv/riscv-common.cc: Add zfa extension version. >* config/riscv/constraints.md (Zf): Constrain the floating point number that the >instructions FLI.H/S/D can load. >((TARGET_XTHEADFMV || TARGET_ZFA) ? FP_REGS : NO_REGS): enable FMVP.D.X and FMVH.X.D. >* config/riscv/iterators.md (ceil): New. >* config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_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 extension. >(riscv_print_operand): Output the floating-point value of the 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. > > 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 `fli` in zfa." > + (and (match_code "const_double") > + (match_test "(riscv_float_const_rtx_index_for_fli (op) != -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.") I think Christoph had good suggestions on the constraints. So let's go with his suggestions. You might consider a follow-up patch where you use negation of one of the predefined constants for synthesis. I would not be surprised at all if that's as efficient on some cores as loading the negated constants out of the constant pool. But
[PATCH v8] RISC-V: Add the 'zfa' extension, version 0.2.
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/1f038182810727f5feca311072e630d6baac51da 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, and 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 that no implementation is required. 3, The instructions FMINM and FMAXM correspond to C23 library function fminimum and fmaximum. Therefore, this patch has simply implemented the pattern of fminm3 and fmaxm3 to prepare for later. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add zfa extension version. * config/riscv/constraints.md (Zf): Constrain the floating point number that the instructions FLI.H/S/D can load. ((TARGET_XTHEADFMV || TARGET_ZFA) ? FP_REGS : NO_REGS): enable FMVP.D.X and FMVH.X.D. * config/riscv/iterators.md (ceil): New. * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_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 extension. (riscv_print_operand): Output the floating-point value of the 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-rv32.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-rv32.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/config/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[] = {"zfh", ISA_SPEC_CLASS_NONE, 1, 0}, {"zfhmin",ISA_SPEC_CLASS_NONE, 1, 0}, + {"zfa", ISA_SPEC_CLASS_NONE, 0, 2}, +
[PATCH] Fixed typo.
gcc/ada/ChangeLog: * gcc-interface/utils.cc (unchecked_convert): Fixed typo. --- gcc/ada/gcc-interface/utils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 392ec0b7f4e..0c4f8b90c8e 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -5543,7 +5543,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) } } - /* Likewise if we are converting from a fixed-szie type to a type with self- + /* Likewise if we are converting from a fixed-size type to a type with self- referential size. We use the max size to do the padding in this case. */ else if (!INDIRECT_REF_P (expr) && TREE_CODE (expr) != STRING_CST -- 2.17.1
[PATCH] RISC-V: Adjust the parsing order of extensions to be consistent with riscv-spec and binutils.
The current order of gcc and binutils parsing extensions is inconsistent. According to latest risc-v spec, the canonical order in which extension names must appear in the name string specified in Table 29.1 is different from before. In the latest table, non-standard extensions must be listed after all standard extensions. To keep consistent, we now change the parsing order. Related llvm patch links: https://reviews.llvm.org/D148315 gcc/ChangeLog: * common/config/riscv/riscv-common.cc (multi_letter_subset_rank): Swap the order of z-extensions and s-extensions. (riscv_subset_list::parse): Likewise. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-5.c: Likewise. --- gcc/common/config/riscv/riscv-common.cc | 12 ++-- gcc/testsuite/gcc.target/riscv/arch-5.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 2fc0f8bffc1..309a52def75 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -398,10 +398,10 @@ multi_letter_subset_rank (const std::string ) char multiletter_class = subset[0]; switch (multiletter_class) { -case 's': +case 'z': high_order = 0; break; -case 'z': +case 's': high_order = 1; break; case 'x': @@ -1121,14 +1121,14 @@ riscv_subset_list::parse (const char *arch, location_t loc) if (p == NULL) goto fail; - /* Parsing supervisor extension. */ - p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension"); + /* Parsing sub-extensions. */ + p = subset_list->parse_multiletter_ext (p, "z", "sub-extension"); if (p == NULL) goto fail; - /* Parsing sub-extensions. */ - p = subset_list->parse_multiletter_ext (p, "z", "sub-extension"); + /* Parsing supervisor extension. */ + p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension"); if (p == NULL) goto fail; diff --git a/gcc/testsuite/gcc.target/riscv/arch-5.c b/gcc/testsuite/gcc.target/riscv/arch-5.c index b945a643cc1..8258552214f 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-5.c +++ b/gcc/testsuite/gcc.target/riscv/arch-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv32isabc_zfoo_xbar -mabi=ilp32" } */ +/* { dg-options "-march=rv32i_zfoo_sabc_xbar -mabi=ilp32" } */ int foo() { } -- 2.17.1
[PATCH] In the ready lists of pipeline, put unrecog insns (such as CLOBBER, USE) at the latest to issue.
Unrecog insns (such as CLOBBER, USE) does not represent real instructions, but in the process of pipeline optimization, they will wait for transmission in ready list like other insns, without considering resource conflicts and cycles. This results in a multi-issue CPU architecture that can be issued at any time if other regular insns have resource conflicts or cannot be launched for other reasons. As a result, its position is advanced in the generated insns sequence, which will affect register allocation and often lead to more redundant mov instructions. gcc/ChangeLog: * haifa-sched.cc (prune_ready_list): Consider unrecog insns(CLOBBER and USE) in pruning ready lists. --- gcc/haifa-sched.cc | 8 1 file changed, 8 insertions(+) diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 48b53776fa9..72c4c44da76 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -6318,6 +6318,14 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p, cost = 1; reason = "not a shadow"; } + else if (recog_memoized (insn) < 0 + && (GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == USE)) + { + if (!first_cycle_insn_p) + cost = 1; + reason = "unrecog insn"; + } else if (recog_memoized (insn) < 0) { if (!first_cycle_insn_p -- 2.17.1
[PATCH v6] RISC-V: Add support for experimental zfa extension.
This patch adds the 'Zfa' extension for riscv, which is based on: https://github.com/riscv/riscv-isa-manual/commit/d74d99e22d5f68832f70982d867614e2149a3bd7 latest 'Zfa' change on the master branch of the RISC-V ISA Manual as of this writing. The Wiki Page (details): https://github.com/a4lg/binutils-gdb/wiki/riscv_zfa The binutils-gdb for 'Zfa' extension: https://sourceware.org/pipermail/binutils/2022-September/122938.html Implementation of zfa extension on LLVM: https://reviews.llvm.org/rGc0947dc44109252fcc0f68a542fc6ef250d4d3a9 There are three points that need to be discussed here. 1. According to riscv-spec, "The FCVTMO D.W.D instruction was added principally to accelerate the processing of JavaScript Numbers.", so it seems that no implementation is required in the compiler. 2. The FROUND and FROUNDN instructions in this patch use related functions in the math library, such as round, floor, ceil, etc. Since there is no interface for half-precision in the math library, the instructions FROUN D.H and FROUNDN X.H have not been implemented for the time being. Is it necessary to add a built-in interface belonging to riscv such as __builtin_roundhf or __builtin_roundf16 to generate half floating point instructions? 3. As far as I know, FMINM and FMAXM instructions correspond to C23 library function fminimum and fmaximum. Therefore, I have not dealt with such instructions for the time being, but have simply implemented the pattern of fminm3 and fmaxm3. Is it necessary to add a built-in interface belonging to riscv such as__builtin_fminm to generate half floating-point instructions? gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add zfa extension. * config/riscv/constraints.md (Zf): Constrain the floating point number that the FLI instruction can load. * config/riscv/iterators.md (round_pattern): New. * config/riscv/predicates.md: Predicate the floating point number that the FLI instruction can load. * config/riscv/riscv-opts.h (MASK_ZFA): New. (TARGET_ZFA): New. * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_fli): Get the index of the floating-point number that the FLI instruction can load. * config/riscv/riscv.cc (find_index_in_array): New. (riscv_float_const_rtx_index_for_fli): New. (riscv_cannot_force_const_mem): Likewise. (riscv_const_insns): Likewise. (riscv_legitimize_const_move): Likewise. (riscv_split_64bit_move_p): Exclude floating point numbers that can be loaded by FLI instructions. (riscv_output_move): Likewise. (riscv_memmodel_needs_release_fence): Likewise. (riscv_print_operand): Likewise. (riscv_secondary_memory_needed): Likewise. * config/riscv/riscv.h (GP_REG_RTX_P): New. * config/riscv/riscv.md (fminm3): New. (fmaxm3): New. (2): New. (rint2): New. (f_quiet4_zfa): 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 | 7 + gcc/config/riscv/iterators.md | 5 + gcc/config/riscv/predicates.md| 4 + 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 + 18 files changed, 654 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq-rv32.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
[PATCH] RISC-V: Don't report an error until the link phase if suitable multilib isn't found.
When suitable multilib isn't found, an error is not reported until the link period, which is inconsistent with the result of compiling option `-print-multi-directory`. For example, when suitable multilib isn't found, the return result of `-print-multi-directory` is the default value '.', while the actual execution result is an error during the link phase. This is not very reasonable. I think the error should be reported in advance, so that the compilation option `-print-multi-directory` will also report an error. The two should be consistent, either reporting errors or using default values. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_compute_multilib): report an error if suitable multilib isn't found. (struct riscv_multi_lib_info_t): Delet. (riscv_multi_lib_check): Likewise. * config/riscv/elf.h (LIB_SPEC): Likewise. * config/riscv/riscv.h (riscv_multi_lib_check): Likewise. (EXTRA_SPEC_FUNCTIONS): Likewise. --- gcc/common/config/riscv/riscv-common.cc | 25 + gcc/config/riscv/elf.h | 3 +-- gcc/config/riscv/riscv.h| 4 +--- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index ebc1ed7d7e4..3f27ecf4b3c 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -274,9 +274,6 @@ struct riscv_multi_lib_info_t { const std::vector &); }; -/* Flag for checking if there is no suitable multi-lib found. */ -static bool riscv_no_matched_multi_lib; - /* Used for record value of -march and -mabi. */ static std::string riscv_current_arch_str; static std::string riscv_current_abi_str; @@ -1396,21 +1393,6 @@ riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED, return xasprintf ("-march=%s", arch.c_str()); } -/* Report error if not found suitable multilib. */ -const char * -riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED, - const char **argv ATTRIBUTE_UNUSED) -{ - if (riscv_no_matched_multi_lib) -fatal_error ( - input_location, - "Cannot find suitable multilib set for %<-march=%s%>/%<-mabi=%s%>", - riscv_current_arch_str.c_str (), - riscv_current_abi_str.c_str ()); - - return ""; -} - /* We only override this in bare-metal toolchain. */ #ifdef RISCV_USE_CUSTOMISED_MULTI_LIB @@ -1583,7 +1565,6 @@ riscv_compute_multilib ( const char *this_path; size_t this_path_len; bool result; - riscv_no_matched_multi_lib = false; riscv_subset_list *subset_list = NULL; std::vector multilib_infos; @@ -1709,7 +1690,11 @@ riscv_compute_multilib ( if (best_match_multi_lib == -1) { - riscv_no_matched_multi_lib = true; + fatal_error ( + input_location, + "Cannot find suitable multilib set for %<-march=%s%>/%<-mabi=%s%>", + riscv_current_arch_str.c_str (), + riscv_current_abi_str.c_str ()); return multilib_dir; } else diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h index a725c00b637..7b8dc29d4cb 100644 --- a/gcc/config/riscv/elf.h +++ b/gcc/config/riscv/elf.h @@ -28,8 +28,7 @@ along with GCC; see the file COPYING3. If not see Handle the circular dependence between libc and libgloss. */ #undef LIB_SPEC #define LIB_SPEC \ - "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group " \ - "%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()" + "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group" #undef STARTFILE_SPEC #define STARTFILE_SPEC "crt0%O%s crtbegin%O%s" diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 5bc7f2f467d..b8fa5f022db 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -46,13 +46,11 @@ along with GCC; see the file COPYING3. If not see extern const char *riscv_expand_arch (int argc, const char **argv); extern const char *riscv_expand_arch_from_cpu (int argc, const char **argv); extern const char *riscv_default_mtune (int argc, const char **argv); -extern const char *riscv_multi_lib_check (int argc, const char **argv); # define EXTRA_SPEC_FUNCTIONS \ { "riscv_expand_arch", riscv_expand_arch }, \ { "riscv_expand_arch_from_cpu", riscv_expand_arch_from_cpu }, \ - { "riscv_default_mtune", riscv_default_mtune }, \ - { "riscv_multi_lib_check", riscv_multi_lib_check }, + { "riscv_default_mtune", riscv_default_mtune }, /* Support for a compile-time default CPU, et cetera. The rules are: --with-arch is ignored if -march or -mcpu is specified. -- 2.17.1
[PATCH] RISC-V: When the TARGET_COMPUTE_MULTILIB hook is implemented, check the version of each extension.
When there is an extension with different versions, the result of the TARGET_COMPUTE_MULTILIB hook is generally wrong, so the version needs to be considered. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::match_score): Match the version of each extension. --- gcc/common/config/riscv/riscv-common.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index ebc1ed7d7e4..0a15ff705d1 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -331,10 +331,9 @@ riscv_subset_list::match_score (riscv_subset_list *list) const /* list must be subset of current this list, otherwise it not safe to link. TODO: We might give different weight for each extension, but the rule could - be complicated. - TODO: We might consider the version of each extension. */ + be complicated. */ for (s = list->m_head; s != NULL; s = s->next) -if (this->lookup (s->name.c_str ()) != NULL) +if (this->lookup (s->name.c_str (), s->major_version, s->minor_version) != NULL) score++; else return 0; -- 2.17.1
[PATCH v1] RISC-V: Change the generation mode of ADJUST_SP_RTX from gen_insn to gen_SET.
The gen_insn method is used to generate ADJUST_SP_RTX here, which has certain potential risks: When the architecture adds pre-processing to `define_insn "adddi3"`, such as `define_expend "adddi3"`, the gen_expand will be automatically called here, causing the patern to emit directly, which will cause insn to enter REG_NOTE for `DWARF` instead of patern. The following error REG_NOTE occurred: error: invalid rtl sharing found in the insn: (insn 19 3 20 2 (parallel [ ... ]) (expr_list:REG_CFA_ADJUST_CFA (insn 18 0 0 (set (reg/f:DI 2 sp) (plus:DI (reg/f:DI 2 sp) (const_int -16 [0xfff0]))) -1 (nil In fact, the correct one should be the following: (insn 19 3 20 2 (parallel [ ... ]) (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 2 sp) (plus:DI (reg/f:DI 2 sp) (const_int -16 [0xfff0]) Following the treatment of arm or other architectures, it is more reasonable to use gen_SET here. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_adjust_libcall_cfi_prologue): Change gen_add3_insn to gen_rtx_SET. (riscv_adjust_libcall_cfi_epilogue): Likewise. --- gcc/config/riscv/riscv.cc | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3b7804b7501..c9c6e53c6d0 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -5054,8 +5054,9 @@ riscv_adjust_libcall_cfi_prologue () } /* Debug info for adjust sp. */ - adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, -stack_pointer_rtx, GEN_INT (-saved_size)); + adjust_sp_rtx = +gen_rtx_SET (stack_pointer_rtx, +gen_rtx_PLUS (GET_MODE(stack_pointer_rtx), stack_pointer_rtx, GEN_INT (-saved_size))); dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf); return dwarf; @@ -5176,8 +5177,9 @@ riscv_adjust_libcall_cfi_epilogue () int saved_size = cfun->machine->frame.save_libcall_adjustment; /* Debug info for adjust sp. */ - adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, -stack_pointer_rtx, GEN_INT (saved_size)); + adjust_sp_rtx = +gen_rtx_SET (stack_pointer_rtx, +gen_rtx_PLUS (GET_MODE(stack_pointer_rtx), stack_pointer_rtx, GEN_INT (saved_size))); dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf); -- 2.17.1
[PATCH] RISC-V: Fix bug of TARGET_COMPUTE_MULTILIB implemented in riscv.
MAX_MATCH_SCORE is not assigned anywhere except initialized to 0, causing BEST_MATCH_MULTI_LIB to always be 0 or -1, which will cause the result of TARGET_COMPUTE_MULTILIB hook to fail. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: --- gcc/common/config/riscv/riscv-common.cc | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 616e2f897b9..787674003cb 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -1700,7 +1700,10 @@ riscv_compute_multilib ( /* Record highest match score multi-lib setting. */ if (match_score > max_match_score) - best_match_multi_lib = i; + { + best_match_multi_lib = i; + max_match_score = match_score; + } } if (best_match_multi_lib == -1) -- 2.17.1
[PATCH v5] [RISCV] Add 'Zfa' extension according to riscv-isa-manual
This patch adds the 'Zfa' extension for riscv, which is based on: ( https://github.com/riscv/riscv-isa-manual/commit/d74d99e22d5f68832f70982d867614e2149a3bd7 ) latest 'Zfa' change on the master branch of the RISC-V ISA Manual as of this writing. The Wiki Page (details): ( https://github.com/a4lg/binutils-gdb/wiki/riscv_zfa ) The binutils-gdb for 'Zfa' extension: ( https://sourceware.org/pipermail/binutils/2022-September/122938.html ) gcc/ChangeLog: * common/config/riscv/riscv-common.cc: * config/riscv/constraints.md (Zf): * config/riscv/predicates.md: * config/riscv/riscv-builtins.cc (RISCV_FTYPE_NAME2): (AVAIL): (RISCV_ATYPE_SF): (RISCV_ATYPE_DF): (RISCV_FTYPE_ATYPES2): * config/riscv/riscv-ftypes.def (2): * config/riscv/riscv-opts.h (MASK_ZFA): (TARGET_ZFA): * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_fli): * config/riscv/riscv.cc (riscv_float_const_rtx_index_for_fli): (riscv_cannot_force_const_mem): (riscv_const_insns): (riscv_legitimize_const_move): (riscv_split_64bit_move_p): (riscv_output_move): (riscv_memmodel_needs_release_fence): (riscv_print_operand): (riscv_secondary_memory_needed): * config/riscv/riscv.h (GP_REG_RTX_P): * config/riscv/riscv.md (riscv_fminm3): (riscv_fmaxm3): (fix_truncdfsi2_zfa): (round2): (rint2): (f_quiet4_zfa): * config/riscv/riscv.opt: gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fcvtmod.c: New test. * gcc.target/riscv/zfa-fleq-fltq.c: New test. * gcc.target/riscv/zfa-fli-zfh.c: New test. * gcc.target/riscv/zfa-fli.c: New test. * gcc.target/riscv/zfa-fminm-fmaxm.c: New test. * gcc.target/riscv/zfa-fmovh-fmovp.c: New test. * gcc.target/riscv/zfa-fround.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 4 + gcc/config/riscv/constraints.md | 7 ++ gcc/config/riscv/predicates.md| 4 + gcc/config/riscv/riscv-builtins.cc| 11 ++ gcc/config/riscv/riscv-ftypes.def | 2 + gcc/config/riscv/riscv-opts.h | 3 + gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv.cc | 113 - gcc/config/riscv/riscv.h | 1 + gcc/config/riscv/riscv.md | 114 ++ gcc/config/riscv/riscv.opt| 4 + gcc/testsuite/gcc.target/riscv/zfa-fcvtmod.c | 12 ++ .../gcc.target/riscv/zfa-fleq-fltq.c | 20 +++ gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c | 42 +++ gcc/testsuite/gcc.target/riscv/zfa-fli.c | 80 .../gcc.target/riscv/zfa-fminm-fmaxm.c| 25 .../gcc.target/riscv/zfa-fmovh-fmovp.c| 11 ++ gcc/testsuite/gcc.target/riscv/zfa-fround.c | 25 18 files changed, 456 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fcvtmod.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.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-fminm-fmaxm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.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/config/riscv/riscv-common.cc index 616e2f897b9..977c8a9acf7 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[] = {"zfh", ISA_SPEC_CLASS_NONE, 1, 0}, {"zfhmin",ISA_SPEC_CLASS_NONE, 1, 0}, + {"zfa", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0}, {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1242,6 +1244,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zfhmin",_options::x_riscv_zf_subext, MASK_ZFHMIN}, {"zfh", _options::x_riscv_zf_subext, MASK_ZFH}, + {"zfa", _options::x_riscv_zf_subext, MASK_ZFA}, + {"zmmul", _options::x_riscv_zm_subext, MASK_ZMMUL}, {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL}, diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 3637380ee47..ace53b355f0 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -110,6 +110,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 `fli` in zfa." + (and (match_code "const_double") + (match_test "(riscv_float_const_rtx_index_for_fli (op) != -1)"))) + ;; Vector
[PATCH v4] [RISCV] Add 'Zfa' extension according to riscv-isa-manual
This patch adds the 'Zfa' extension for riscv, which is based on: ( https://github.com/riscv/riscv-isa-manual/commit/d74d99e22d5f68832f70982d867614e2149a3bd7 ) latest 'Zfa' change on the master branch of the RISC-V ISA Manual as of this writing. The Wiki Page (details): ( https://github.com/a4lg/binutils-gdb/wiki/riscv_zfa ) The binutils-gdb for 'Zfa' extension: ( https://sourceware.org/pipermail/binutils/2022-September/122938.html ) gcc/ChangeLog: * common/config/riscv/riscv-common.cc: * config/riscv/constraints.md (Zf): * config/riscv/predicates.md: * config/riscv/riscv-builtins.cc (RISCV_FTYPE_NAME2): (AVAIL): (RISCV_ATYPE_SF): (RISCV_ATYPE_DF): (RISCV_FTYPE_ATYPES2): * config/riscv/riscv-ftypes.def (2): * config/riscv/riscv-opts.h (MASK_ZFA): (TARGET_ZFA): * config/riscv/riscv-protos.h (riscv_float_const_rtx_index_for_fli): * config/riscv/riscv.cc (riscv_float_const_rtx_index_for_fli): (riscv_cannot_force_const_mem): (riscv_const_insns): (riscv_legitimize_const_move): (riscv_split_64bit_move_p): (riscv_output_move): (riscv_memmodel_needs_release_fence): (riscv_print_operand): (riscv_secondary_memory_needed): * config/riscv/riscv.h (GP_REG_RTX_P): * config/riscv/riscv.md (riscv_fminm3): (riscv_fmaxm3): (fix_truncdfsi2_zfa): (round2): (rint2): (f_quiet4_zfa): * config/riscv/riscv.opt: gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fcvtmod.c: New test. * gcc.target/riscv/zfa-fleq-fltq.c: New test. * gcc.target/riscv/zfa-fli-zfh.c: New test. * gcc.target/riscv/zfa-fli.c: New test. * gcc.target/riscv/zfa-fminm-fmaxm.c: New test. * gcc.target/riscv/zfa-fmovh-fmovp.c: New test. * gcc.target/riscv/zfa-fround.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 4 + gcc/config/riscv/constraints.md | 7 ++ gcc/config/riscv/predicates.md| 4 + gcc/config/riscv/riscv-builtins.cc| 11 ++ gcc/config/riscv/riscv-ftypes.def | 2 + gcc/config/riscv/riscv-opts.h | 3 + gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv.cc | 109 - gcc/config/riscv/riscv.h | 1 + gcc/config/riscv/riscv.md | 114 ++ gcc/config/riscv/riscv.opt| 4 + gcc/testsuite/gcc.target/riscv/zfa-fcvtmod.c | 12 ++ .../gcc.target/riscv/zfa-fleq-fltq.c | 20 +++ gcc/testsuite/gcc.target/riscv/zfa-fli-zfh.c | 42 +++ gcc/testsuite/gcc.target/riscv/zfa-fli.c | 80 .../gcc.target/riscv/zfa-fminm-fmaxm.c| 25 .../gcc.target/riscv/zfa-fmovh-fmovp.c| 11 ++ gcc/testsuite/gcc.target/riscv/zfa-fround.c | 25 18 files changed, 452 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fcvtmod.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fleq-fltq.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-fminm-fmaxm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.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/config/riscv/riscv-common.cc index 0a89fdaffe2..cccec12975c 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[] = {"zfh", ISA_SPEC_CLASS_NONE, 1, 0}, {"zfhmin",ISA_SPEC_CLASS_NONE, 1, 0}, + {"zfa", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0}, {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1242,6 +1244,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zfhmin",_options::x_riscv_zf_subext, MASK_ZFHMIN}, {"zfh", _options::x_riscv_zf_subext, MASK_ZFH}, + {"zfa", _options::x_riscv_zf_subext, MASK_ZFA}, + {"zmmul", _options::x_riscv_zm_subext, MASK_ZMMUL}, {"svinval", _options::x_riscv_sv_subext, MASK_SVINVAL}, diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 51cffb2bcb6..2fd407b1d9c 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -110,6 +110,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 `fli` in zfa." + (and (match_code "const_double") + (match_test "(riscv_float_const_rtx_index_for_fli (op) != -1)"))) + ;; Vector