> This Patch implements the Quad-precision Float extension for RISC-V, based on > Kito's work five years ago in > https://github.com/riscvarchive/riscv-gcc/tree/q-ext
Thanks for bringing this back, I almost forgot this still has not merged yet. > diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md > index d300224150..8abfe96785 100644 > --- a/gcc/config/riscv/iterators.md > +++ b/gcc/config/riscv/iterators.md > @@ -107,12 +107,14 @@ > ;; 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") > + (TF "TARGET_QUAD_FLOAT")]) indention > > ;; Iterator for hardware-supported load/store floating-point modes. > (define_mode_iterator ANYLSF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX") > (DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX") > - (HF "TARGET_ZFHMIN || TARGET_ZHINXMIN")]) > + (HF "TARGET_ZFHMIN || TARGET_ZHINXMIN") > + (TF "TARGET_QUAD_FLOAT")]) indention > > ;; Iterator for floating-point modes that can be loaded into X registers. > (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")]) > @@ -143,7 +145,7 @@ > (define_mode_attr softload [(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") (HF "fsh") > (SF "fsw") (DF "fsd") (TF "flq")]) Should be fsq? also it should add flq to "define_mode_attr load"? > diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h > index 46b256d635..5bb1d81006 100644 > --- a/gcc/config/riscv/riscv-protos.h > +++ b/gcc/config/riscv/riscv-protos.h > @@ -122,7 +122,7 @@ extern rtx riscv_unspec_address (rtx, enum > riscv_symbol_type); > extern void riscv_move_integer (rtx, rtx, HOST_WIDE_INT, machine_mode); > extern bool riscv_legitimize_move (machine_mode, rtx, rtx); > extern rtx riscv_subword (rtx, bool); > -extern bool riscv_split_64bit_move_p (rtx, rtx); > +extern bool riscv_split_move_p (rtx, rtx); > extern void riscv_split_doubleword_move (rtx, rtx); > extern const char *riscv_output_move (rtx, rtx); > extern const char *riscv_output_return (); > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 07d40f459e..82cc6ad8d9 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -2661,7 +2661,7 @@ riscv_load_store_insns (rtx mem, rtx_insn *insn) > else if (GET_MODE_BITSIZE (mode).to_constant () == 64) > { > set = single_set (insn); > - if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set))) > + if (set && !riscv_split_move_p (SET_DEST (set), SET_SRC (set))) > might_split_p = false; > } > > @@ -4721,12 +4721,14 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, > rtx > riscv_subword (rtx op, bool high_p) > { > - unsigned int byte = (high_p != BYTES_BIG_ENDIAN) ? UNITS_PER_WORD : 0; > + unsigned int byte; > machine_mode mode = GET_MODE (op); > > if (mode == VOIDmode) > mode = TARGET_64BIT ? TImode : DImode; > > + byte = high_p ? (GET_MODE_SIZE (mode).to_constant () / 2 ) : 0; > + BYTES_BIG_ENDIAN handling is gone after this change? > if (MEM_P (op)) > return adjust_address (op, word_mode, byte); > > @@ -4736,12 +4738,14 @@ riscv_subword (rtx op, bool high_p) > return simplify_gen_subreg (word_mode, op, mode, byte); > } > > -/* Return true if a 64-bit move from SRC to DEST should be split into two. > */ > +/* Return true if move from SRC to DEST should be split into two. */ > > bool > -riscv_split_64bit_move_p (rtx dest, rtx src) > +riscv_split_move_p (rtx dest, rtx src) > { > - if (TARGET_64BIT) > + machine_mode mode = GET_MODE (dest); > + > + if (GET_MODE_SIZE (mode).to_constant () <= UNITS_PER_WORD) > return false; > > /* Zilsd provides load/store with even-odd register pair. */ > @@ -4763,7 +4767,7 @@ riscv_split_64bit_move_p (rtx dest, rtx src) > > /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case > of zeroing an FPR with FCVT.D.W. */ > - if (TARGET_DOUBLE_FLOAT > + if (GET_MODE_SIZE (mode).to_constant () <= UNITS_PER_FP_REG > && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest)) > || (FP_REG_RTX_P (dest) && MEM_P (src)) > || (FP_REG_RTX_P (src) && MEM_P (dest)) > @@ -4774,7 +4778,7 @@ riscv_split_64bit_move_p (rtx dest, rtx src) > } > > /* Split a doubleword move from SRC to DEST. On 32-bit targets, > - this function handles 64-bit moves for which riscv_split_64bit_move_p > + this function handles 64-bit moves for which riscv_split_move_p > holds. For 64-bit targets, this function handles 128-bit moves. */ > > void > @@ -4876,7 +4880,7 @@ riscv_output_move (rtx dest, rtx src) > dbl_p = (GET_MODE_SIZE (mode).to_constant () == 8); > width = GET_MODE_SIZE (mode).to_constant (); > > - if (dbl_p && riscv_split_64bit_move_p (dest, src)) > + if (dbl_p && riscv_split_move_p (dest, src)) > return "#"; > > if (dest_code == REG && GP_REG_P (REGNO (dest))) > @@ -4893,6 +4897,8 @@ riscv_output_move (rtx dest, rtx src) > return "fmv.x.s\t%0,%1"; > case 8: > return "fmv.x.d\t%0,%1"; > + case 16: > + return "fmv.x.q\t%0,%1"; indention seems not right here > } > > if (src_code == MEM) > @@ -4954,6 +4960,13 @@ riscv_output_move (rtx dest, rtx src) > /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */ > gcc_assert (src == CONST0_RTX (mode)); > return "fcvt.d.w\t%0,x0"; > + case 16: > + gcc_assert (src == CONST0_RTX (mode)); > + /* In RV64, we can emulate fmv.q.x %0, x0 using fcvt.d.x. */ > + if(TARGET_64BIT) > + return "fmv.d.x\t%0,x0"; > + /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */ > + return "fcvt.d.w\t%0,x0"; indention seems not right here > } > } > if (dest_code == MEM) > @@ -4978,6 +4991,8 @@ riscv_output_move (rtx dest, rtx src) > return "fmv.s\t%0,%1"; > case 8: > return "fmv.d\t%0,%1"; > + case 16: > + return "fmv.q\t%0,%1"; indention seems not right here > } > > if (dest_code == MEM) > @@ -4989,6 +5004,8 @@ riscv_output_move (rtx dest, rtx src) > return "fsw\t%1,%0"; > case 8: > return "fsd\t%1,%0"; > + case 16: > + return "fsq\t%1,%0"; indention seems not right here > } > } > if (dest_code == REG && FP_REG_P (REGNO (dest))) > @@ -5002,6 +5019,8 @@ riscv_output_move (rtx dest, rtx src) > return "flw\t%0,%1"; > case 8: > return "fld\t%0,%1"; > + case 16: > + return "flq\t%0,%1"; indention seems not right here > diff --git a/gcc/testsuite/gcc.target/riscv/long-double-1.c > b/gcc/testsuite/gcc.target/riscv/long-double-1.c > new file mode 100644 > index 0000000000..1ee990eb44 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/long-double-1.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv64gcq -mabi=lp64q -O0" } */ Could you also add some tests for rv32gcq? IIRC q on RV32 has some issues and I don't remember if I fixed them all at that moment. > + > +long double foo(long double a, long double b) > +{ > + return a + b; > +} > + > +long double foo2(long double a, long double b) > +{ > + return a - b; > +} > + > +/* { dg-final { scan-assembler-times {\mfadd\.q\M} 1 } } */ > +/* { dg-final { scan-assembler-times {\mfsub\.q\M} 1 } } */