mips: handle delay slot so do not duplicate calling instruction handler. this fixes issue #133

This commit is contained in:
Nguyen Anh Quynh 2015-09-22 11:59:53 +08:00
parent 80c316026f
commit 14a01b5186
2 changed files with 16 additions and 16 deletions

View file

@ -1415,7 +1415,7 @@ enum {
* exception condition */ * exception condition */
BS_STOP = 1, /* We want to stop translation for any reason */ BS_STOP = 1, /* We want to stop translation for any reason */
BS_BRANCH = 2, /* We reached a branch condition */ BS_BRANCH = 2, /* We reached a branch condition */
BS_EXCP = 3, /* We reached an exception condition */ // qq BS_EXCP = 3, /* We reached an exception condition */
}; };
static const char * const regnames[] = { static const char * const regnames[] = {
@ -11322,7 +11322,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
return 4; return 4;
} }
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx) static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
{ {
TCGContext *tcg_ctx = ctx->uc->tcg_ctx; TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr; TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
@ -11343,7 +11343,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
n_bytes = 2; n_bytes = 2;
// Unicorn: trace this instruction on request // Unicorn: trace this instruction on request
if (env->uc->hook_insn) { if (!is_slot && env->uc->hook_insn) {
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc); struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace) if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data); 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) static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
{ {
TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGContext *tcg_ctx = env->uc->tcg_ctx;
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr; TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
@ -13943,7 +13943,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
} }
// Unicorn: trace this instruction on request // Unicorn: trace this instruction on request
if (env->uc->hook_insn) { if (!is_slot && env->uc->hook_insn) {
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc); struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace) if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data); 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) static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
{ {
TCGContext *tcg_ctx = ctx->uc->tcg_ctx; TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
#if defined(TARGET_MIPS64) #if defined(TARGET_MIPS64)
@ -18514,6 +18514,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
uint32_t op, op1; uint32_t op, op1;
int16_t imm; int16_t imm;
/* make sure instructions are on a word boundary */ /* make sure instructions are on a word boundary */
if (ctx->pc & 0x3) { if (ctx->pc & 0x3) {
env->CP0_BadVAddr = ctx->pc; env->CP0_BadVAddr = ctx->pc;
@ -18522,7 +18523,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
} }
// Unicorn: trace this instruction on request // Unicorn: trace this instruction on request
if (env->uc->hook_insn) { if (!is_slot && env->uc->hook_insn) {
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc); struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace) if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data); gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
@ -19227,7 +19228,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
} }
gen_tb_start(tcg_ctx); gen_tb_start(tcg_ctx);
while (ctx.bstate == BS_NONE) { // qq while (ctx.bstate == BS_NONE) {
if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == ctx.pc) { if (bp->pc == ctx.pc) {
@ -19268,16 +19269,16 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
save_opparam_ptr = tcg_ctx->gen_opparam_ptr; save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
is_slot = ctx.hflags & MIPS_HFLAG_BMASK; is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
if (!(ctx.hflags & MIPS_HFLAG_M16)) { // qq if (!(ctx.hflags & MIPS_HFLAG_M16)) {
ctx.opcode = cpu_ldl_code(env, ctx.pc); ctx.opcode = cpu_ldl_code(env, ctx.pc);
insn_bytes = 4; insn_bytes = 4;
decode_opc(env, &ctx); decode_opc(env, &ctx, is_slot);
} else if (ctx.insn_flags & ASE_MICROMIPS) { // qq } else if (ctx.insn_flags & ASE_MICROMIPS) {
ctx.opcode = cpu_lduw_code(env, ctx.pc); ctx.opcode = cpu_lduw_code(env, ctx.pc);
insn_bytes = decode_micromips_opc(env, &ctx); insn_bytes = decode_micromips_opc(env, &ctx, is_slot);
} else if (ctx.insn_flags & ASE_MIPS16) { // qq } else if (ctx.insn_flags & ASE_MIPS16) {
ctx.opcode = cpu_lduw_code(env, ctx.pc); ctx.opcode = cpu_lduw_code(env, ctx.pc);
insn_bytes = decode_mips16_opc(env, &ctx); insn_bytes = decode_mips16_opc(env, &ctx, is_slot);
} else { } else {
generate_exception(&ctx, EXCP_RI); generate_exception(&ctx, EXCP_RI);
ctx.bstate = BS_STOP; ctx.bstate = BS_STOP;

View file

@ -1,7 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from capstone import * from capstone import *
from unicorn import * from unicorn import *
from unicorn.mips_const import *
import regress import regress
@ -19,7 +18,7 @@ class MipsBranchDelay(regress.RegressTest):
disas(mem, addr) disas(mem, addr)
CODE = 0x400000 CODE = 0x400000
asm = '0000a4126a00822800000000'.decode('hex') asm = '0000a4126a00822800000000'.decode('hex') # beq $a0, $s5, 0x4008a0; slti $v0, $a0, 0x6a; nop
print 'Input instructions:' print 'Input instructions:'
disas(asm, CODE) disas(asm, CODE)