Re: Re: [RE] [v2] RISC-V: Add Zfbfmin extension

2024-06-18 Thread Jin Ma

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

2024-06-18 Thread Jin Ma

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

2024-06-07 Thread Jin Ma
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.

2024-06-06 Thread Jin Ma

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

2024-06-05 Thread Jin Ma
> 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.

2024-06-04 Thread Jin Ma
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

2024-04-02 Thread Jin Ma
> 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.

2024-01-29 Thread Jin Ma
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.

2024-01-29 Thread Jin Ma
>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.

2024-01-29 Thread Jin Ma
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.

2024-01-11 Thread Jin Ma
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

2024-01-09 Thread Jin Ma
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

2024-01-09 Thread Jin Ma
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

2024-01-09 Thread Jin Ma
ping


[PATCH] Support libcall __float{, un}sibf by SF when it is not supported for _bf16

2023-12-20 Thread Jin Ma
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

2023-11-16 Thread Jin Ma
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.

2023-11-12 Thread Jin Ma
> > 
> > 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.

2023-11-10 Thread Jin Ma
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.

2023-11-09 Thread Jin Ma
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.

2023-11-08 Thread Jin Ma
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

2023-11-06 Thread Jin Ma
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

2023-11-02 Thread Jin Ma
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.

2023-10-25 Thread Jin Ma
> >>> +;; 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.

2023-10-09 Thread Jin Ma
> 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.

2023-09-19 Thread Jin Ma
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.

2023-09-19 Thread Jin Ma
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.

2023-08-29 Thread Jin Ma via Gcc-patches
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.

2023-08-29 Thread Jin Ma via Gcc-patches
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'

2023-08-15 Thread Jin Ma via Gcc-patches
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'

2023-08-14 Thread Jin Ma via Gcc-patches
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.

2023-08-14 Thread Jin Ma via Gcc-patches
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

2023-08-14 Thread Jin Ma via Gcc-patches
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

2023-08-14 Thread Jin Ma via Gcc-patches
> > 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

2023-08-13 Thread Jin Ma via Gcc-patches
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

2023-08-11 Thread Jin Ma via Gcc-patches
> 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.

2023-08-10 Thread Jin Ma via Gcc-patches
> 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.

2023-07-25 Thread Jin Ma via Gcc-patches
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.

2023-07-25 Thread Jin Ma via Gcc-patches
> 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.

2023-07-25 Thread Jin Ma via Gcc-patches
> -  [(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.

2023-07-25 Thread Jin Ma via Gcc-patches
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.

2023-07-25 Thread Jin Ma via Gcc-patches
> 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.

2023-07-25 Thread Jin Ma via Gcc-patches
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.

2023-07-25 Thread Jin Ma via Gcc-patches
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.

2023-06-15 Thread Jin Ma via Gcc-patches
> 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.

2023-06-15 Thread Jin Ma via Gcc-patches
> 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.

2023-06-14 Thread Jin Ma via Gcc-patches
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.

2023-06-13 Thread Jin Ma via Gcc-patches
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.

2023-06-11 Thread Jin Ma via Gcc-patches
> 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.

2023-06-07 Thread Jin Ma via Gcc-patches
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.

2023-06-01 Thread Jin Ma via Gcc-patches
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.

2023-05-29 Thread Jin Ma via Gcc-patches
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.

2023-05-29 Thread Jin Ma via Gcc-patches
  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.

2023-05-28 Thread Jin Ma via Gcc-patches
> > > > 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.

2023-05-28 Thread Jin Ma via Gcc-patches
> > 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.

2023-05-26 Thread Jin Ma via Gcc-patches
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.

2023-05-25 Thread Jin Ma via Gcc-patches
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)).'

2023-05-25 Thread Jin Ma via Gcc-patches
> > 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.

2023-05-22 Thread Jin Ma via Gcc-patches
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.

2023-05-17 Thread Jin Ma via Gcc-patches
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)).'

2023-05-17 Thread Jin Ma via Gcc-patches
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

2023-05-15 Thread Jin Ma via Gcc-patches
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.

2023-05-06 Thread Jin Ma via Gcc-patches




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.

2023-04-19 Thread Jin Ma via Gcc-patches
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.

2023-04-18 Thread Jin Ma via Gcc-patches
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.

2023-04-18 Thread Jin Ma via Gcc-patches
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.

2023-03-23 Thread Jin Ma via Gcc-patches
  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.

2023-03-10 Thread Jin Ma via Gcc-patches
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.

2023-02-22 Thread Jin Ma via Gcc-patches
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.

2023-02-22 Thread Jin Ma via Gcc-patches
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.

2023-02-03 Thread Jin Ma via Gcc-patches
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.

2023-02-02 Thread Jin Ma via Gcc-patches
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

2023-02-01 Thread Jin Ma via Gcc-patches
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

2023-01-11 Thread Jin Ma via Gcc-patches
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