summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2020-01-20 22:46:36 -0800
committerCorinna Vinschen <corinna@vinschen.de>2020-01-21 10:28:35 +0100
commit5377a847764461493c620644f6530892344d1cdd (patch)
treefa3d943c9c83db67a13dc29e442a8b63e147b31e
parent8e74c7119fb7f95662bb4986570a98496f259400 (diff)
downloadcygnal-5377a847764461493c620644f6530892344d1cdd.tar.gz
cygnal-5377a847764461493c620644f6530892344d1cdd.tar.bz2
cygnal-5377a847764461493c620644f6530892344d1cdd.zip
riscv: Map between ieeefp.h exception bits and RISC-V FCSR bits
If we had architecture-specific exception bits, we could just set them to match the processor, but instead ieeefp.h is shared by all targets so we need to map between the public values and the register contents. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--newlib/libc/machine/riscv/ieeefp.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/newlib/libc/machine/riscv/ieeefp.c b/newlib/libc/machine/riscv/ieeefp.c
index c45832280..60ecacfc2 100644
--- a/newlib/libc/machine/riscv/ieeefp.c
+++ b/newlib/libc/machine/riscv/ieeefp.c
@@ -40,6 +40,40 @@ frm_fp_rnd (unsigned frm)
}
}
+static fp_except
+frm_fp_except (unsigned except)
+{
+ fp_except fp = 0;
+ if (except & (1 << 0))
+ fp |= FP_X_IMP;
+ if (except & (1 << 1))
+ fp |= FP_X_UFL;
+ if (except & (1 << 2))
+ fp |= FP_X_OFL;
+ if (except & (1 << 3))
+ fp |= FP_X_DX;
+ if (except & (1 << 4))
+ fp |= FP_X_INV;
+ return fp;
+}
+
+static unsigned
+frm_except(fp_except fp)
+{
+ unsigned except = 0;
+ if (fp & FP_X_IMP)
+ except |= (1 << 0);
+ if (fp & FP_X_UFL)
+ except |= (1 << 1);
+ if (fp & FP_X_OFL)
+ except |= (1 << 2);
+ if (fp & FP_X_DX)
+ except |= (1 << 3);
+ if (fp & FP_X_INV)
+ except |= (1 << 4);
+ return except;
+}
+
#endif /* __riscv_flen */
fp_except
@@ -63,7 +97,7 @@ fp_except
fpgetsticky(void)
{
#ifdef __riscv_flen
- return frsr () & 0x1f;
+ return frm_fp_except(frsr ());
#else
return 0;
#endif /* __riscv_flen */
@@ -102,8 +136,8 @@ fpsetsticky(fp_except sticky)
{
#ifdef __riscv_flen
unsigned fsr = frsr ();
- fssr (sticky & 0x1f | fsr & ~0x1f);
- return fsr & 0x1f;
+ fssr (frm_except(sticky) | (fsr & ~0x1f));
+ return frm_fp_except(fsr);
#else
return -1;
#endif /* __riscv_flen */