riscv: Add support for floating point

This change adds full shared floating point support for the RISCV
architecture with minimal impact on threads with floating point
support not enabled.

Signed-off-by: Corey Wharton <coreyw7@fb.com>
This commit is contained in:
Corey Wharton 2020-03-11 18:15:29 -07:00 committed by Andrew Boie
commit 58232d58e0
14 changed files with 667 additions and 18 deletions

View file

@ -40,13 +40,24 @@
#define RV_REGSHIFT 2
#endif
#ifdef CONFIG_FLOAT_64BIT
#define RV_OP_LOADFPREG fld
#define RV_OP_STOREFPREG fsd
#else
#define RV_OP_LOADFPREG flw
#define RV_OP_STOREFPREG fsw
#endif
/* Common mstatus bits. All supported cores today have the same
* layouts.
*/
#define MSTATUS_IEN (1UL << 3)
#define MSTATUS_MPP_M (3UL << 11)
#define MSTATUS_IEN (1UL << 3)
#define MSTATUS_MPP_M (3UL << 11)
#define MSTATUS_MPIE_EN (1UL << 7)
#define MSTATUS_FS_INIT (1UL << 13)
#define MSTATUS_FS_MASK ((1UL << 13) | (1UL << 14))
/* This comes from openisa_rv32m1, but doesn't seem to hurt on other
* platforms:

View file

@ -41,6 +41,14 @@ struct soc_esf {
};
#endif
#if !defined(RV_FP_TYPE) && defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
#ifdef CONFIG_FLOAT_64BIT
#define RV_FP_TYPE u64_t
#else
#define RV_FP_TYPE u32_t
#endif
#endif
struct __esf {
ulong_t ra; /* return address */
ulong_t gp; /* global pointer */
@ -66,6 +74,30 @@ struct __esf {
ulong_t mepc; /* machine exception program counter */
ulong_t mstatus; /* machine status register */
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
ulong_t fp_state; /* Floating-point saved context state. */
RV_FP_TYPE ft0; /* Caller-saved temporary floating register */
RV_FP_TYPE ft1; /* Caller-saved temporary floating register */
RV_FP_TYPE ft2; /* Caller-saved temporary floating register */
RV_FP_TYPE ft3; /* Caller-saved temporary floating register */
RV_FP_TYPE ft4; /* Caller-saved temporary floating register */
RV_FP_TYPE ft5; /* Caller-saved temporary floating register */
RV_FP_TYPE ft6; /* Caller-saved temporary floating register */
RV_FP_TYPE ft7; /* Caller-saved temporary floating register */
RV_FP_TYPE ft8; /* Caller-saved temporary floating register */
RV_FP_TYPE ft9; /* Caller-saved temporary floating register */
RV_FP_TYPE ft10; /* Caller-saved temporary floating register */
RV_FP_TYPE ft11; /* Caller-saved temporary floating register */
RV_FP_TYPE fa0; /* function argument/return value */
RV_FP_TYPE fa1; /* function argument/return value */
RV_FP_TYPE fa2; /* function argument */
RV_FP_TYPE fa3; /* function argument */
RV_FP_TYPE fa4; /* function argument */
RV_FP_TYPE fa5; /* function argument */
RV_FP_TYPE fa6; /* function argument */
RV_FP_TYPE fa7; /* function argument */
#endif
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
struct soc_esf soc_context;
#endif

View file

@ -22,6 +22,14 @@
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#if !defined(RV_FP_TYPE) && defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
#ifdef CONFIG_FLOAT_64BIT
#define RV_FP_TYPE u64_t
#else
#define RV_FP_TYPE u32_t
#endif
#endif
/*
* The following structure defines the list of registers that need to be
* saved/restored when a cooperative context switch occurs.
@ -41,6 +49,22 @@ struct _callee_saved {
ulong_t s9; /* saved register */
ulong_t s10; /* saved register */
ulong_t s11; /* saved register */
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
u32_t fcsr; /* Control and status register */
RV_FP_TYPE fs0; /* saved floating-point register */
RV_FP_TYPE fs1; /* saved floating-point register */
RV_FP_TYPE fs2; /* saved floating-point register */
RV_FP_TYPE fs3; /* saved floating-point register */
RV_FP_TYPE fs4; /* saved floating-point register */
RV_FP_TYPE fs5; /* saved floating-point register */
RV_FP_TYPE fs6; /* saved floating-point register */
RV_FP_TYPE fs7; /* saved floating-point register */
RV_FP_TYPE fs8; /* saved floating-point register */
RV_FP_TYPE fs9; /* saved floating-point register */
RV_FP_TYPE fs10; /* saved floating-point register */
RV_FP_TYPE fs11; /* saved floating-point register */
#endif
};
typedef struct _callee_saved _callee_saved_t;