Implement __flt_rounds() for RISC-V. RISC-V is "interesting" since it
authorkettenis <kettenis@openbsd.org>
Wed, 28 Apr 2021 15:38:59 +0000 (15:38 +0000)
committerkettenis <kettenis@openbsd.org>
Wed, 28 Apr 2021 15:38:59 +0000 (15:38 +0000)
implements a variation on the traditional "to nearest" rounding mode that
rounds away from zero when tied.  The upcoming C2x includes support for that
and LLVM already implements this so provide an implementation that matches
our system compiler.

ok drahn@

lib/libc/arch/riscv64/gen/flt_rounds.c [new file with mode: 0644]

diff --git a/lib/libc/arch/riscv64/gen/flt_rounds.c b/lib/libc/arch/riscv64/gen/flt_rounds.c
new file mode 100644 (file)
index 0000000..b89de97
--- /dev/null
@@ -0,0 +1,30 @@
+/*     $OpenBSD: flt_rounds.c,v 1.1 2021/04/28 15:38:59 kettenis Exp $ */
+
+/*
+ * Written by Mark Kettenis based on the hppa version written by
+ * Miodrag Vallat.  Public domain.
+ */
+
+#include <sys/types.h>
+#include <float.h>
+
+static const int map[] = {
+       1,      /* round to nearest, ties to even */
+       0,      /* round to zero */
+       3,      /* round to negative infinity */
+       2,      /* round to positive infinity */
+       4,      /* round to nearest, ties away from zero */
+       -1,     /* invalid */
+       -1,     /* invalid */
+       -1      /* invalid */
+};
+
+int
+__flt_rounds(void)
+{
+       uint32_t frm;
+
+       __asm volatile ("frrm %0" : "=r"(frm));
+       return map[frm];
+}
+DEF_STRONG(__flt_rounds);