Commit a465772e authored by Richard Henderson's avatar Richard Henderson
Browse files

target/openrisc: Implement move to/from FPCSR

parent 2b13b4b9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ static void openrisc_cpu_reset(CPUState *s)
    cpu->env.sr = SR_FO | SR_SM;
    cpu->env.lock_addr = -1;
    s->exception_index = -1;
    cpu_set_fpcsr(&cpu->env, 0);

#ifndef CONFIG_USER_ONLY
    cpu->env.picmr = 0x00000000;
+2 −0
Original line number Diff line number Diff line
@@ -413,6 +413,8 @@ static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
}

void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val);

#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0

#endif /* OPENRISC_CPU_H */
+13 −0
Original line number Diff line number Diff line
@@ -61,6 +61,19 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
    }
}

void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val)
{
    static const int rm_to_sf[] = {
        float_round_nearest_even,
        float_round_to_zero,
        float_round_up,
        float_round_down
    };

    env->fpcsr = val & 0x7ff;
    set_float_rounding_mode(rm_to_sf[extract32(val, 1, 2)], &env->fp_status);
}

uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
{
    return int64_to_float64(val, &env->fp_status);
+11 −0
Original line number Diff line number Diff line
@@ -121,10 +121,21 @@ static const VMStateDescription vmstate_env = {
    }
};

static int cpu_post_load(void *opaque, int version_id)
{
    OpenRISCCPU *cpu = opaque;
    CPUOpenRISCState *env = &cpu->env;

    /* Update env->fp_status to match env->fpcsr.  */
    cpu_set_fpcsr(env, env->fpcsr);
    return 0;
}

const VMStateDescription vmstate_openrisc_cpu = {
    .name = "cpu",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = cpu_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_CPU(),
        VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState),
+11 −5
Original line number Diff line number Diff line
@@ -37,8 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
    CPUState *cs = env_cpu(env);
    target_ulong mr;
    int idx;
#endif

    switch (spr) {
#ifndef CONFIG_USER_ONLY
    case TO_SPR(0, 11): /* EVBAR */
        env->evbar = rb;
        break;
@@ -179,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
        }
        cpu_openrisc_timer_update(cpu);
        break;
    default:
#endif

    case TO_SPR(0, 20): /* FPCSR */
        cpu_set_fpcsr(env, rb);
        break;
    }
#endif
}

target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
@@ -193,8 +197,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
    OpenRISCCPU *cpu = env_archcpu(env);
    CPUState *cs = env_cpu(env);
    int idx;
#endif

    switch (spr) {
#ifndef CONFIG_USER_ONLY
    case TO_SPR(0, 0): /* VR */
        return env->vr;

@@ -303,11 +309,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
    case TO_SPR(10, 1): /* TTCR */
        cpu_openrisc_count_update(cpu);
        return cpu_openrisc_count_get(cpu);
#endif

    default:
        break;
    case TO_SPR(0, 20): /* FPCSR */
        return env->fpcsr;
    }
#endif

    /* for rd is passed in, if rd unchanged, just keep it back.  */
    return rd;