RISC-V: Add floating point rounding mode (RMM)

Message ID 1599459780-252633-1-git-send-email-hankuan.chen@sifive.com
State Changes Requested, archived
Headers
Series RISC-V: Add floating point rounding mode (RMM) |

Commit Message

Han-Kuan Chen Sept. 7, 2020, 6:23 a.m. UTC
  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

Stefan O'Rear Sept. 7, 2020, 7:43 a.m. UTC | #1
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
  
Joseph Myers Sept. 7, 2020, 4:48 p.m. UTC | #2
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.
  

Patch

diff --git a/sysdeps/riscv/bits/fenv.h b/sysdeps/riscv/bits/fenv.h
index c592bdd..b20f5d5 100644
--- a/sysdeps/riscv/bits/fenv.h
+++ b/sysdeps/riscv/bits/fenv.h
@@ -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
   };
 
 
diff --git a/sysdeps/riscv/rvf/fesetround.c b/sysdeps/riscv/rvf/fesetround.c
index bd1ecff..d16822f 100644
--- a/sysdeps/riscv/rvf/fesetround.c
+++ b/sysdeps/riscv/rvf/fesetround.c
@@ -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:
diff --git a/sysdeps/riscv/sfp-machine.h b/sysdeps/riscv/sfp-machine.h
index bbeb9b3..9977233 100644
--- a/sysdeps/riscv/sfp-machine.h
+++ b/sysdeps/riscv/sfp-machine.h
@@ -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