On 5/15/23 07:16, Jin Ma wrote:
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 fminm<hf\sf\df>3
and
fmaxm<hf\sf\df>3 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 (fminm<mode>3): New.
(fmaxm<mode>3): New.
(movsidf2_low_rv32): New.
(movsidf2_high_rv32): New.
(movdfsisi3_rv32): New.
(f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_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
+
+/* Return index of the FLI instruction table if rtx X is an immediate constant
that can
+ be moved using a single FLI instruction in zfa extension. Return -1 if not
found. */
+
+int
+riscv_float_const_rtx_index_for_fli (rtx x)
+{
+ unsigned HOST_WIDE_INT *fli_value_array;
+
+ machine_mode mode = GET_MODE (x);
+
+ if (!TARGET_ZFA
+ || !CONST_DOUBLE_P(x)
+ || mode == VOIDmode
+ || (mode == HFmode && !TARGET_ZFH)
+ || (mode == SFmode && !TARGET_HARD_FLOAT)
+ || (mode == DFmode && !TARGET_DOUBLE_FLOAT))
+ return -1;
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