aboutsummaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer.dabbelt@eecs.berkeley.edu>2015-07-01 15:28:58 -0700
committerPalmer Dabbelt <palmer.dabbelt@eecs.berkeley.edu>2015-07-01 16:20:54 -0700
commit1b33b0210fbe42a713ee0999fa5eae367fd33fad (patch)
tree8cd1d864c1fd0714e722ee2038990426f3264419 /newlib
parent6dcbadf525763339c0d061f23e156b719c2f1cc2 (diff)
downloadriscv-gnu-toolchain-1b33b0210fbe42a713ee0999fa5eae367fd33fad.zip
riscv-gnu-toolchain-1b33b0210fbe42a713ee0999fa5eae367fd33fad.tar.gz
riscv-gnu-toolchain-1b33b0210fbe42a713ee0999fa5eae367fd33fad.tar.bz2
Disable newlib's dynamic rounding without F
GCC's softfloat is built by default without support for dynamic rounding modes. This makes softfloat newlib's floating point always round-to-zero, and returns a failure code when trying to set it. This patch is needed to make newlib compile on anything without F, as it used to try use an undefined instruction to do this.
Diffstat (limited to 'newlib')
-rw-r--r--newlib/newlib/libc/machine/riscv/ieeefp.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/newlib/newlib/libc/machine/riscv/ieeefp.c b/newlib/newlib/libc/machine/riscv/ieeefp.c
index ffa57a5..5bd0712 100644
--- a/newlib/newlib/libc/machine/riscv/ieeefp.c
+++ b/newlib/newlib/libc/machine/riscv/ieeefp.c
@@ -1,5 +1,6 @@
#include <ieeefp.h>
+#ifdef __riscv_hard_float
static void fssr(int value)
{
asm volatile ("fssr %0" :: "r"(value));
@@ -11,6 +12,7 @@ static int frsr()
asm volatile ("frsr %0" : "=r"(value));
return value;
}
+#endif
fp_except fpgetmask(void)
{
@@ -19,13 +21,21 @@ fp_except fpgetmask(void)
fp_rnd fpgetround(void)
{
+#ifdef __riscv_hard_float
int rm = frsr() >> 5;
return rm == 0 ? FP_RN : rm == 1 ? FP_RZ : rm == 2 ? FP_RM : FP_RP;
+#else
+ return FP_RZ;
+#endif
}
fp_except fpgetsticky(void)
{
+#ifdef __riscv_hard_float
return frsr() & 0x1f;
+#else
+ return 0;
+#endif
}
fp_except fpsetmask(fp_except mask)
@@ -35,16 +45,24 @@ fp_except fpsetmask(fp_except mask)
fp_rnd fpsetround(fp_rnd rnd_dir)
{
+#ifdef __riscv_hard_float
int fsr = frsr();
int rm = fsr >> 5;
int new_rm = rnd_dir == FP_RN ? 0 : rnd_dir == FP_RZ ? 1 : rnd_dir == FP_RM ? 2 : 3;
fssr(new_rm << 5 | fsr & 0x1f);
return rm == 0 ? FP_RN : rm == 1 ? FP_RZ : rm == 2 ? FP_RM : FP_RP;
+#else
+ return -1;
+#endif
}
fp_except fpsetsticky(fp_except sticky)
{
+#ifdef __riscv_hard_float
int fsr = frsr();
fssr(sticky & 0x1f | fsr & ~0x1f);
return fsr & 0x1f;
+#else
+ return -1;
+#endif
}