mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 19:51:10 +00:00
target/mips: convert to DisasJumpType
Notes: - BS_EXCP in generate_exception_err and after hen_helper_wait becomes DISAS_NORETURN, because we do not return after raising an exception. - Some uses of BS_EXCP are misleading in that they're used only as a "not BS_STOP" exit condition, i.e. they have nothing to do with an actual exception. For those cases, define and use DISAS_EXIT, which is clearer. With this and the above change, BS_EXCP goes away completely. - fix a comment typo (s/intetrupt/interrupt/). Backports commit b28425babc2ad4b90cd87d07a1809d3322b9c065 from qemu
This commit is contained in:
parent
8a416b8146
commit
de5d90f9a4
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "exec/gen-icount.h"
|
#include "exec/gen-icount.h"
|
||||||
|
|
||||||
|
#include "exec/translator.h"
|
||||||
|
|
||||||
#define MIPS_DEBUG_DISAS 0
|
#define MIPS_DEBUG_DISAS 0
|
||||||
|
|
||||||
/* MIPS major opcodes */
|
/* MIPS major opcodes */
|
||||||
|
@ -1424,7 +1426,7 @@ typedef struct DisasContext {
|
||||||
int mem_idx;
|
int mem_idx;
|
||||||
TCGMemOp default_tcg_memop_mask;
|
TCGMemOp default_tcg_memop_mask;
|
||||||
uint32_t hflags, saved_hflags;
|
uint32_t hflags, saved_hflags;
|
||||||
int bstate;
|
DisasJumpType is_jmp;
|
||||||
target_ulong btarget;
|
target_ulong btarget;
|
||||||
bool ulri;
|
bool ulri;
|
||||||
int kscrexist;
|
int kscrexist;
|
||||||
|
@ -1447,13 +1449,8 @@ typedef struct DisasContext {
|
||||||
struct uc_struct *uc;
|
struct uc_struct *uc;
|
||||||
} DisasContext;
|
} DisasContext;
|
||||||
|
|
||||||
enum {
|
#define DISAS_STOP DISAS_TARGET_0
|
||||||
BS_NONE = 0, /* We go out of the TB without reaching a branch or an
|
#define DISAS_EXIT DISAS_TARGET_1
|
||||||
* exception condition */
|
|
||||||
BS_STOP = 1, /* We want to stop translation for any reason */
|
|
||||||
BS_BRANCH = 2, /* We reached a branch condition */
|
|
||||||
BS_EXCP = 3, /* We reached an exception condition */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char * const regnames[] = {
|
static const char * const regnames[] = {
|
||||||
"r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
"r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||||
|
@ -1634,7 +1631,7 @@ static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
|
||||||
gen_helper_raise_exception_err(tcg_ctx, tcg_ctx->cpu_env, texcp, terr);
|
gen_helper_raise_exception_err(tcg_ctx, tcg_ctx->cpu_env, texcp, terr);
|
||||||
tcg_temp_free_i32(tcg_ctx, terr);
|
tcg_temp_free_i32(tcg_ctx, terr);
|
||||||
tcg_temp_free_i32(tcg_ctx, texcp);
|
tcg_temp_free_i32(tcg_ctx, texcp);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_NORETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void generate_exception(DisasContext *ctx, int excp)
|
static inline void generate_exception(DisasContext *ctx, int excp)
|
||||||
|
@ -5410,10 +5407,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
// gen_io_end();
|
// gen_io_end();
|
||||||
//}
|
//}
|
||||||
/* Break the TB to be able to take timer interrupts immediately
|
/* Break the TB to be able to take timer interrupts immediately
|
||||||
after reading count. BS_STOP isn't sufficient, we need to ensure
|
after reading count. DISAS_STOP isn't sufficient, we need to
|
||||||
we break completely out of translated code. */
|
ensure we break completely out of translated code. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Count";
|
rn = "Count";
|
||||||
break;
|
break;
|
||||||
/* 6,7 are implementation dependent */
|
/* 6,7 are implementation dependent */
|
||||||
|
@ -5983,7 +5980,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_pagegrain(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_pagegrain(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "PageGrain";
|
rn = "PageGrain";
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
CP0_CHECK(ctx->sc);
|
CP0_CHECK(ctx->sc);
|
||||||
|
@ -6044,7 +6041,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
case 0:
|
case 0:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "HWREna";
|
rn = "HWREna";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -6106,30 +6103,30 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
case 0:
|
case 0:
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* BS_STOP isn't good enough here, hflags may have changed. */
|
/* DISAS_STOP isn't good enough here, hflags may have changed. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Status";
|
rn = "Status";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "IntCtl";
|
rn = "IntCtl";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "SRSCtl";
|
rn = "SRSCtl";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
|
gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "SRSMap";
|
rn = "SRSMap";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -6141,11 +6138,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
case 0:
|
case 0:
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have triggered an interrupt. BS_STOP
|
/* Stop translation as we may have triggered an interrupt.
|
||||||
* isn't sufficient, we need to ensure we break out of translated
|
* DISAS_STOP isn't sufficient, we need to ensure we break out of
|
||||||
* code to check for pending interrupts. */
|
* translated code to check for pending interrupts. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Cause";
|
rn = "Cause";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -6183,7 +6180,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config";
|
rn = "Config";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* ignored, read only */
|
/* ignored, read only */
|
||||||
|
@ -6193,24 +6190,24 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config2";
|
rn = "Config2";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
gen_helper_mtc0_config3(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config3(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config3";
|
rn = "Config3";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
gen_helper_mtc0_config4(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config4(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config4";
|
rn = "Config4";
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config5";
|
rn = "Config5";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
/* 6,7 are implementation dependent */
|
/* 6,7 are implementation dependent */
|
||||||
case 6:
|
case 6:
|
||||||
|
@ -6299,35 +6296,35 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
|
gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
|
||||||
/* BS_STOP isn't good enough here, hflags may have changed. */
|
/* DISAS_STOP isn't good enough here, hflags may have changed. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Debug";
|
rn = "Debug";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
rn = "TraceControl";
|
rn = "TraceControl";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 2:
|
case 2:
|
||||||
// gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
rn = "TraceControl2";
|
rn = "TraceControl2";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 3:
|
case 3:
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
// gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
rn = "UserTraceData";
|
rn = "UserTraceData";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 4:
|
case 4:
|
||||||
// gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "TraceBPC";
|
rn = "TraceBPC";
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
default:
|
default:
|
||||||
|
@ -6387,7 +6384,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_errctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_errctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "ErrCtl";
|
rn = "ErrCtl";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -6483,7 +6480,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
// /* BS_STOP isn't sufficient, we need to ensure we break out of
|
// /* BS_STOP isn't sufficient, we need to ensure we break out of
|
||||||
// * translated code to check for pending interrupts. */
|
// * translated code to check for pending interrupts. */
|
||||||
// gen_save_pc(ctx, ctx->pc + 4);
|
// gen_save_pc(ctx, ctx->pc + 4);
|
||||||
// ctx->bstate = BS_EXCP;
|
// ctx->is_jmp = DISAS_EXIT;
|
||||||
//}
|
//}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -6765,10 +6762,10 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
// gen_io_end();
|
// gen_io_end();
|
||||||
//}
|
//}
|
||||||
/* Break the TB to be able to take timer interrupts immediately
|
/* Break the TB to be able to take timer interrupts immediately
|
||||||
after reading count. BS_STOP isn't sufficient, we need to ensure
|
after reading count. DISAS_STOP isn't sufficient, we need to
|
||||||
we break completely out of translated code. */
|
ensure we break completely out of translated code. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Count";
|
rn = "Count";
|
||||||
break;
|
break;
|
||||||
/* 6,7 are implementation dependent */
|
/* 6,7 are implementation dependent */
|
||||||
|
@ -7382,7 +7379,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
case 0:
|
case 0:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_hwrena(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "HWREna";
|
rn = "HWREna";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -7418,7 +7415,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
}
|
}
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
|
@ -7441,7 +7438,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
}
|
}
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
|
@ -7450,28 +7447,28 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_status(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* BS_STOP isn't good enough here, hflags may have changed. */
|
/* BS_STOP isn't good enough here, hflags may have changed. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Status";
|
rn = "Status";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_intctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "IntCtl";
|
rn = "IntCtl";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_srsctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "SRSCtl";
|
rn = "SRSCtl";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
|
gen_mtc0_store32(ctx, arg, offsetof(CPUMIPSState, CP0_SRSMap));
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "SRSMap";
|
rn = "SRSMap";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -7483,11 +7480,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
case 0:
|
case 0:
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_cause(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
/* Stop translation as we may have triggered an intetrupt. BS_STOP
|
/* Stop translation as we may have triggered an interrupt.
|
||||||
* isn't sufficient, we need to ensure we break out of translated
|
* DISAS_STOP isn't sufficient, we need to ensure we break out of
|
||||||
* code to check for pending interrupts. */
|
* translated code to check for pending interrupts. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Cause";
|
rn = "Cause";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -7525,7 +7522,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config0(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config";
|
rn = "Config";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* ignored, read only */
|
/* ignored, read only */
|
||||||
|
@ -7535,13 +7532,13 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config2(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config2";
|
rn = "Config2";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
gen_helper_mtc0_config3(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config3(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config3";
|
rn = "Config3";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
/* currently ignored */
|
/* currently ignored */
|
||||||
|
@ -7551,7 +7548,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_config5(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
rn = "Config5";
|
rn = "Config5";
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
/* 6,7 are implementation dependent */
|
/* 6,7 are implementation dependent */
|
||||||
default:
|
default:
|
||||||
|
@ -7630,33 +7627,33 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
|
gen_helper_mtc0_debug(tcg_ctx, tcg_ctx->cpu_env, arg); /* EJTAG support */
|
||||||
/* BS_STOP isn't good enough here, hflags may have changed. */
|
/* DISAS_STOP isn't good enough here, hflags may have changed. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
rn = "Debug";
|
rn = "Debug";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracecontrol(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "TraceControl";
|
rn = "TraceControl";
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 2:
|
case 2:
|
||||||
// gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracecontrol2(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "TraceControl2";
|
rn = "TraceControl2";
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 3:
|
case 3:
|
||||||
// gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_usertracedata(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "UserTraceData";
|
rn = "UserTraceData";
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
case 4:
|
case 4:
|
||||||
// gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
// gen_helper_mtc0_tracebpc(tcg_ctx->cpu_env, arg); /* PDtrace support */
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "TraceBPC";
|
rn = "TraceBPC";
|
||||||
goto cp0_unimplemented;
|
goto cp0_unimplemented;
|
||||||
default:
|
default:
|
||||||
|
@ -7716,7 +7713,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_mtc0_errctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
gen_helper_mtc0_errctl(tcg_ctx, tcg_ctx->cpu_env, arg);
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
rn = "ErrCtl";
|
rn = "ErrCtl";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -7809,10 +7806,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
||||||
/* For simplicity assume that all writes can cause interrupts. */
|
/* For simplicity assume that all writes can cause interrupts. */
|
||||||
//if (ctx->tb->cflags & CF_USE_ICOUNT) {
|
//if (ctx->tb->cflags & CF_USE_ICOUNT) {
|
||||||
// gen_io_end();
|
// gen_io_end();
|
||||||
// /* BS_STOP isn't sufficient, we need to ensure we break out of
|
// /* DISAS_STOP isn't sufficient, we need to ensure we break out of
|
||||||
// * translated code to check for pending interrupts. */
|
// * translated code to check for pending interrupts. */
|
||||||
// gen_save_pc(ctx, ctx->pc + 4);
|
// gen_save_pc(ctx, ctx->pc + 4);
|
||||||
// ctx->bstate = BS_EXCP;
|
// ctx->is_jmp = DISAS_EXIT;
|
||||||
//}
|
//}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -8225,7 +8222,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
|
||||||
tcg_temp_free_i32(tcg_ctx, fs_tmp);
|
tcg_temp_free_i32(tcg_ctx, fs_tmp);
|
||||||
}
|
}
|
||||||
/* Stop translation as we may have changed hflags */
|
/* Stop translation as we may have changed hflags */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
/* COP2: Not implemented. */
|
/* COP2: Not implemented. */
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -8386,7 +8383,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
|
||||||
check_insn(ctx, ISA_MIPS2);
|
check_insn(ctx, ISA_MIPS2);
|
||||||
gen_helper_eret(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_eret(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
}
|
}
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_DERET:
|
case OPC_DERET:
|
||||||
|
@ -8401,7 +8398,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
|
||||||
generate_exception_end(ctx, EXCP_RI);
|
generate_exception_end(ctx, EXCP_RI);
|
||||||
} else {
|
} else {
|
||||||
gen_helper_deret(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_deret(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_WAIT:
|
case OPC_WAIT:
|
||||||
|
@ -8416,7 +8413,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
ctx->pc -= 4;
|
ctx->pc -= 4;
|
||||||
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_NORETURN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die:
|
die:
|
||||||
|
@ -8844,7 +8841,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
|
||||||
tcg_temp_free_i32(tcg_ctx, fs_tmp);
|
tcg_temp_free_i32(tcg_ctx, fs_tmp);
|
||||||
}
|
}
|
||||||
/* Stop translation as we may have changed hflags */
|
/* Stop translation as we may have changed hflags */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
case OPC_DMFC1:
|
case OPC_DMFC1:
|
||||||
|
@ -10872,10 +10869,10 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
|
||||||
#endif
|
#endif
|
||||||
gen_store_gpr(tcg_ctx, t0, rt);
|
gen_store_gpr(tcg_ctx, t0, rt);
|
||||||
/* Break the TB to be able to take timer interrupts immediately
|
/* Break the TB to be able to take timer interrupts immediately
|
||||||
after reading count. BS_STOP isn't sufficient, we need to ensure
|
after reading count. DISAS_STOP isn't sufficient, we need to ensure
|
||||||
we break completely out of translated code. */
|
we break completely out of translated code. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
gen_helper_rdhwr_ccres(tcg_ctx, t0, tcg_ctx->cpu_env);
|
gen_helper_rdhwr_ccres(tcg_ctx, t0, tcg_ctx->cpu_env);
|
||||||
|
@ -10926,7 +10923,7 @@ static inline void clear_branch_hflags(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
ctx->hflags &= ~MIPS_HFLAG_BMASK;
|
ctx->hflags &= ~MIPS_HFLAG_BMASK;
|
||||||
if (ctx->bstate == BS_NONE) {
|
if (ctx->is_jmp == DISAS_NEXT) {
|
||||||
save_cpu_state(ctx, 0);
|
save_cpu_state(ctx, 0);
|
||||||
} else {
|
} else {
|
||||||
/* it is not safe to save ctx->hflags as hflags may be changed
|
/* it is not safe to save ctx->hflags as hflags may be changed
|
||||||
|
@ -10942,7 +10939,7 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
|
||||||
int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
|
int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
|
||||||
/* Branches completion */
|
/* Branches completion */
|
||||||
clear_branch_hflags(ctx);
|
clear_branch_hflags(ctx);
|
||||||
ctx->bstate = BS_BRANCH;
|
ctx->is_jmp = DISAS_NORETURN;
|
||||||
/* FIXME: Need to clear can_do_io. */
|
/* FIXME: Need to clear can_do_io. */
|
||||||
switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
|
switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
|
||||||
case MIPS_HFLAG_FBNSLOT:
|
case MIPS_HFLAG_FBNSLOT:
|
||||||
|
@ -13695,7 +13692,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
|
||||||
gen_helper_di(tcg_ctx, t0, tcg_ctx->cpu_env);
|
gen_helper_di(tcg_ctx, t0, tcg_ctx->cpu_env);
|
||||||
gen_store_gpr(tcg_ctx, t0, rs);
|
gen_store_gpr(tcg_ctx, t0, rs);
|
||||||
/* Stop translation as we may have switched the execution mode */
|
/* Stop translation as we may have switched the execution mode */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -13707,10 +13704,10 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
|
gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
|
||||||
gen_store_gpr(tcg_ctx, t0, rs);
|
gen_store_gpr(tcg_ctx, t0, rs);
|
||||||
/* BS_STOP isn't sufficient, we need to ensure we break out
|
/* DISAS_STOP isn't sufficient, we need to ensure we break out
|
||||||
of translated code to check for pending interrupts. */
|
of translated code to check for pending interrupts. */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -14862,7 +14859,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||||
/* SYNCI */
|
/* SYNCI */
|
||||||
/* Break the TB to be able to sync copied instructions
|
/* Break the TB to be able to sync copied instructions
|
||||||
immediately */
|
immediately */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
} else {
|
} else {
|
||||||
/* TNEI */
|
/* TNEI */
|
||||||
mips32_op = OPC_TNEI;
|
mips32_op = OPC_TNEI;
|
||||||
|
@ -14893,7 +14890,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||||
/* Break the TB to be able to sync copied instructions
|
/* Break the TB to be able to sync copied instructions
|
||||||
immediately */
|
immediately */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case BC2F:
|
case BC2F:
|
||||||
case BC2T:
|
case BC2T:
|
||||||
|
@ -19772,7 +19769,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx, bool *insn_need_pat
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
/* Break the TB to be able to sync copied instructions
|
/* Break the TB to be able to sync copied instructions
|
||||||
immediately */
|
immediately */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case OPC_BPOSGE32: /* MIPS DSP branch */
|
case OPC_BPOSGE32: /* MIPS DSP branch */
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
|
@ -19875,17 +19872,17 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx, bool *insn_need_pat
|
||||||
gen_store_gpr(tcg_ctx, t0, rt);
|
gen_store_gpr(tcg_ctx, t0, rt);
|
||||||
/* Stop translation as we may have switched
|
/* Stop translation as we may have switched
|
||||||
the execution mode. */
|
the execution mode. */
|
||||||
ctx->bstate = BS_STOP;
|
ctx->is_jmp = DISAS_STOP;
|
||||||
break;
|
break;
|
||||||
case OPC_EI:
|
case OPC_EI:
|
||||||
check_insn(ctx, ISA_MIPS32R2);
|
check_insn(ctx, ISA_MIPS32R2);
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
|
gen_helper_ei(tcg_ctx, t0, tcg_ctx->cpu_env);
|
||||||
gen_store_gpr(tcg_ctx, t0, rt);
|
gen_store_gpr(tcg_ctx, t0, rt);
|
||||||
/* BS_STOP isn't sufficient, we need to ensure we break out
|
/* DISAS_STOP isn't sufficient, we need to ensure we break
|
||||||
of translated code to check for pending interrupts. */
|
out of translated code to check for pending interrupts */
|
||||||
gen_save_pc(ctx, ctx->pc + 4);
|
gen_save_pc(ctx, ctx->pc + 4);
|
||||||
ctx->bstate = BS_EXCP;
|
ctx->is_jmp = DISAS_EXIT;
|
||||||
break;
|
break;
|
||||||
default: /* Invalid */
|
default: /* Invalid */
|
||||||
MIPS_INVAL("mfmc0");
|
MIPS_INVAL("mfmc0");
|
||||||
|
@ -20392,7 +20389,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
||||||
ctx.insn_flags = env->insn_flags;
|
ctx.insn_flags = env->insn_flags;
|
||||||
ctx.CP0_Config1 = env->CP0_Config1;
|
ctx.CP0_Config1 = env->CP0_Config1;
|
||||||
ctx.tb = tb;
|
ctx.tb = tb;
|
||||||
ctx.bstate = BS_NONE;
|
ctx.is_jmp = DISAS_NEXT;
|
||||||
ctx.btarget = 0;
|
ctx.btarget = 0;
|
||||||
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
|
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
|
||||||
ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
|
ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
|
||||||
|
@ -20437,7 +20434,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
gen_tb_start(tcg_ctx, tb);
|
gen_tb_start(tcg_ctx, tb);
|
||||||
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
ctx.bstate = BS_EXCP;
|
ctx.is_jmp = DISAS_EXIT;
|
||||||
goto done_generating;
|
goto done_generating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20458,13 +20455,13 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx, tb);
|
gen_tb_start(tcg_ctx, tb);
|
||||||
while (ctx.bstate == BS_NONE) {
|
while (ctx.is_jmp == DISAS_NEXT) {
|
||||||
tcg_gen_insn_start(tcg_ctx, ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
|
tcg_gen_insn_start(tcg_ctx, ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
|
||||||
num_insns++;
|
num_insns++;
|
||||||
|
|
||||||
if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
|
if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
|
||||||
save_cpu_state(&ctx, 1);
|
save_cpu_state(&ctx, 1);
|
||||||
ctx.bstate = BS_BRANCH;
|
ctx.is_jmp = DISAS_NORETURN;
|
||||||
gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
/* The address covered by the breakpoint must be included in
|
/* The address covered by the breakpoint must be included in
|
||||||
[tb->pc, tb->pc + tb->size) in order to for it to be
|
[tb->pc, tb->pc + tb->size) in order to for it to be
|
||||||
|
@ -20482,7 +20479,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (ctx.pc == ctx.uc->addr_end) {
|
if (ctx.pc == ctx.uc->addr_end) {
|
||||||
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
ctx.bstate = BS_EXCP;
|
ctx.is_jmp = DISAS_EXIT;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
bool insn_need_patch = false;
|
bool insn_need_patch = false;
|
||||||
|
@ -20575,24 +20572,24 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
||||||
//if (tb->cflags & CF_LAST_IO) {
|
//if (tb->cflags & CF_LAST_IO) {
|
||||||
// gen_io_end();
|
// gen_io_end();
|
||||||
//}
|
//}
|
||||||
if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
|
if (cs->singlestep_enabled && ctx.is_jmp != DISAS_NORETURN) {
|
||||||
save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
|
save_cpu_state(&ctx, ctx.is_jmp != DISAS_EXIT);
|
||||||
gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
} else {
|
} else {
|
||||||
switch (ctx.bstate) {
|
switch (ctx.is_jmp) {
|
||||||
case BS_STOP:
|
case DISAS_STOP:
|
||||||
gen_save_pc(tcg_ctx, ctx.pc);
|
gen_save_pc(&ctx, ctx.pc);
|
||||||
tcg_gen_lookup_and_goto_ptr(tcg_ctx);
|
tcg_gen_lookup_and_goto_ptr(tcg_ctx);
|
||||||
env->uc->next_pc = ctx.pc;
|
env->uc->next_pc = ctx.pc;
|
||||||
break;
|
break;
|
||||||
case BS_NONE:
|
case DISAS_NEXT:
|
||||||
save_cpu_state(&ctx, 0);
|
save_cpu_state(&ctx, 0);
|
||||||
gen_goto_tb(&ctx, 0, ctx.pc);
|
gen_goto_tb(&ctx, 0, ctx.pc);
|
||||||
break;
|
break;
|
||||||
case BS_EXCP:
|
case DISAS_EXIT:
|
||||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||||
break;
|
break;
|
||||||
case BS_BRANCH:
|
case DISAS_NORETURN:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue