Commit a50f98b0 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/jovanovic/mips-ufrp' into staging



* remotes/jovanovic/mips-ufrp:
  target-mips: add user-mode FR switch support for MIPS32r5
  target-mips: add support for CP0_Config5
  target-mips: add support for CP0_Config4
  target-mips: add CPU definition for MIPS32R5

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 933b19ea 736d120a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ struct CPUMIPSFPUContext {
    float_status fp_status;
    /* fpu implementation/revision register (fir) */
    uint32_t fcr0;
#define FCR0_UFRP 28
#define FCR0_F64 22
#define FCR0_L 21
#define FCR0_W 20
@@ -368,6 +369,18 @@ struct CPUMIPSState {
#define CP0C3_MT   2
#define CP0C3_SM   1
#define CP0C3_TL   0
    uint32_t CP0_Config4;
    uint32_t CP0_Config4_rw_bitmask;
#define CP0C4_M    31
    uint32_t CP0_Config5;
    uint32_t CP0_Config5_rw_bitmask;
#define CP0C5_M          31
#define CP0C5_K          30
#define CP0C5_CV         29
#define CP0C5_EVA        28
#define CP0C5_MSAEn      27
#define CP0C5_UFR        2
#define CP0C5_NFExists   0
    int32_t CP0_Config6;
    int32_t CP0_Config7;
    /* XXX: Maybe make LLAddr per-TC? */
+3 −1
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@ DEF_HELPER_2(mtc0_ebase, void, env, tl)
DEF_HELPER_2(mttc0_ebase, void, env, tl)
DEF_HELPER_2(mtc0_config0, void, env, tl)
DEF_HELPER_2(mtc0_config2, void, env, tl)
DEF_HELPER_2(mtc0_config4, void, env, tl)
DEF_HELPER_2(mtc0_config5, void, env, tl)
DEF_HELPER_2(mtc0_lladdr, void, env, tl)
DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
@@ -177,7 +179,7 @@ DEF_HELPER_2(yield, tl, env, tl)

/* CP1 functions */
DEF_HELPER_2(cfc1, tl, env, i32)
DEF_HELPER_3(ctc1, void, env, tl, i32)
DEF_HELPER_4(ctc1, void, env, tl, i32, i32)

DEF_HELPER_2(float_cvtd_s, i64, env, i32)
DEF_HELPER_2(float_cvtd_w, i64, env, i32)
+8 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
#define		ISA_MIPS32R2	0x00000040
#define		ISA_MIPS64	0x00000080
#define		ISA_MIPS64R2	0x00000100
#define   ISA_MIPS32R3  0x00000200
#define   ISA_MIPS32R5  0x00000400

/* MIPS ASEs. */
#define		ASE_MIPS16	0x00001000
@@ -64,6 +66,12 @@
#define		CPU_MIPS32R2	(CPU_MIPS32 | ISA_MIPS32R2)
#define		CPU_MIPS64R2	(CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)

/* MIPS Technologies "Release 3" */
#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3)

/* MIPS Technologies "Release 5" */
#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5)

/* Strictly follow the architecture standard:
   - Disallow "special" instruction handling for PMON/SPIM.
   Note that we still maintain Count/Compare to match the host clock. */
+50 −3
Original line number Diff line number Diff line
@@ -1489,6 +1489,18 @@ void helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1)
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
}

void helper_mtc0_config4(CPUMIPSState *env, target_ulong arg1)
{
    env->CP0_Config4 = (env->CP0_Config4 & (~env->CP0_Config4_rw_bitmask)) |
                       (arg1 & env->CP0_Config4_rw_bitmask);
}

void helper_mtc0_config5(CPUMIPSState *env, target_ulong arg1)
{
    env->CP0_Config5 = (env->CP0_Config5 & (~env->CP0_Config5_rw_bitmask)) |
                       (arg1 & env->CP0_Config5_rw_bitmask);
}

void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
{
    target_long mask = env->CP0_LLAddr_rw_bitmask;
@@ -2187,12 +2199,23 @@ static inline void restore_flush_mode(CPUMIPSState *env)

target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
{
    target_ulong arg1;
    target_ulong arg1 = 0;

    switch (reg) {
    case 0:
        arg1 = (int32_t)env->active_fpu.fcr0;
        break;
    case 1:
        /* UFR Support - Read Status FR */
        if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
            if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
                arg1 = (int32_t)
                       ((env->CP0_Status & (1  << CP0St_FR)) >> CP0St_FR);
            } else {
                helper_raise_exception(env, EXCP_RI);
            }
        }
        break;
    case 25:
        arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1);
        break;
@@ -2210,9 +2233,33 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
    return arg1;
}

void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t reg)
void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
{
    switch(reg) {
    switch (fs) {
    case 1:
        /* UFR Alias - Reset Status FR */
        if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
            return;
        }
        if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
            env->CP0_Status &= ~(1 << CP0St_FR);
            compute_hflags(env);
        } else {
            helper_raise_exception(env, EXCP_RI);
        }
        break;
    case 4:
        /* UNFR Alias - Set Status FR */
        if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
            return;
        }
        if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
            env->CP0_Status |= (1 << CP0St_FR);
            compute_hflags(env);
        } else {
            helper_raise_exception(env, EXCP_RI);
        }
        break;
    case 25:
        if (arg1 & 0xffffff00)
            return;
+35 −4
Original line number Diff line number Diff line
@@ -4405,7 +4405,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
            rn = "Config3";
            break;
        /* 4,5 are reserved */
        case 4:
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
            rn = "Config4";
            break;
        case 5:
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
            rn = "Config5";
            break;
        /* 6,7 are implementation dependent */
        case 6:
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
@@ -4982,7 +4989,17 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
            /* ignored, read only */
            rn = "Config3";
            break;
        /* 4,5 are reserved */
        case 4:
            gen_helper_mtc0_config4(cpu_env, arg);
            rn = "Config4";
            ctx->bstate = BS_STOP;
            break;
        case 5:
            gen_helper_mtc0_config5(cpu_env, arg);
            rn = "Config5";
            /* Stop translation as we may have switched the execution mode */
            ctx->bstate = BS_STOP;
            break;
        /* 6,7 are implementation dependent */
        case 6:
            /* ignored */
@@ -6801,7 +6818,12 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
        break;
    case 3:
        /* XXX: For now we support only a single FPU context. */
        gen_helper_0e1i(ctc1, t0, rd);
        {
            TCGv_i32 fs_tmp = tcg_const_i32(rd);

            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
            tcg_temp_free_i32(fs_tmp);
        }
        break;
    /* COP2: Not implemented. */
    case 4:
@@ -7237,7 +7259,12 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
        break;
    case OPC_CTC1:
        gen_load_gpr(t0, rt);
        gen_helper_0e1i(ctc1, t0, fs);
        {
            TCGv_i32 fs_tmp = tcg_const_i32(fs);

            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
            tcg_temp_free_i32(fs_tmp);
        }
        opn = "ctc1";
        break;
#if defined(TARGET_MIPS64)
@@ -15916,6 +15943,10 @@ void cpu_state_reset(CPUMIPSState *env)
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
    env->CP0_Config4 = env->cpu_model->CP0_Config4;
    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
    env->CP0_Config5 = env->cpu_model->CP0_Config5;
    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
Loading