diff options
author | Andrew Waterman <andrew@sifive.com> | 2019-12-06 15:27:42 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2019-12-06 15:28:37 -0800 |
commit | 103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d (patch) | |
tree | 1361efe65d7ae64c233f2276ce03c19fb2a49089 | |
parent | 14e87d2dd250b0efb5e9fb19ab279ccf1ccbdbd7 (diff) | |
download | riscv-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.S | 10 | ||||
-rw-r--r-- | machine/fp_emulation.c | 8 | ||||
-rw-r--r-- | machine/minit.c | 11 |
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); |