From 103f61c8a0204e0ad4e2a2dc4c0e9993eb7ef28d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 6 Dec 2019 15:27:42 -0800 Subject: [PATCH] Only prohibit float32-only when FP emulation is enabled --- machine/fp_asm.S | 10 +++++----- machine/fp_emulation.c | 8 ++++++++ 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);