Commit 0a1a6ed7 authored by Stefan Markovic's avatar Stefan Markovic Committed by Aleksandar Markovic
Browse files

target/mips: Implement MT ASE support for nanoMIPS



Add emulation of MT ASE instructions for nanoMIPS.

Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Signed-off-by: default avatarAleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: default avatarStefan Markovic <smarkovic@wavecomp.com>
parent 9affc1c5
Loading
Loading
Loading
Loading
+83 −2
Original line number Diff line number Diff line
@@ -16989,7 +16989,7 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
    }
}
static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
{
    int rt = extract32(ctx->opcode, 21, 5);
    int rs = extract32(ctx->opcode, 16, 5);
@@ -17157,6 +17157,87 @@ static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
            tcg_temp_free(t0);
        }
        break;
    case NM_D_E_MT_VPE:
        {
            uint8_t sc = extract32(ctx->opcode, 10, 1);
            TCGv t0 = tcg_temp_new();
            switch (sc) {
            case 0:
                if (rs == 1) {
                    /* DMT */
                    check_cp0_mt(ctx);
                    gen_helper_dmt(t0);
                    gen_store_gpr(t0, rt);
                } else if (rs == 0) {
                    /* DVPE */
                    check_cp0_mt(ctx);
                    gen_helper_dvpe(t0, cpu_env);
                    gen_store_gpr(t0, rt);
                } else {
                    generate_exception_end(ctx, EXCP_RI);
                }
                break;
            case 1:
                if (rs == 1) {
                    /* EMT */
                    check_cp0_mt(ctx);
                    gen_helper_emt(t0);
                    gen_store_gpr(t0, rt);
                } else if (rs == 0) {
                    /* EVPE */
                    check_cp0_mt(ctx);
                    gen_helper_evpe(t0, cpu_env);
                    gen_store_gpr(t0, rt);
                } else {
                    generate_exception_end(ctx, EXCP_RI);
                }
                break;
            }
            tcg_temp_free(t0);
        }
        break;
    case NM_FORK:
        check_mt(ctx);
        {
            TCGv t0 = tcg_temp_new();
            TCGv t1 = tcg_temp_new();
            gen_load_gpr(t0, rt);
            gen_load_gpr(t1, rs);
            gen_helper_fork(t0, t1);
            tcg_temp_free(t0);
            tcg_temp_free(t1);
        }
        break;
    case NM_MFTR:
    case NM_MFHTR:
        check_cp0_enabled(ctx);
        if (rd == 0) {
            /* Treat as NOP. */
            return;
        }
        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
        break;
    case NM_MTTR:
    case NM_MTHTR:
        check_cp0_enabled(ctx);
        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
        break;
    case NM_YIELD:
        check_mt(ctx);
        {
            TCGv t0 = tcg_temp_new();
            gen_load_gpr(t0, rs);
            gen_helper_yield(t0, cpu_env, t0);
            gen_store_gpr(t0, rt);
            tcg_temp_free(t0);
        }
        break;
#endif
    default:
        generate_exception_end(ctx, EXCP_RI);
@@ -18049,7 +18130,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
    case NM_POOL32A:
        switch (ctx->opcode & 0x07) {
        case NM_POOL32A0:
            gen_pool32a0_nanomips_insn(ctx);
            gen_pool32a0_nanomips_insn(env, ctx);
            break;
        case NM_POOL32A7:
            switch (extract32(ctx->opcode, 3, 3)) {