RISC-V: Add floating point rounding mode (RMM)
Commit Message
Current implementation only support four standard rounding modes.
However, RISC-V has an additional rounding mode (RNE), which should be defined
in fenv.h.
RMM is defined as 0x4 in riscv-spec.
Follow riscv-newlib name (FE_TONEAREST_MM).
---
sysdeps/riscv/bits/fenv.h | 5 ++++-
sysdeps/riscv/rvf/fesetround.c | 1 +
sysdeps/riscv/sfp-machine.h | 1 +
3 files changed, 6 insertions(+), 1 deletion(-)
Comments
On Mon, Sep 7, 2020, at 2:23 AM, Han-Kuan Chen wrote:
> Current implementation only support four standard rounding modes.
>
> However, RISC-V has an additional rounding mode (RNE), which should be defined
>
> in fenv.h.
>
> RMM is defined as 0x4 in riscv-spec.
>
> Follow riscv-newlib name (FE_TONEAREST_MM).
I'm wondering if this is the same thing as FE_TONEARESTFROMZERO defined in C2X?
If so, should we use the C2X name instead of the newlib name?
-s
On Mon, 7 Sep 2020, Stefan O'Rear via Libc-alpha wrote:
> On Mon, Sep 7, 2020, at 2:23 AM, Han-Kuan Chen wrote:
> > Current implementation only support four standard rounding modes.
> >
> > However, RISC-V has an additional rounding mode (RNE), which should be defined
> >
> > in fenv.h.
> >
> > RMM is defined as 0x4 in riscv-spec.
> >
> > Follow riscv-newlib name (FE_TONEAREST_MM).
>
> I'm wondering if this is the same thing as FE_TONEARESTFROMZERO defined in C2X?
>
> If so, should we use the C2X name instead of the newlib name?
Yes, the C2X name should be used.
Also, note what I said in
<https://gcc.gnu.org/legacy-ml/gcc-patches/2017-01/msg00840.html> when the
RISC-V GCC port was being reviewed, that a fair number of glibc changes
would be needed to support that rounding mode from C code. Simply being
able to set it in the rounding mode register isn't enough for it to work
properly everywhere.
* Some code in glibc has cases for individual rounding modes. See, for
example, include/rounding-mode.h. That code needs updating to handle the
new mode (otherwise e.g. strtod will abort whenever called in the new
rounding mode), without breaking the build for architectures that don't
have it. The existing code requires get-rounding-mode.h to define
distinct FE_* values for all unsupported modes, to simplify the switch
statement; if you use that approach, lots of architecture-specific files
need to change, and otherwise code using this rounding mode needs
conditionals.
* Likewise, soft-fp needs support for the new rounding mode, preferably
without increasing code size for configurations not supporting it. Then
the copy of soft-fp in libgcc needs updating, and the feature needs
enabling in libgcc/config/riscv/sfp-machine.h, so that the rounding mode
is correctly used for software floating-point formats when set for those
formats implemented in hardware.
* Likewise, test cases, and test case generators, that cover the different
rounding modes, need updating to handle the new mode as well (and then the
checked-in outputs such as auto-libm-test-out-* need regenerating), so
that you know the rounding mode actually works. Note that MPFR doesn't
actually support MPFR_RNDNA in general, which means local support for
emulating that rounding mode is needed in test case generators.
@@ -55,7 +55,10 @@ enum
FE_DOWNWARD,
FE_UPWARD =
#define FE_UPWARD (0x3)
- FE_UPWARD
+ FE_UPWARD,
+ FE_TONEAREST_MM =
+#define FE_TONEAREST_MM (0x4)
+ FE_TONEAREST_MM
};
@@ -28,6 +28,7 @@ __fesetround (int round)
case FE_TOWARDZERO:
case FE_DOWNWARD:
case FE_UPWARD:
+ case FE_TONEAREST_MM:
riscv_setround (round);
return 0;
default:
@@ -101,6 +101,7 @@
#define FP_RND_ZERO FE_TOWARDZERO
#define FP_RND_PINF FE_UPWARD
#define FP_RND_MINF FE_DOWNWARD
+#define FP_RND_AWAYZERO FE_TONEAREST_MM
#define FP_EX_INVALID FE_INVALID
#define FP_EX_OVERFLOW FE_OVERFLOW