15abf9495SPeter Crosthwaite /*
25abf9495SPeter Crosthwaite * emulator main execution loop
35abf9495SPeter Crosthwaite *
45abf9495SPeter Crosthwaite * Copyright (c) 2003-2005 Fabrice Bellard
55abf9495SPeter Crosthwaite *
65abf9495SPeter Crosthwaite * This library is free software; you can redistribute it and/or
75abf9495SPeter Crosthwaite * modify it under the terms of the GNU Lesser General Public
85abf9495SPeter Crosthwaite * License as published by the Free Software Foundation; either
9fb0343d5SThomas Huth * version 2.1 of the License, or (at your option) any later version.
105abf9495SPeter Crosthwaite *
115abf9495SPeter Crosthwaite * This library is distributed in the hope that it will be useful,
125abf9495SPeter Crosthwaite * but WITHOUT ANY WARRANTY; without even the implied warranty of
135abf9495SPeter Crosthwaite * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
145abf9495SPeter Crosthwaite * Lesser General Public License for more details.
155abf9495SPeter Crosthwaite *
165abf9495SPeter Crosthwaite * You should have received a copy of the GNU Lesser General Public
175abf9495SPeter Crosthwaite * License along with this library; if not, see <http://www.gnu.org/licenses/>.
185abf9495SPeter Crosthwaite */
195abf9495SPeter Crosthwaite
207b31bbc2SPeter Maydell #include "qemu/osdep.h"
21*b2837885SPhilippe Mathieu-Daudé #include "exec/log.h"
2232cad1ffSPhilippe Mathieu-Daudé #include "system/tcg.h"
23720ace24SRichard Henderson #include "qemu/plugin.h"
2443e7a2d3SPhilippe Mathieu-Daudé #include "internal-common.h"
255abf9495SPeter Crosthwaite
268e2b7299SYang Zhong bool tcg_allowed;
278e2b7299SYang Zhong
tcg_cflags_has(CPUState * cpu,uint32_t flags)28*b2837885SPhilippe Mathieu-Daudé bool tcg_cflags_has(CPUState *cpu, uint32_t flags)
29*b2837885SPhilippe Mathieu-Daudé {
30*b2837885SPhilippe Mathieu-Daudé return cpu->tcg_cflags & flags;
31*b2837885SPhilippe Mathieu-Daudé }
32*b2837885SPhilippe Mathieu-Daudé
tcg_cflags_set(CPUState * cpu,uint32_t flags)33*b2837885SPhilippe Mathieu-Daudé void tcg_cflags_set(CPUState *cpu, uint32_t flags)
34*b2837885SPhilippe Mathieu-Daudé {
35*b2837885SPhilippe Mathieu-Daudé cpu->tcg_cflags |= flags;
36*b2837885SPhilippe Mathieu-Daudé }
37*b2837885SPhilippe Mathieu-Daudé
curr_cflags(CPUState * cpu)38*b2837885SPhilippe Mathieu-Daudé uint32_t curr_cflags(CPUState *cpu)
39*b2837885SPhilippe Mathieu-Daudé {
40*b2837885SPhilippe Mathieu-Daudé uint32_t cflags = cpu->tcg_cflags;
41*b2837885SPhilippe Mathieu-Daudé
42*b2837885SPhilippe Mathieu-Daudé /*
43*b2837885SPhilippe Mathieu-Daudé * Record gdb single-step. We should be exiting the TB by raising
44*b2837885SPhilippe Mathieu-Daudé * EXCP_DEBUG, but to simplify other tests, disable chaining too.
45*b2837885SPhilippe Mathieu-Daudé *
46*b2837885SPhilippe Mathieu-Daudé * For singlestep and -d nochain, suppress goto_tb so that
47*b2837885SPhilippe Mathieu-Daudé * we can log -d cpu,exec after every TB.
48*b2837885SPhilippe Mathieu-Daudé */
49*b2837885SPhilippe Mathieu-Daudé if (unlikely(cpu->singlestep_enabled)) {
50*b2837885SPhilippe Mathieu-Daudé cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_SINGLE_STEP | 1;
51*b2837885SPhilippe Mathieu-Daudé } else if (qatomic_read(&one_insn_per_tb)) {
52*b2837885SPhilippe Mathieu-Daudé cflags |= CF_NO_GOTO_TB | 1;
53*b2837885SPhilippe Mathieu-Daudé } else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
54*b2837885SPhilippe Mathieu-Daudé cflags |= CF_NO_GOTO_TB;
55*b2837885SPhilippe Mathieu-Daudé }
56*b2837885SPhilippe Mathieu-Daudé
57*b2837885SPhilippe Mathieu-Daudé return cflags;
58*b2837885SPhilippe Mathieu-Daudé }
59*b2837885SPhilippe Mathieu-Daudé
606886b980SPeter Maydell /* exit the current TB, but without causing any exception to be raised */
cpu_loop_exit_noexc(CPUState * cpu)616886b980SPeter Maydell void cpu_loop_exit_noexc(CPUState *cpu)
625abf9495SPeter Crosthwaite {
635abf9495SPeter Crosthwaite cpu->exception_index = -1;
64afd46fcaSPavel Dovgalyuk cpu_loop_exit(cpu);
655abf9495SPeter Crosthwaite }
665abf9495SPeter Crosthwaite
cpu_loop_exit(CPUState * cpu)675abf9495SPeter Crosthwaite void cpu_loop_exit(CPUState *cpu)
685abf9495SPeter Crosthwaite {
69afd46fcaSPavel Dovgalyuk /* Undo the setting in cpu_tb_exec. */
70464dacf6SRichard Henderson cpu->neg.can_do_io = true;
71e04660afSRichard Henderson /* Undo any setting in generated code. */
72e04660afSRichard Henderson qemu_plugin_disable_mem_helpers(cpu);
735abf9495SPeter Crosthwaite siglongjmp(cpu->jmp_env, 1);
745abf9495SPeter Crosthwaite }
755abf9495SPeter Crosthwaite
cpu_loop_exit_restore(CPUState * cpu,uintptr_t pc)765abf9495SPeter Crosthwaite void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
775abf9495SPeter Crosthwaite {
785abf9495SPeter Crosthwaite if (pc) {
793d419a4dSRichard Henderson cpu_restore_state(cpu, pc);
805abf9495SPeter Crosthwaite }
81afd46fcaSPavel Dovgalyuk cpu_loop_exit(cpu);
825abf9495SPeter Crosthwaite }
83fdbc2b57SRichard Henderson
cpu_loop_exit_atomic(CPUState * cpu,uintptr_t pc)84fdbc2b57SRichard Henderson void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc)
85fdbc2b57SRichard Henderson {
869877ea05SRichard Henderson /* Prevent looping if already executing in a serial context. */
879877ea05SRichard Henderson g_assert(!cpu_in_serial_context(cpu));
88fdbc2b57SRichard Henderson cpu->exception_index = EXCP_ATOMIC;
89fdbc2b57SRichard Henderson cpu_loop_exit_restore(cpu, pc);
90fdbc2b57SRichard Henderson }
91