18 #ifndef __CORE_FEATURE_FPU_H__
19 #define __CORE_FEATURE_FPU_H__
35 #include "core_feature_base.h"
55 #if defined(__FPU_PRESENT) && (__FPU_PRESENT > 0)
57 #if __FPU_PRESENT == 1
59 #define __RISCV_FLEN 32
60 #elif __FPU_PRESENT == 2
61 #define __RISCV_FLEN 64
63 #define __RISCV_FLEN __riscv_flen
67 #define __get_FCSR() __RV_CSR_READ(CSR_FCSR)
69 #define __set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val))
71 #define __get_FRM() __RV_CSR_READ(CSR_FRM)
73 #define __set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val))
75 #define __get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS)
77 #define __set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val))
80 #define __enable_FPU() { __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS); \
81 __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS_INITIAL); \
90 #define __disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS)
107 #define __RV_FLW(freg, addr, ofs) \
109 rv_csr_t __addr = (rv_csr_t)(addr); \
110 __ASM volatile("flw " STRINGIFY(freg) ", %0(%1) " \
111 : : "I"(ofs), "r"(__addr) \
128 #define __RV_FSW(freg, addr, ofs) \
130 rv_csr_t __addr = (rv_csr_t)(addr); \
131 __ASM volatile("fsw " STRINGIFY(freg) ", %0(%1) " \
132 : : "I"(ofs), "r"(__addr) \
151 #define __RV_FLD(freg, addr, ofs) \
153 rv_csr_t __addr = (rv_csr_t)(addr); \
154 __ASM volatile("fld " STRINGIFY(freg) ", %0(%1) " \
155 : : "I"(ofs), "r"(__addr) \
174 #define __RV_FSD(freg, addr, ofs) \
176 rv_csr_t __addr = (rv_csr_t)(addr); \
177 __ASM volatile("fsd " STRINGIFY(freg) ", %0(%1) " \
178 : : "I"(ofs), "r"(__addr) \
206 #if __FPU_PRESENT == 1
207 #define __RV_FLOAD __RV_FLW
208 #define __RV_FSTORE __RV_FSW
211 #elif __FPU_PRESENT == 2
212 #define __RV_FLOAD __RV_FLD
213 #define __RV_FSTORE __RV_FSD
247 #define SAVE_FPU_CONTEXT() \
248 rv_fpu_t __fpu_context[20]; \
249 __RV_FSTORE(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
250 __RV_FSTORE(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
251 __RV_FSTORE(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
252 __RV_FSTORE(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
253 __RV_FSTORE(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
254 __RV_FSTORE(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
255 __RV_FSTORE(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
256 __RV_FSTORE(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
257 __RV_FSTORE(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
258 __RV_FSTORE(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
259 __RV_FSTORE(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
260 __RV_FSTORE(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
261 __RV_FSTORE(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
262 __RV_FSTORE(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
263 __RV_FSTORE(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
264 __RV_FSTORE(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
265 __RV_FSTORE(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
266 __RV_FSTORE(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
267 __RV_FSTORE(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
268 __RV_FSTORE(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
278 #define RESTORE_FPU_CONTEXT() \
279 __RV_FLOAD(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
280 __RV_FLOAD(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
281 __RV_FLOAD(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
282 __RV_FLOAD(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
283 __RV_FLOAD(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
284 __RV_FLOAD(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
285 __RV_FLOAD(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
286 __RV_FLOAD(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
287 __RV_FLOAD(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
288 __RV_FLOAD(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
289 __RV_FLOAD(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
290 __RV_FLOAD(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
291 __RV_FLOAD(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
292 __RV_FLOAD(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
293 __RV_FLOAD(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
294 __RV_FLOAD(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
295 __RV_FLOAD(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
296 __RV_FLOAD(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
297 __RV_FLOAD(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
298 __RV_FLOAD(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
300 #define SAVE_FPU_CONTEXT()
301 #define RESTORE_FPU_CONTEXT()
uint64_t rv_fpu_t
Type of FPU register, depends on the FLEN defined in RISC-V.