Unverified Commit b345b480 authored by Alistair Francis's avatar Alistair Francis Committed by Palmer Dabbelt
Browse files

target/riscv: Create function to test if FP is enabled



Let's create a function that tests if floating point support is
enabled. We can then protect all floating point operations based on if
they are enabled.

This patch so far doesn't change anything, it's just preparing for the
Hypervisor support for floating point operations.

Signed-off-by: default avatarAlistair Francis <alistair.francis@wdc.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: default avatarChristophe de Dinechin <dinechin@redhat.com>
Signed-off-by: default avatarPalmer Dabbelt <palmer@sifive.com>
parent f14d65e8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ void riscv_cpu_do_interrupt(CPUState *cpu);
int riscv_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
bool riscv_cpu_fp_enabled(CPURISCVState *env);
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
@@ -298,7 +299,10 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
#ifdef CONFIG_USER_ONLY
    *flags = TB_FLAGS_MSTATUS_FS;
#else
    *flags = cpu_mmu_index(env, 0) | (env->mstatus & MSTATUS_FS);
    *flags = cpu_mmu_index(env, 0);
    if (riscv_cpu_fp_enabled(env)) {
        *flags |= env->mstatus & MSTATUS_FS;
    }
#endif
}

+10 −0
Original line number Diff line number Diff line
@@ -71,6 +71,16 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)

#if !defined(CONFIG_USER_ONLY)

/* Return true is floating point support is currently enabled */
bool riscv_cpu_fp_enabled(CPURISCVState *env)
{
    if (env->mstatus & MSTATUS_FS) {
        return true;
    }

    return false;
}

int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
{
    CPURISCVState *env = &cpu->env;
+11 −9
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
static int fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
#endif
@@ -108,7 +108,7 @@ static int pmp(CPURISCVState *env, int csrno)
static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
#endif
@@ -119,7 +119,7 @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
    env->mstatus |= MSTATUS_FS;
@@ -131,7 +131,7 @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
#endif
@@ -142,7 +142,7 @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
    env->mstatus |= MSTATUS_FS;
@@ -154,7 +154,7 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
#endif
@@ -166,7 +166,7 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
    if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
    if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
        return -1;
    }
    env->mstatus |= MSTATUS_FS;
@@ -307,6 +307,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
{
    target_ulong mstatus = env->mstatus;
    target_ulong mask = 0;
    int dirty;

    /* flush tlb on mstatus fields that affect VM */
    if (env->priv_ver <= PRIV_VERSION_1_09_1) {
@@ -340,7 +341,8 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)

    mstatus = (mstatus & ~mask) | (val & mask);

    int dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
    dirty = (riscv_cpu_fp_enabled(env) &&
             ((mstatus & MSTATUS_FS) == MSTATUS_FS)) |
            ((mstatus & MSTATUS_XS) == MSTATUS_XS);
    mstatus = set_field(mstatus, MSTATUS_SD, dirty);
    env->mstatus = mstatus;