Move gdb singlestep to generic code
Fix cpu_common_props -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmFrFmIdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+oegf+JNIiYsdM2XOkHSJ0 u48VLJn8iVB8KWod1qcEE9H6SK2akY0nEi1vfqIGfBqDfwz+7KClJtFQk+f1OeaW zLgwxjg+7JeMxHIiLxkUWbFlMdsqQcC1fa3WVSxWrXtE3qunf0naOdhVxoHaL+eL nMhCH31NB+x0ceBl8xmQAY3WRSFUQKOY3bQ8eRH2UcTlvxI6iCBEGlIgfVhnSmUm mzyudpoEC3yJq2ZTHlQdMMPJvpCklC5FdDHLb0dvmkvjCDKZsxAZazC5H0hAuPIi aPJmD5Exoym6XbUNwjAYe0VjZN7xrWD4MvnjmbShb7B/BBiF8is9wY7dBIjEDp1X nZqxmQ== =ufxg -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20211016' into staging Move gdb singlestep to generic code Fix cpu_common_props # gpg: Signature made Sat 16 Oct 2021 11:13:54 AM PDT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * remotes/rth/tags/pull-tcg-20211016: (24 commits) Revert "cpu: Move cpu_common_props to hw/core/cpu.c" target/xtensa: Drop check for singlestep_enabled target/tricore: Drop check for singlestep_enabled target/sh4: Drop check for singlestep_enabled target/s390x: Drop check for singlestep_enabled target/rx: Drop checks for singlestep_enabled target/riscv: Remove exit_tb and lookup_and_goto_ptr target/riscv: Remove dead code after exception target/ppc: Drop exit checks for singlestep_enabled target/openrisc: Drop checks for singlestep_enabled target/mips: Drop exit checks for singlestep_enabled target/mips: Fix single stepping target/microblaze: Drop checks for singlestep_enabled target/microblaze: Check CF_NO_GOTO_TB for DISAS_JUMP target/m68k: Drop checks for singlestep_enabled target/i386: Drop check for singlestep_enabled target/i386: Check CF_NO_GOTO_TB for dc->jmp_opt target/hppa: Drop checks for singlestep_enabled target/arm: Drop checks for singlestep_enabled target/hexagon: Drop checks for singlestep_enabled ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
c148a05721
@ -383,6 +383,17 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
|
||||
cc->set_pc(cpu, last_tb->pc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If gdb single-step, and we haven't raised another exception,
|
||||
* raise a debug exception. Single-step with another exception
|
||||
* is handled in cpu_handle_exception.
|
||||
*/
|
||||
if (unlikely(cpu->singlestep_enabled) && cpu->exception_index == -1) {
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
|
||||
return last_tb;
|
||||
}
|
||||
|
||||
|
21
cpu.c
21
cpu.c
@ -179,6 +179,27 @@ void cpu_exec_unrealizefn(CPUState *cpu)
|
||||
cpu_list_remove(cpu);
|
||||
}
|
||||
|
||||
static Property cpu_common_props[] = {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/*
|
||||
* Create a memory property for softmmu CPU object,
|
||||
* so users can wire up its memory. (This can't go in hw/core/cpu.c
|
||||
* because that file is compiled only once for both user-mode
|
||||
* and system builds.) The default if no link is set up is to use
|
||||
* the system address space.
|
||||
*/
|
||||
DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
|
||||
MemoryRegion *),
|
||||
#endif
|
||||
DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
void cpu_class_init_props(DeviceClass *dc)
|
||||
{
|
||||
device_class_set_props(dc, cpu_common_props);
|
||||
}
|
||||
|
||||
void cpu_exec_initfn(CPUState *cpu)
|
||||
{
|
||||
cpu->as = NULL;
|
||||
|
@ -257,21 +257,6 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
|
||||
return cpu->cpu_index;
|
||||
}
|
||||
|
||||
static Property cpu_common_props[] = {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* Create a memory property for softmmu CPU object,
|
||||
* so users can wire up its memory. (This can't go in hw/core/cpu.c
|
||||
* because that file is compiled only once for both user-mode
|
||||
* and system builds.) The default if no link is set up is to use
|
||||
* the system address space.
|
||||
*/
|
||||
DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
|
||||
MemoryRegion *),
|
||||
#endif
|
||||
DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void cpu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@ -286,7 +271,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
|
||||
dc->realize = cpu_common_realizefn;
|
||||
dc->unrealize = cpu_common_unrealizefn;
|
||||
dc->reset = cpu_common_reset;
|
||||
device_class_set_props(dc, cpu_common_props);
|
||||
cpu_class_init_props(dc);
|
||||
/*
|
||||
* Reason: CPUs still need special care by board code: wiring up
|
||||
* IRQs, adding reset handlers, halting non-first CPUs, ...
|
||||
|
@ -1008,6 +1008,7 @@ void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
/* $(top_srcdir)/cpu.c */
|
||||
void cpu_class_init_props(DeviceClass *dc);
|
||||
void cpu_exec_initfn(CPUState *cpu);
|
||||
void cpu_exec_realizefn(CPUState *cpu, Error **errp);
|
||||
void cpu_exec_unrealizefn(CPUState *cpu);
|
||||
|
@ -3005,17 +3005,10 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
|
||||
/* FALLTHRU */
|
||||
case DISAS_PC_UPDATED:
|
||||
if (!ctx->base.singlestep_enabled) {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
case DISAS_PC_UPDATED_NOCHAIN:
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_excp_1(EXCP_DEBUG, 0);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -404,8 +404,6 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
|
||||
gen_a64_set_pc_im(dest);
|
||||
if (s->ss_active) {
|
||||
gen_step_complete_exception(s);
|
||||
} else if (s->base.singlestep_enabled) {
|
||||
gen_exception_internal(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
@ -14879,7 +14877,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
{
|
||||
DisasContext *dc = container_of(dcbase, DisasContext, base);
|
||||
|
||||
if (unlikely(dc->base.singlestep_enabled || dc->ss_active)) {
|
||||
if (unlikely(dc->ss_active)) {
|
||||
/* Note that this means single stepping WFI doesn't halt the CPU.
|
||||
* For conditional branch insns this is harmless unreachable code as
|
||||
* gen_goto_tb() has already handled emitting the debug exception
|
||||
@ -14891,11 +14889,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
/* fall through */
|
||||
case DISAS_EXIT:
|
||||
case DISAS_JUMP:
|
||||
if (dc->base.singlestep_enabled) {
|
||||
gen_exception_internal(EXCP_DEBUG);
|
||||
} else {
|
||||
gen_step_complete_exception(dc);
|
||||
}
|
||||
gen_step_complete_exception(dc);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
|
@ -341,7 +341,7 @@ static void gen_exception_internal(int excp)
|
||||
tcg_temp_free_i32(tcg_excp);
|
||||
}
|
||||
|
||||
static void gen_step_complete_exception(DisasContext *s)
|
||||
static void gen_singlestep_exception(DisasContext *s)
|
||||
{
|
||||
/* We just completed step of an insn. Move from Active-not-pending
|
||||
* to Active-pending, and then also take the swstep exception.
|
||||
@ -357,30 +357,6 @@ static void gen_step_complete_exception(DisasContext *s)
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_singlestep_exception(DisasContext *s)
|
||||
{
|
||||
/* Generate the right kind of exception for singlestep, which is
|
||||
* either the architectural singlestep or EXCP_DEBUG for QEMU's
|
||||
* gdb singlestepping.
|
||||
*/
|
||||
if (s->ss_active) {
|
||||
gen_step_complete_exception(s);
|
||||
} else {
|
||||
gen_exception_internal(EXCP_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_singlestepping(DisasContext *s)
|
||||
{
|
||||
/* Return true if we are singlestepping either because of
|
||||
* architectural singlestep or QEMU gdbstub singlestep. This does
|
||||
* not include the command line '-singlestep' mode which is rather
|
||||
* misnamed as it only means "one instruction per TB" and doesn't
|
||||
* affect the code we generate.
|
||||
*/
|
||||
return s->base.singlestep_enabled || s->ss_active;
|
||||
}
|
||||
|
||||
void clear_eci_state(DisasContext *s)
|
||||
{
|
||||
/*
|
||||
@ -837,7 +813,7 @@ static inline void gen_bx_excret_final_code(DisasContext *s)
|
||||
/* Is the new PC value in the magic range indicating exception return? */
|
||||
tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
|
||||
/* No: end the TB as we would for a DISAS_JMP */
|
||||
if (is_singlestepping(s)) {
|
||||
if (s->ss_active) {
|
||||
gen_singlestep_exception(s);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
@ -2606,7 +2582,7 @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
|
||||
/* Jump, specifying which TB number to use if we gen_goto_tb() */
|
||||
static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
|
||||
{
|
||||
if (unlikely(is_singlestepping(s))) {
|
||||
if (unlikely(s->ss_active)) {
|
||||
/* An indirect jump so that we still trigger the debug exception. */
|
||||
gen_set_pc_im(s, dest);
|
||||
s->base.is_jmp = DISAS_JUMP;
|
||||
@ -9459,7 +9435,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
|
||||
|
||||
/* If architectural single step active, limit to 1. */
|
||||
if (is_singlestepping(dc)) {
|
||||
if (dc->ss_active) {
|
||||
dc->base.max_insns = 1;
|
||||
}
|
||||
|
||||
@ -9794,7 +9770,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
* insn codepath itself.
|
||||
*/
|
||||
gen_bx_excret_final_code(dc);
|
||||
} else if (unlikely(is_singlestepping(dc))) {
|
||||
} else if (unlikely(dc->ss_active)) {
|
||||
/* Unconditional and "condition passed" instruction codepath. */
|
||||
switch (dc->base.is_jmp) {
|
||||
case DISAS_SWI:
|
||||
@ -9889,7 +9865,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
/* "Condition failed" instruction codepath for the branch/trap insn */
|
||||
gen_set_label(dc->condlabel);
|
||||
gen_set_condexec(dc);
|
||||
if (unlikely(is_singlestepping(dc))) {
|
||||
if (unlikely(dc->ss_active)) {
|
||||
gen_set_pc_im(dc, dc->base.pc_next);
|
||||
gen_singlestep_exception(dc);
|
||||
} else {
|
||||
|
@ -1087,11 +1087,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(tb, n);
|
||||
} else {
|
||||
tcg_gen_movi_i32(cpu_pc, dest);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
@ -3009,17 +3005,10 @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->npc);
|
||||
/* fall through */
|
||||
case DISAS_LOOKUP:
|
||||
if (!ctx->base.singlestep_enabled) {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -3249,22 +3249,6 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(dc->base.singlestep_enabled)) {
|
||||
switch (is_jmp) {
|
||||
case DISAS_TOO_MANY:
|
||||
case DISAS_UPDATE_NEXT:
|
||||
tcg_gen_movi_tl(env_pc, npc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
case DISAS_UPDATE:
|
||||
t_gen_raise_exception(EXCP_DEBUG);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
switch (is_jmp) {
|
||||
case DISAS_TOO_MANY:
|
||||
gen_goto_tb(dc, 0, npc);
|
||||
|
@ -69,11 +69,7 @@ static void gen_end_tb(DisasContext *ctx)
|
||||
{
|
||||
gen_exec_counters(ctx);
|
||||
tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_exception_raw(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
@ -614,11 +610,7 @@ static void hexagon_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
case DISAS_TOO_MANY:
|
||||
gen_exec_counters(ctx);
|
||||
tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_exception_raw(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
|
@ -814,11 +814,7 @@ static void gen_goto_tb(DisasContext *ctx, int which,
|
||||
} else {
|
||||
copy_iaoq_entry(cpu_iaoq_f, f, cpu_iaoq_b);
|
||||
copy_iaoq_entry(cpu_iaoq_b, b, ctx->iaoq_n_var);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_excp_1(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2346,11 +2342,7 @@ static bool do_rfi(DisasContext *ctx, bool rfi_r)
|
||||
gen_helper_rfi(cpu_env);
|
||||
}
|
||||
/* Exit the TB to recognize new interrupts. */
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_excp_1(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
return nullify_end(ctx);
|
||||
@ -4274,10 +4266,9 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
nullify_save(ctx);
|
||||
/* FALLTHRU */
|
||||
case DISAS_IAQ_N_UPDATED:
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_excp_1(EXCP_DEBUG);
|
||||
} else if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
|
||||
if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case DISAS_EXIT:
|
||||
|
@ -56,7 +56,6 @@ DEF_HELPER_2(syscall, void, env, int)
|
||||
DEF_HELPER_2(sysret, void, env, int)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
|
||||
DEF_HELPER_FLAGS_1(debug, TCG_CALL_NO_WG, noreturn, env)
|
||||
DEF_HELPER_1(reset_rf, void, env)
|
||||
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
|
||||
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
|
||||
|
@ -110,14 +110,6 @@ void QEMU_NORETURN helper_pause(CPUX86State *env, int next_eip_addend)
|
||||
do_pause(env);
|
||||
}
|
||||
|
||||
void QEMU_NORETURN helper_debug(CPUX86State *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
cs->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
||||
uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx)
|
||||
{
|
||||
if ((env->cr[4] & CR4_PKE_MASK) == 0) {
|
||||
|
@ -2660,9 +2660,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
|
||||
if (s->base.tb->flags & HF_RF_MASK) {
|
||||
gen_helper_reset_rf(cpu_env);
|
||||
}
|
||||
if (s->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else if (recheck_tf) {
|
||||
if (recheck_tf) {
|
||||
gen_helper_rechecking_single_step(cpu_env);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
} else if (s->flags & HF_TF_MASK) {
|
||||
@ -8556,6 +8554,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
||||
DisasContext *dc = container_of(dcbase, DisasContext, base);
|
||||
CPUX86State *env = cpu->env_ptr;
|
||||
uint32_t flags = dc->base.tb->flags;
|
||||
uint32_t cflags = tb_cflags(dc->base.tb);
|
||||
int cpl = (flags >> HF_CPL_SHIFT) & 3;
|
||||
int iopl = (flags >> IOPL_SHIFT) & 3;
|
||||
|
||||
@ -8593,14 +8592,14 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
||||
dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
|
||||
dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
|
||||
dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
|
||||
dc->jmp_opt = !(dc->base.singlestep_enabled ||
|
||||
dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
|
||||
(flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
|
||||
/*
|
||||
* If jmp_opt, we want to handle each string instruction individually.
|
||||
* For icount also disable repz optimization so that each iteration
|
||||
* is accounted separately.
|
||||
*/
|
||||
dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
|
||||
dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
|
||||
|
||||
dc->T0 = tcg_temp_new();
|
||||
dc->T1 = tcg_temp_new();
|
||||
|
@ -194,18 +194,6 @@ static void do_writebacks(DisasContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_singlestepping(DisasContext *s)
|
||||
{
|
||||
/*
|
||||
* Return true if we are singlestepping either because of
|
||||
* architectural singlestep or QEMU gdbstub singlestep. This does
|
||||
* not include the command line '-singlestep' mode which is rather
|
||||
* misnamed as it only means "one instruction per TB" and doesn't
|
||||
* affect the code we generate.
|
||||
*/
|
||||
return s->base.singlestep_enabled || s->ss_active;
|
||||
}
|
||||
|
||||
/* is_jmp field values */
|
||||
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
|
||||
#define DISAS_EXIT DISAS_TARGET_1 /* cpu state was modified dynamically */
|
||||
@ -320,20 +308,6 @@ static void gen_exception(DisasContext *s, uint32_t dest, int nr)
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_singlestep_exception(DisasContext *s)
|
||||
{
|
||||
/*
|
||||
* Generate the right kind of exception for singlestep, which is
|
||||
* either the architectural singlestep or EXCP_DEBUG for QEMU's
|
||||
* gdb singlestepping.
|
||||
*/
|
||||
if (s->ss_active) {
|
||||
gen_raise_exception(EXCP_TRACE);
|
||||
} else {
|
||||
gen_raise_exception(EXCP_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_addr_fault(DisasContext *s)
|
||||
{
|
||||
gen_exception(s, s->base.pc_next, EXCP_ADDRESS);
|
||||
@ -1522,10 +1496,10 @@ static void gen_exit_tb(DisasContext *s)
|
||||
/* Generate a jump to an immediate address. */
|
||||
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
|
||||
{
|
||||
if (unlikely(is_singlestepping(s))) {
|
||||
if (unlikely(s->ss_active)) {
|
||||
update_cc_op(s);
|
||||
tcg_gen_movi_i32(QREG_PC, dest);
|
||||
gen_singlestep_exception(s);
|
||||
gen_raise_exception(EXCP_TRACE);
|
||||
} else if (translator_use_goto_tb(&s->base, dest)) {
|
||||
tcg_gen_goto_tb(n);
|
||||
tcg_gen_movi_i32(QREG_PC, dest);
|
||||
@ -6193,7 +6167,7 @@ static void m68k_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
||||
|
||||
dc->ss_active = (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS);
|
||||
/* If architectural single step active, limit to 1 */
|
||||
if (is_singlestepping(dc)) {
|
||||
if (dc->ss_active) {
|
||||
dc->base.max_insns = 1;
|
||||
}
|
||||
}
|
||||
@ -6252,17 +6226,17 @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
break;
|
||||
case DISAS_TOO_MANY:
|
||||
update_cc_op(dc);
|
||||
if (is_singlestepping(dc)) {
|
||||
if (dc->ss_active) {
|
||||
tcg_gen_movi_i32(QREG_PC, dc->pc);
|
||||
gen_singlestep_exception(dc);
|
||||
gen_raise_exception(EXCP_TRACE);
|
||||
} else {
|
||||
gen_jmp_tb(dc, 0, dc->pc);
|
||||
}
|
||||
break;
|
||||
case DISAS_JUMP:
|
||||
/* We updated CC_OP and PC in gen_jmp/gen_jmp_im. */
|
||||
if (is_singlestepping(dc)) {
|
||||
gen_singlestep_exception(dc);
|
||||
if (dc->ss_active) {
|
||||
gen_raise_exception(EXCP_TRACE);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
@ -6272,8 +6246,8 @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
* We updated CC_OP and PC in gen_exit_tb, but also modified
|
||||
* other state that may require returning to the main loop.
|
||||
*/
|
||||
if (is_singlestepping(dc)) {
|
||||
gen_singlestep_exception(dc);
|
||||
if (dc->ss_active) {
|
||||
gen_raise_exception(EXCP_TRACE);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
|
@ -126,12 +126,7 @@ static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
|
||||
|
||||
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
|
||||
{
|
||||
if (dc->base.singlestep_enabled) {
|
||||
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
|
||||
tcg_gen_movi_i32(cpu_pc, dest);
|
||||
gen_helper_raise_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
} else if (translator_use_goto_tb(&dc->base, dest)) {
|
||||
if (translator_use_goto_tb(&dc->base, dest)) {
|
||||
tcg_gen_goto_tb(n);
|
||||
tcg_gen_movi_i32(cpu_pc, dest);
|
||||
tcg_gen_exit_tb(dc->base.tb, n);
|
||||
@ -1779,7 +1774,7 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
|
||||
break;
|
||||
|
||||
case DISAS_JUMP:
|
||||
if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
|
||||
if (dc->jmp_dest != -1 && !(tb_cflags(dc->base.tb) & CF_NO_GOTO_TB)) {
|
||||
/* Direct jump. */
|
||||
tcg_gen_discard_i32(cpu_btarget);
|
||||
|
||||
@ -1804,15 +1799,10 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Indirect jump (or direct jump w/ singlestep) */
|
||||
/* Indirect jump (or direct jump w/ goto_tb disabled) */
|
||||
tcg_gen_mov_i32(cpu_pc, cpu_btarget);
|
||||
tcg_gen_discard_i32(cpu_btarget);
|
||||
|
||||
if (unlikely(cs->singlestep_enabled)) {
|
||||
gen_raise_exception(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -4823,12 +4823,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(ctx->base.tb, n);
|
||||
} else {
|
||||
gen_save_pc(dest);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
save_cpu_state(ctx, 0);
|
||||
gen_helper_raise_exception_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -11788,10 +11783,6 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
|
||||
} else {
|
||||
tcg_gen_mov_tl(cpu_PC, btarget);
|
||||
}
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
save_cpu_state(ctx, 0);
|
||||
gen_helper_raise_exception_debug(cpu_env);
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
default:
|
||||
@ -16016,6 +16007,16 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
|
||||
INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
|
||||
|
||||
/*
|
||||
* Execute a branch and its delay slot as a single instruction.
|
||||
* This is what GDB expects and is consistent with what the
|
||||
* hardware does (e.g. if a delay slot instruction faults, the
|
||||
* reported PC is the PC of the branch).
|
||||
*/
|
||||
if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
|
||||
ctx->base.max_insns = 2;
|
||||
}
|
||||
|
||||
LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
|
||||
ctx->hflags);
|
||||
}
|
||||
@ -16085,17 +16086,14 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
||||
if (ctx->base.is_jmp != DISAS_NEXT) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a branch and its delay slot as a single instruction.
|
||||
* This is what GDB expects and is consistent with what the
|
||||
* hardware does (e.g. if a delay slot instruction faults, the
|
||||
* reported PC is the PC of the branch).
|
||||
* End the TB on (most) page crossings.
|
||||
* See mips_tr_init_disas_context about single-stepping a branch
|
||||
* together with its delay slot.
|
||||
*/
|
||||
if (ctx->base.singlestep_enabled &&
|
||||
(ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
|
||||
ctx->base.is_jmp = DISAS_TOO_MANY;
|
||||
}
|
||||
if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
|
||||
if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
|
||||
&& !ctx->base.singlestep_enabled) {
|
||||
ctx->base.is_jmp = DISAS_TOO_MANY;
|
||||
}
|
||||
}
|
||||
@ -16104,28 +16102,23 @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
{
|
||||
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
||||
|
||||
if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
|
||||
save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
|
||||
gen_helper_raise_exception_debug(cpu_env);
|
||||
} else {
|
||||
switch (ctx->base.is_jmp) {
|
||||
case DISAS_STOP:
|
||||
gen_save_pc(ctx->base.pc_next);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
save_cpu_state(ctx, 0);
|
||||
gen_goto_tb(ctx, 0, ctx->base.pc_next);
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
switch (ctx->base.is_jmp) {
|
||||
case DISAS_STOP:
|
||||
gen_save_pc(ctx->base.pc_next);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
save_cpu_state(ctx, 0);
|
||||
gen_goto_tb(ctx, 0, ctx->base.pc_next);
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1659,11 +1659,7 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
/* The jump destination is indirect/computed; use jmp_pc. */
|
||||
tcg_gen_mov_tl(cpu_pc, jmp_pc);
|
||||
tcg_gen_discard_tl(jmp_pc);
|
||||
if (unlikely(dc->base.singlestep_enabled)) {
|
||||
gen_exception(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
}
|
||||
/* The jump destination is direct; use jmp_pc_imm.
|
||||
@ -1680,19 +1676,11 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
break;
|
||||
}
|
||||
tcg_gen_movi_tl(cpu_pc, jmp_dest);
|
||||
if (unlikely(dc->base.singlestep_enabled)) {
|
||||
gen_exception(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
|
||||
case DISAS_EXIT:
|
||||
if (unlikely(dc->base.singlestep_enabled)) {
|
||||
gen_exception(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -42,7 +42,6 @@
|
||||
|
||||
#define CPU_SINGLE_STEP 0x1
|
||||
#define CPU_BRANCH_STEP 0x2
|
||||
#define GDBSTUB_SINGLE_STEP 0x4
|
||||
|
||||
/* Include definitions for instructions classes and implementations flags */
|
||||
/* #define PPC_DEBUG_DISAS */
|
||||
@ -333,7 +332,7 @@ static uint32_t gen_prep_dbgex(DisasContext *ctx)
|
||||
|
||||
static void gen_debug_exception(DisasContext *ctx)
|
||||
{
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
@ -4309,15 +4308,8 @@ static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
|
||||
|
||||
static void gen_lookup_and_goto_ptr(DisasContext *ctx)
|
||||
{
|
||||
int sse = ctx->singlestep_enabled;
|
||||
if (unlikely(sse)) {
|
||||
if (sse & GDBSTUB_SINGLE_STEP) {
|
||||
gen_debug_exception(ctx);
|
||||
} else if (sse & (CPU_SINGLE_STEP | CPU_BRANCH_STEP)) {
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
if (unlikely(ctx->singlestep_enabled)) {
|
||||
gen_debug_exception(ctx);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
@ -8563,17 +8555,11 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
ctx->singlestep_enabled = 0;
|
||||
if ((hflags >> HFLAGS_SE) & 1) {
|
||||
ctx->singlestep_enabled |= CPU_SINGLE_STEP;
|
||||
ctx->base.max_insns = 1;
|
||||
}
|
||||
if ((hflags >> HFLAGS_BE) & 1) {
|
||||
ctx->singlestep_enabled |= CPU_BRANCH_STEP;
|
||||
}
|
||||
if (unlikely(ctx->base.singlestep_enabled)) {
|
||||
ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP;
|
||||
}
|
||||
|
||||
if (ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP)) {
|
||||
ctx->base.max_insns = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs)
|
||||
@ -8642,7 +8628,6 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
||||
DisasJumpType is_jmp = ctx->base.is_jmp;
|
||||
target_ulong nip = ctx->base.pc_next;
|
||||
int sse;
|
||||
|
||||
if (is_jmp == DISAS_NORETURN) {
|
||||
/* We have already exited the TB. */
|
||||
@ -8650,8 +8635,8 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
}
|
||||
|
||||
/* Honor single stepping. */
|
||||
sse = ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP);
|
||||
if (unlikely(sse)) {
|
||||
if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP)
|
||||
&& (nip <= 0x100 || nip > 0xf00)) {
|
||||
switch (is_jmp) {
|
||||
case DISAS_TOO_MANY:
|
||||
case DISAS_EXIT_UPDATE:
|
||||
@ -8665,15 +8650,8 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (sse & GDBSTUB_SINGLE_STEP) {
|
||||
gen_debug_exception(ctx);
|
||||
return;
|
||||
}
|
||||
/* else CPU_SINGLE_STEP... */
|
||||
if (nip <= 0x100 || nip > 0xf00) {
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
|
||||
return;
|
||||
}
|
||||
gen_debug_exception(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (is_jmp) {
|
||||
|
@ -22,8 +22,6 @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
|
||||
{
|
||||
/* always generates U-level ECALL, fixed in do_interrupt handler */
|
||||
generate_exception(ctx, RISCV_EXCP_U_ECALL);
|
||||
exit_tb(ctx); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -60,13 +58,11 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
|
||||
post = opcode_at(&ctx->base, post_addr);
|
||||
}
|
||||
|
||||
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
|
||||
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
|
||||
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
|
||||
} else {
|
||||
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
|
||||
}
|
||||
exit_tb(ctx); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -82,7 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
|
||||
|
||||
if (has_ext(ctx, RVS)) {
|
||||
gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
|
||||
exit_tb(ctx); /* no chaining */
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
} else {
|
||||
return false;
|
||||
@ -98,7 +94,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
||||
gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
|
||||
exit_tb(ctx); /* no chaining */
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
#else
|
||||
|
@ -71,9 +71,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
|
||||
if (a->rd != 0) {
|
||||
tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
|
||||
}
|
||||
|
||||
/* No chaining with JALR. */
|
||||
lookup_and_goto_ptr(ctx);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
|
||||
if (misaligned) {
|
||||
gen_set_label(misaligned);
|
||||
@ -421,7 +419,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
||||
* however we need to end the translation block
|
||||
*/
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
exit_tb(ctx);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
@ -430,7 +428,7 @@ static bool do_csr_post(DisasContext *ctx)
|
||||
{
|
||||
/* We may have changed important cpu state -- exit to main loop. */
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
exit_tb(ctx);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
|
||||
gen_set_gpr(ctx, a->rd, dst);
|
||||
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
lookup_and_goto_ptr(ctx);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
@ -149,31 +149,6 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_exception_debug(void)
|
||||
{
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
|
||||
}
|
||||
|
||||
/* Wrapper around tcg_gen_exit_tb that handles single stepping */
|
||||
static void exit_tb(DisasContext *ctx)
|
||||
{
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_exception_debug();
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wrapper around tcg_gen_lookup_and_goto_ptr that handles single stepping */
|
||||
static void lookup_and_goto_ptr(DisasContext *ctx)
|
||||
{
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_exception_debug();
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_exception_illegal(DisasContext *ctx)
|
||||
{
|
||||
generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
|
||||
@ -192,7 +167,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(ctx->base.tb, n);
|
||||
} else {
|
||||
tcg_gen_movi_tl(cpu_pc, dest);
|
||||
lookup_and_goto_ptr(ctx);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
|
||||
DEF_HELPER_1(raise_access_fault, noreturn, env)
|
||||
DEF_HELPER_1(raise_privilege_violation, noreturn, env)
|
||||
DEF_HELPER_1(wait, noreturn, env)
|
||||
DEF_HELPER_1(debug, noreturn, env)
|
||||
DEF_HELPER_2(rxint, noreturn, env, i32)
|
||||
DEF_HELPER_1(rxbrk, noreturn, env)
|
||||
DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
|
||||
|
@ -451,14 +451,6 @@ void QEMU_NORETURN helper_wait(CPURXState *env)
|
||||
raise_exception(env, EXCP_HLT, 0);
|
||||
}
|
||||
|
||||
void QEMU_NORETURN helper_debug(CPURXState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
cs->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
||||
void QEMU_NORETURN helper_rxint(CPURXState *env, uint32_t vec)
|
||||
{
|
||||
raise_exception(env, 0x100 + vec, 0);
|
||||
|
@ -150,11 +150,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(dc->base.tb, n);
|
||||
} else {
|
||||
tcg_gen_movi_i32(cpu_pc, dest);
|
||||
if (dc->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
@ -2331,11 +2327,7 @@ static void rx_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
gen_goto_tb(ctx, 0, dcbase->pc_next);
|
||||
break;
|
||||
case DISAS_JUMP:
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
break;
|
||||
case DISAS_UPDATE:
|
||||
tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
|
||||
|
@ -149,7 +149,6 @@ struct DisasContext {
|
||||
uint64_t pc_tmp;
|
||||
uint32_t ilen;
|
||||
enum cc_op cc_op;
|
||||
bool do_debug;
|
||||
};
|
||||
|
||||
/* Information carried about a condition to be evaluated. */
|
||||
@ -6544,7 +6543,6 @@ static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
|
||||
dc->cc_op = CC_OP_DYNAMIC;
|
||||
dc->ex_value = dc->base.tb->cs_base;
|
||||
dc->do_debug = dc->base.singlestep_enabled;
|
||||
}
|
||||
|
||||
static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
|
||||
@ -6596,10 +6594,8 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
/* FALLTHRU */
|
||||
case DISAS_PC_CC_UPDATED:
|
||||
/* Exit the TB, either by raising a debug exception or by return. */
|
||||
if (dc->do_debug) {
|
||||
gen_exception(EXCP_DEBUG);
|
||||
} else if ((dc->base.tb->flags & FLAG_MASK_PER) ||
|
||||
dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
|
||||
if ((dc->base.tb->flags & FLAG_MASK_PER) ||
|
||||
dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
|
@ -3,7 +3,6 @@ DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
|
||||
DEF_HELPER_1(raise_slot_illegal_instruction, noreturn, env)
|
||||
DEF_HELPER_1(raise_fpu_disable, noreturn, env)
|
||||
DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env)
|
||||
DEF_HELPER_1(debug, noreturn, env)
|
||||
DEF_HELPER_1(sleep, noreturn, env)
|
||||
DEF_HELPER_2(trapa, noreturn, env, i32)
|
||||
DEF_HELPER_1(exclusive, noreturn, env)
|
||||
|
@ -81,11 +81,6 @@ void helper_raise_slot_fpu_disable(CPUSH4State *env)
|
||||
raise_exception(env, 0x820, 0);
|
||||
}
|
||||
|
||||
void helper_debug(CPUSH4State *env)
|
||||
{
|
||||
raise_exception(env, EXCP_DEBUG, 0);
|
||||
}
|
||||
|
||||
void helper_sleep(CPUSH4State *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
@ -240,9 +240,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(ctx->base.tb, n);
|
||||
} else {
|
||||
tcg_gen_movi_i32(cpu_pc, dest);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else if (use_exit_tb(ctx)) {
|
||||
if (use_exit_tb(ctx)) {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
@ -258,9 +256,7 @@ static void gen_jump(DisasContext * ctx)
|
||||
delayed jump as immediate jump are conditinal jumps */
|
||||
tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
|
||||
tcg_gen_discard_i32(cpu_delayed_pc);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else if (use_exit_tb(ctx)) {
|
||||
if (use_exit_tb(ctx)) {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
@ -2324,11 +2320,7 @@ static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
switch (ctx->base.is_jmp) {
|
||||
case DISAS_STOP:
|
||||
gen_save_cpu_state(ctx, true);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_helper_debug(cpu_env);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
break;
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
|
@ -153,4 +153,3 @@ DEF_HELPER_2(psw_write, void, env, i32)
|
||||
DEF_HELPER_1(psw_read, i32, env)
|
||||
/* Exceptions */
|
||||
DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
|
||||
DEF_HELPER_2(qemu_excp, noreturn, env, i32)
|
||||
|
@ -107,13 +107,6 @@ static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
|
||||
raise_exception_sync_internal(env, class, tin, pc, 0);
|
||||
}
|
||||
|
||||
void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
cs->exception_index = excp;
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
||||
/* Addressing mode helper */
|
||||
|
||||
static uint16_t reverse16(uint16_t val)
|
||||
|
@ -3225,14 +3225,6 @@ static inline void gen_save_pc(target_ulong pc)
|
||||
tcg_gen_movi_tl(cpu_PC, pc);
|
||||
}
|
||||
|
||||
static void generate_qemu_excp(DisasContext *ctx, int excp)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_const_i32(excp);
|
||||
gen_helper_qemu_excp(cpu_env, tmp);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
|
||||
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
{
|
||||
if (translator_use_goto_tb(&ctx->base, dest)) {
|
||||
@ -3241,11 +3233,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
tcg_gen_exit_tb(ctx->base.tb, n);
|
||||
} else {
|
||||
gen_save_pc(dest);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
generate_qemu_excp(ctx, EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -382,18 +382,14 @@ static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
|
||||
if (dc->icount) {
|
||||
tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
|
||||
}
|
||||
if (dc->base.singlestep_enabled) {
|
||||
gen_exception(dc, EXCP_DEBUG);
|
||||
if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
|
||||
slot = gen_postprocess(dc, slot);
|
||||
}
|
||||
if (slot >= 0) {
|
||||
tcg_gen_goto_tb(slot);
|
||||
tcg_gen_exit_tb(dc->base.tb, slot);
|
||||
} else {
|
||||
if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
|
||||
slot = gen_postprocess(dc, slot);
|
||||
}
|
||||
if (slot >= 0) {
|
||||
tcg_gen_goto_tb(slot);
|
||||
tcg_gen_exit_tb(dc->base.tb, slot);
|
||||
} else {
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
}
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
@ -1293,12 +1289,7 @@ static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
case DISAS_TOO_MANY:
|
||||
if (dc->base.singlestep_enabled) {
|
||||
tcg_gen_movi_i32(cpu_pc, dc->pc);
|
||||
gen_exception(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
gen_jumpi(dc, dc->pc, 0);
|
||||
}
|
||||
gen_jumpi(dc, dc->pc, 0);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
Loading…
Reference in New Issue
Block a user