mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 08:48:13 +00:00
mips: handle delay slot better for branch instructions. this should fix issue #155
This commit is contained in:
parent
4a2092fa10
commit
53ce8f217d
2 changed files with 17 additions and 11 deletions
|
@ -11322,7 +11322,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
|
|||
return 4;
|
||||
}
|
||||
|
||||
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
||||
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||
|
@ -11343,7 +11343,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
|||
n_bytes = 2;
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
if (!is_slot && env->uc->hook_insn) {
|
||||
if (!is_bc_slot && env->uc->hook_insn) {
|
||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||
if (trace)
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||
|
@ -13928,7 +13928,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
||||
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||
{
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||
|
@ -13943,7 +13943,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int is_sl
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
if (!is_slot && env->uc->hook_insn) {
|
||||
if (!is_bc_slot && env->uc->hook_insn) {
|
||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||
if (trace)
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||
|
@ -18503,7 +18503,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
||||
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
#if defined(TARGET_MIPS64)
|
||||
|
@ -18523,7 +18523,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
|||
}
|
||||
|
||||
// Unicorn: trace this instruction on request
|
||||
if (!is_slot && env->uc->hook_insn) {
|
||||
if (!is_bc_slot && env->uc->hook_insn) {
|
||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||
if (trace)
|
||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||
|
@ -19171,6 +19171,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||
int max_insns;
|
||||
int insn_bytes;
|
||||
int is_slot = 0;
|
||||
bool is_bc_slot = false;
|
||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||
TCGArg *save_opparam_ptr = NULL;
|
||||
bool block_full = false;
|
||||
|
@ -19272,16 +19273,18 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||
save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
||||
|
||||
is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
|
||||
is_bc_slot = (is_slot & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BC;
|
||||
|
||||
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
|
||||
ctx.opcode = cpu_ldl_code(env, ctx.pc);
|
||||
insn_bytes = 4;
|
||||
decode_opc(env, &ctx, is_slot);
|
||||
decode_opc(env, &ctx, is_bc_slot);
|
||||
} else if (ctx.insn_flags & ASE_MICROMIPS) {
|
||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||
insn_bytes = decode_micromips_opc(env, &ctx, is_slot);
|
||||
insn_bytes = decode_micromips_opc(env, &ctx, is_bc_slot);
|
||||
} else if (ctx.insn_flags & ASE_MIPS16) {
|
||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||
insn_bytes = decode_mips16_opc(env, &ctx, is_slot);
|
||||
insn_bytes = decode_mips16_opc(env, &ctx, is_bc_slot);
|
||||
} else {
|
||||
generate_exception(&ctx, EXCP_RI);
|
||||
ctx.bstate = BS_STOP;
|
||||
|
@ -19289,18 +19292,19 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
|||
}
|
||||
|
||||
// Unicorn: patch the callback for the instruction size
|
||||
if (env->uc->hook_insn)
|
||||
if (!is_bc_slot && env->uc->hook_insn)
|
||||
*(save_opparam_ptr + 1) = insn_bytes;
|
||||
}
|
||||
|
||||
if (ctx.hflags & MIPS_HFLAG_BMASK) {
|
||||
if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
|
||||
MIPS_HFLAG_FBNSLOT))) {
|
||||
MIPS_HFLAG_FBNSLOT))) {
|
||||
/* force to generate branch as there is neither delay nor
|
||||
forbidden slot */
|
||||
is_slot = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_slot) {
|
||||
gen_branch(&ctx, insn_bytes);
|
||||
}
|
||||
|
|
2
tests/regress/mips_single_step_sp.py
Normal file → Executable file
2
tests/regress/mips_single_step_sp.py
Normal file → Executable file
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from unicorn import *
|
||||
from unicorn.mips_const import *
|
||||
|
||||
|
|
Loading…
Reference in a new issue