aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-12-06 15:27:42 -0800
committerAndrew Waterman <andrew@sifive.com>2019-12-06 15:28:37 -0800
commit103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d (patch)
tree1361efe65d7ae64c233f2276ce03c19fb2a49089
parent14e87d2dd250b0efb5e9fb19ab279ccf1ccbdbd7 (diff)
downloadriscv-pk-103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d.zip
riscv-pk-103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d.tar.gz
riscv-pk-103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d.tar.bz2
Only prohibit float32-only when FP emulation is enabled
-rw-r--r--machine/fp_asm.S10
-rw-r--r--machine/fp_emulation.c8
-rw-r--r--machine/minit.c11
3 files changed, 22 insertions, 7 deletions
diff --git a/machine/fp_asm.S b/machine/fp_asm.S
index cdbb151..b449359 100644
--- a/machine/fp_asm.S
+++ b/machine/fp_asm.S
@@ -2,10 +2,6 @@
#ifdef __riscv_flen
-#if __riscv_flen != 64
-# error single-float only is not supported
-#endif
-
#define get_f32(which) fmv.x.s a0, which; jr t0
#define put_f32(which) fmv.s.x which, a0; jr t0
#if __riscv_xlen == 64
@@ -88,7 +84,9 @@
put_f32(f29)
put_f32(f30)
put_f32(f31)
-
+
+ #if __riscv_flen > 32
+
.text
.globl get_f64_reg
get_f64_reg:
@@ -162,3 +160,5 @@
put_f64(f31)
#endif
+
+#endif
diff --git a/machine/fp_emulation.c b/machine/fp_emulation.c
index c16aff9..61220b0 100644
--- a/machine/fp_emulation.c
+++ b/machine/fp_emulation.c
@@ -6,6 +6,12 @@
#include "internals.h"
#include "config.h"
+#ifdef PK_ENABLE_FP_EMULATION
+
+#if defined(__riscv_flen) && __riscv_flen != 64
+# error single-float only is not supported
+#endif
+
DECLARE_EMULATION_FUNC(emulate_fp)
{
asm (".pushsection .rodata\n"
@@ -406,3 +412,5 @@ DECLARE_EMULATION_FUNC(emulate_fmadd)
return truly_illegal_insn(regs, mcause, mepc, mstatus, insn);
}
}
+
+#endif
diff --git a/machine/minit.c b/machine/minit.c
index 5ad6d92..963010d 100644
--- a/machine/minit.c
+++ b/machine/minit.c
@@ -24,7 +24,7 @@ void* kernel_end;
static void mstatus_init()
{
// Enable FPU
- if (supports_extension('D') || supports_extension('F'))
+ if (supports_extension('F'))
write_csr(mstatus, MSTATUS_FS);
// Enable user/supervisor use of perf counters
@@ -64,7 +64,7 @@ static void delegate_traps()
static void fp_init()
{
- if (!supports_extension('D') && !supports_extension('F'))
+ if (!supports_extension('F'))
return;
assert(read_csr(mstatus) & MSTATUS_FS);
@@ -73,6 +73,13 @@ static void fp_init()
for (int i = 0; i < 32; i++)
init_fp_reg(i);
write_csr(fcsr, 0);
+
+# if __riscv_flen == 32
+ uintptr_t d_mask = 1 << ('D' - 'A');
+ clear_csr(misa, d_mask);
+ assert(!(read_csr(misa) & d_mask));
+# endif
+
#else
uintptr_t fd_mask = (1 << ('F' - 'A')) | (1 << ('D' - 'A'));
clear_csr(misa, fd_mask);