From db0ca1924e5e3ac19b44010e7195b9461ad1c14c Mon Sep 17 00:00:00 2001 From: Yongbok Kim Date: Mon, 27 Aug 2018 05:02:06 -0400 Subject: [PATCH] target/mips: Add emulation of misc nanoMIPS instructions (pool32axf) Add emulation of misc nanoMIPS instructions situated in pool32axf. Backports commit 642241870a029da1525ad1641e1c99d434580817 from qemu --- qemu/target/mips/translate.c | 92 ++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 629869a5..0567ec4b 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -17151,6 +17151,90 @@ static void gen_pool32a0_nanomips_insn(DisasContext *ctx) } } +static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) +{ +#ifndef CONFIG_USER_ONLY + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + int rt = extract32(ctx->opcode, 21, 5); + int rs = extract32(ctx->opcode, 16, 5); +#endif + + switch (extract32(ctx->opcode, 6, 3)) { + case NM_POOL32AXF_4: + case NM_POOL32AXF_5: + switch (extract32(ctx->opcode, 9, 7)) { +#ifndef CONFIG_USER_ONLY + case NM_TLBP: + gen_cp0(env, ctx, OPC_TLBP, 0, 0); + break; + case NM_TLBR: + gen_cp0(env, ctx, OPC_TLBR, 0, 0); + break; + case NM_TLBWI: + gen_cp0(env, ctx, OPC_TLBWI, 0, 0); + break; + case NM_TLBWR: + gen_cp0(env, ctx, OPC_TLBWR, 0, 0); + break; + case NM_TLBINV: + gen_cp0(env, ctx, OPC_TLBINV, 0, 0); + break; + case NM_TLBINVF: + gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); + break; + case NM_DI: + check_cp0_enabled(ctx); + { + TCGv t0 = tcg_temp_new(tcg_ctx); + + save_cpu_state(ctx, 1); + gen_helper_di(tcg_ctx, t0, tcg_ctx->cpu_env); + gen_store_gpr(tcg_ctx, t0, rt); + /* Stop translation as we may have switched the execution mode */ + ctx->base.is_jmp = DISAS_STOP; + tcg_temp_free(tcg_ctx, t0); + } + break; + case NM_EI: + check_cp0_enabled(ctx); + { + TCGv t0 = tcg_temp_new(tcg_ctx); + + save_cpu_state(ctx, 1); + gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env); + gen_store_gpr(ctx, t0, rt); + /* Stop translation as we may have switched the execution mode */ + ctx->base.is_jmp = DISAS_STOP; + tcg_temp_free(tcg_ctx, t0); + } + break; + case NM_RDPGPR: + gen_load_srsgpr(rs, rt); + break; + case NM_WRPGPR: + gen_store_srsgpr(rs, rt); + break; + case NM_WAIT: + gen_cp0(env, ctx, OPC_WAIT, 0, 0); + break; + case NM_DERET: + gen_cp0(env, ctx, OPC_DERET, 0, 0); + break; + case NM_ERETX: + gen_cp0(env, ctx, OPC_ERET, 0, 0); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + static void gen_pool32f_nanomips_insn(DisasContext *ctx) { int rt, rs, rd; @@ -17523,6 +17607,14 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_pool32a0_nanomips_insn(ctx); break; case NM_POOL32A7: + switch (extract32(ctx->opcode, 3, 3)) { + case NM_POOL32AXF: + gen_pool32axf_nanomips_insn(env, ctx); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } break; default: generate_exception_end(ctx, EXCP_RI);