FPU Functions
- group NMSIS_Core_FPU_Functions
Functions that related to the RISC-V FPU (F and D extension).
Nuclei provided floating point unit by RISC-V F and D extension.
F extension
adds single-precision floating-point computational instructions compliant with the IEEE 754-2008 arithmetic standard, __RISCV_FLEN = 32. The F extension adds 32 floating-point registers, f0-f31, each 32 bits wide, and a floating-point control and status register fcsr, which contains the operating mode and exception status of the floating-point unit.D extension
adds double-precision floating-point computational instructions compliant with the IEEE 754-2008 arithmetic standard. The D extension widens the 32 floating-point registers, f0-f31, to 64 bits, __RISCV_FLEN = 64
Defines
-
__RISCV_FLEN 64
-
__get_FCSR() __RV_CSR_READ(CSR_FCSR)
Get FCSR CSR Register.
-
__set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val))
Set FCSR CSR Register with val.
-
__get_FRM() __RV_CSR_READ(CSR_FRM)
Get FRM CSR Register.
-
__set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val))
Set FRM CSR Register with val.
-
__get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS)
Get FFLAGS CSR Register.
-
__set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val))
Set FFLAGS CSR Register with val.
-
__enable_FPU()
Enable FPU Unit, and set state to initial.
-
__disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS)
Disable FPU Unit.
We can save power by disable FPU Unit.
When FPU Unit is disabled, any access to FPU related CSR registers and FPU instructions will cause illegal Instuction Exception.
-
__RV_FLW(freg, addr, ofs)
Load a single-precision value from memory into float point register freg using flw instruction.
The FLW instruction loads a single-precision floating point value from memory address (addr + ofs) into floating point register freg(f0-f31)
Remark
FLW and FSW operations need to make sure the address is 4 bytes aligned, otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved
- Parameters
freg – [in] The floating point register, eg. FREG(0), f0
addr – [in] The memory base address, 4 byte aligned required
ofs – [in] a 12-bit immediate signed byte offset value, should be an const value
-
__RV_FSW(freg, addr, ofs)
Store a single-precision value from float point freg into memory using fsw instruction.
The FSW instruction stores a single-precision value from floating point register to memory
Remark
FLW and FSW operations need to make sure the address is 4 bytes aligned, otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved
- Parameters
freg – [in] The floating point register(f0-f31), eg. FREG(0), f0
addr – [in] The memory base address, 4 byte aligned required
ofs – [in] a 12-bit immediate signed byte offset value, should be an const value
-
__RV_FLD(freg, addr, ofs)
Load a double-precision value from memory into float point register freg using fld instruction.
The FLD instruction loads a double-precision floating point value from memory address (addr + ofs) into floating point register freg(f0-f31)
Remark
FLD and FSD operations need to make sure the address is 8 bytes aligned, otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.
- Attention
Function only available for double precision floating point unit, FLEN = 64
- Parameters
freg – [in] The floating point register, eg. FREG(0), f0
addr – [in] The memory base address, 8 byte aligned required
ofs – [in] a 12-bit immediate signed byte offset value, should be an const value
-
__RV_FSD(freg, addr, ofs)
Store a double-precision value from float point freg into memory using fsd instruction.
The FSD instruction stores double-precision value from floating point register to memory
Remark
FLD and FSD operations need to make sure the address is 8 bytes aligned, otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.
- Attention
Function only available for double precision floating point unit, FLEN = 64
- Parameters
freg – [in] The floating point register(f0-f31), eg. FREG(0), f0
addr – [in] The memory base address, 8 byte aligned required
ofs – [in] a 12-bit immediate signed byte offset value, should be an const value
-
__RV_FLOAD __RV_FLD
Load a float point value from memory into float point register freg using flw/fld instruction.
For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): It will call __RV_FLW to load a single-precision floating point value from memory to floating point register
For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): It will call __RV_FLD to load a double-precision floating point value from memory to floating point register
- Attention
Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
-
__RV_FSTORE __RV_FSD
Store a float value from float point freg into memory using fsw/fsd instruction.
For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): It will call __RV_FSW to store floating point register into memory
For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): It will call __RV_FSD to store floating point register into memory
- Attention
Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
-
SAVE_FPU_CONTEXT()
Save FPU context into variables for interrupt nesting.
This macro is used to declare variables which are used for saving FPU context, and it will store the nessary fpu registers into these variables, it need to be used in a interrupt when in this interrupt fpu registers are used.
Remark
It need to be used together with RESTORE_FPU_CONTEXT
Don’t use variable names __fpu_context in your ISR code
If you isr code will use fpu registers, and this interrupt is nested. Then you can do it like this:
void eclic_mtip_handler(void) { // !!!Interrupt is enabled here!!! // !!!Higher priority interrupt could nest it!!! // Necessary only when you need to use fpu registers // in this isr handler functions SAVE_FPU_CONTEXT(); // put you own interrupt handling code here // pair of SAVE_FPU_CONTEXT() RESTORE_FPU_CONTEXT(); }
-
RESTORE_FPU_CONTEXT()
Restore necessary fpu registers from variables for interrupt nesting.
This macro is used restore necessary fpu registers from pre-defined variables in SAVE_FPU_CONTEXT macro.
Remark
It need to be used together with SAVE_FPU_CONTEXT
Typedefs
-
typedef uint64_t rv_fpu_t
Type of FPU register, depends on the FLEN defined in RISC-V.