Statistics
| Branch: | Revision:

root / cpu-exec.c @ 795ca114

History | View | Annotate | Download (29.3 kB)

1 7d13299d bellard
/*
2 e965fc38 陳韋任
 *  emulator main execution loop
3 5fafdf24 ths
 *
4 66321a11 bellard
 *  Copyright (c) 2003-2005 Fabrice Bellard
5 7d13299d bellard
 *
6 3ef693a0 bellard
 * This library is free software; you can redistribute it and/or
7 3ef693a0 bellard
 * modify it under the terms of the GNU Lesser General Public
8 3ef693a0 bellard
 * License as published by the Free Software Foundation; either
9 3ef693a0 bellard
 * version 2 of the License, or (at your option) any later version.
10 7d13299d bellard
 *
11 3ef693a0 bellard
 * This library is distributed in the hope that it will be useful,
12 3ef693a0 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 3ef693a0 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3ef693a0 bellard
 * Lesser General Public License for more details.
15 7d13299d bellard
 *
16 3ef693a0 bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 7d13299d bellard
 */
19 e4533c7a bellard
#include "config.h"
20 cea5f9a2 Blue Swirl
#include "cpu.h"
21 76cad711 Paolo Bonzini
#include "disas/disas.h"
22 7cb69cae bellard
#include "tcg.h"
23 1de7afc9 Paolo Bonzini
#include "qemu/atomic.h"
24 9c17d615 Paolo Bonzini
#include "sysemu/qtest.h"
25 7d13299d bellard
26 3993c6bd Andreas Färber
bool qemu_cpu_has_work(CPUState *cpu)
27 6a4955a8 aliguori
{
28 3993c6bd Andreas Färber
    return cpu_has_work(cpu);
29 6a4955a8 aliguori
}
30 6a4955a8 aliguori
31 9349b4f9 Andreas Färber
void cpu_loop_exit(CPUArchState *env)
32 e4533c7a bellard
{
33 d77953b9 Andreas Färber
    CPUState *cpu = ENV_GET_CPU(env);
34 d77953b9 Andreas Färber
35 d77953b9 Andreas Färber
    cpu->current_tb = NULL;
36 6ab7e546 Peter Maydell
    siglongjmp(env->jmp_env, 1);
37 e4533c7a bellard
}
38 bfed01fc ths
39 fbf9eeb3 bellard
/* exit the current TB from a signal handler. The host registers are
40 fbf9eeb3 bellard
   restored in a state compatible with the CPU emulator
41 fbf9eeb3 bellard
 */
42 9eff14f3 Blue Swirl
#if defined(CONFIG_SOFTMMU)
43 9349b4f9 Andreas Färber
void cpu_resume_from_signal(CPUArchState *env, void *puc)
44 9eff14f3 Blue Swirl
{
45 9eff14f3 Blue Swirl
    /* XXX: restore cpu registers saved in host registers */
46 9eff14f3 Blue Swirl
47 9eff14f3 Blue Swirl
    env->exception_index = -1;
48 6ab7e546 Peter Maydell
    siglongjmp(env->jmp_env, 1);
49 9eff14f3 Blue Swirl
}
50 9eff14f3 Blue Swirl
#endif
51 fbf9eeb3 bellard
52 77211379 Peter Maydell
/* Execute a TB, and fix up the CPU state afterwards if necessary */
53 77211379 Peter Maydell
static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
54 77211379 Peter Maydell
{
55 77211379 Peter Maydell
    CPUArchState *env = cpu->env_ptr;
56 03afa5f8 Richard Henderson
    uintptr_t next_tb;
57 03afa5f8 Richard Henderson
58 03afa5f8 Richard Henderson
#if defined(DEBUG_DISAS)
59 03afa5f8 Richard Henderson
    if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
60 03afa5f8 Richard Henderson
#if defined(TARGET_I386)
61 03afa5f8 Richard Henderson
        log_cpu_state(cpu, CPU_DUMP_CCOP);
62 03afa5f8 Richard Henderson
#elif defined(TARGET_M68K)
63 03afa5f8 Richard Henderson
        /* ??? Should not modify env state for dumping.  */
64 03afa5f8 Richard Henderson
        cpu_m68k_flush_flags(env, env->cc_op);
65 03afa5f8 Richard Henderson
        env->cc_op = CC_OP_FLAGS;
66 03afa5f8 Richard Henderson
        env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
67 03afa5f8 Richard Henderson
        log_cpu_state(cpu, 0);
68 03afa5f8 Richard Henderson
#else
69 03afa5f8 Richard Henderson
        log_cpu_state(cpu, 0);
70 03afa5f8 Richard Henderson
#endif
71 03afa5f8 Richard Henderson
    }
72 03afa5f8 Richard Henderson
#endif /* DEBUG_DISAS */
73 03afa5f8 Richard Henderson
74 03afa5f8 Richard Henderson
    next_tb = tcg_qemu_tb_exec(env, tb_ptr);
75 77211379 Peter Maydell
    if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
76 77211379 Peter Maydell
        /* We didn't start executing this TB (eg because the instruction
77 77211379 Peter Maydell
         * counter hit zero); we must restore the guest PC to the address
78 77211379 Peter Maydell
         * of the start of the TB.
79 77211379 Peter Maydell
         */
80 bdf7ae5b Andreas Färber
        CPUClass *cc = CPU_GET_CLASS(cpu);
81 77211379 Peter Maydell
        TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
82 bdf7ae5b Andreas Färber
        if (cc->synchronize_from_tb) {
83 bdf7ae5b Andreas Färber
            cc->synchronize_from_tb(cpu, tb);
84 bdf7ae5b Andreas Färber
        } else {
85 bdf7ae5b Andreas Färber
            assert(cc->set_pc);
86 bdf7ae5b Andreas Färber
            cc->set_pc(cpu, tb->pc);
87 bdf7ae5b Andreas Färber
        }
88 77211379 Peter Maydell
    }
89 378df4b2 Peter Maydell
    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
90 378df4b2 Peter Maydell
        /* We were asked to stop executing TBs (probably a pending
91 378df4b2 Peter Maydell
         * interrupt. We've now stopped, so clear the flag.
92 378df4b2 Peter Maydell
         */
93 378df4b2 Peter Maydell
        cpu->tcg_exit_req = 0;
94 378df4b2 Peter Maydell
    }
95 77211379 Peter Maydell
    return next_tb;
96 77211379 Peter Maydell
}
97 77211379 Peter Maydell
98 2e70f6ef pbrook
/* Execute the code without caching the generated code. An interpreter
99 2e70f6ef pbrook
   could be used if available. */
100 9349b4f9 Andreas Färber
static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
101 cea5f9a2 Blue Swirl
                             TranslationBlock *orig_tb)
102 2e70f6ef pbrook
{
103 d77953b9 Andreas Färber
    CPUState *cpu = ENV_GET_CPU(env);
104 2e70f6ef pbrook
    TranslationBlock *tb;
105 2e70f6ef pbrook
106 2e70f6ef pbrook
    /* Should never happen.
107 2e70f6ef pbrook
       We only end up here when an existing TB is too long.  */
108 2e70f6ef pbrook
    if (max_cycles > CF_COUNT_MASK)
109 2e70f6ef pbrook
        max_cycles = CF_COUNT_MASK;
110 2e70f6ef pbrook
111 2e70f6ef pbrook
    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
112 2e70f6ef pbrook
                     max_cycles);
113 d77953b9 Andreas Färber
    cpu->current_tb = tb;
114 2e70f6ef pbrook
    /* execute the generated code */
115 77211379 Peter Maydell
    cpu_tb_exec(cpu, tb->tc_ptr);
116 d77953b9 Andreas Färber
    cpu->current_tb = NULL;
117 2e70f6ef pbrook
    tb_phys_invalidate(tb, -1);
118 2e70f6ef pbrook
    tb_free(tb);
119 2e70f6ef pbrook
}
120 2e70f6ef pbrook
121 9349b4f9 Andreas Färber
static TranslationBlock *tb_find_slow(CPUArchState *env,
122 cea5f9a2 Blue Swirl
                                      target_ulong pc,
123 8a40a180 bellard
                                      target_ulong cs_base,
124 c068688b j_mayer
                                      uint64_t flags)
125 8a40a180 bellard
{
126 8a40a180 bellard
    TranslationBlock *tb, **ptb1;
127 8a40a180 bellard
    unsigned int h;
128 337fc758 Blue Swirl
    tb_page_addr_t phys_pc, phys_page1;
129 41c1b1c9 Paul Brook
    target_ulong virt_page2;
130 3b46e624 ths
131 5e5f07e0 Evgeny Voevodin
    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
132 3b46e624 ths
133 8a40a180 bellard
    /* find translated block using physical mappings */
134 41c1b1c9 Paul Brook
    phys_pc = get_page_addr_code(env, pc);
135 8a40a180 bellard
    phys_page1 = phys_pc & TARGET_PAGE_MASK;
136 8a40a180 bellard
    h = tb_phys_hash_func(phys_pc);
137 5e5f07e0 Evgeny Voevodin
    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
138 8a40a180 bellard
    for(;;) {
139 8a40a180 bellard
        tb = *ptb1;
140 8a40a180 bellard
        if (!tb)
141 8a40a180 bellard
            goto not_found;
142 5fafdf24 ths
        if (tb->pc == pc &&
143 8a40a180 bellard
            tb->page_addr[0] == phys_page1 &&
144 5fafdf24 ths
            tb->cs_base == cs_base &&
145 8a40a180 bellard
            tb->flags == flags) {
146 8a40a180 bellard
            /* check next page if needed */
147 8a40a180 bellard
            if (tb->page_addr[1] != -1) {
148 337fc758 Blue Swirl
                tb_page_addr_t phys_page2;
149 337fc758 Blue Swirl
150 5fafdf24 ths
                virt_page2 = (pc & TARGET_PAGE_MASK) +
151 8a40a180 bellard
                    TARGET_PAGE_SIZE;
152 41c1b1c9 Paul Brook
                phys_page2 = get_page_addr_code(env, virt_page2);
153 8a40a180 bellard
                if (tb->page_addr[1] == phys_page2)
154 8a40a180 bellard
                    goto found;
155 8a40a180 bellard
            } else {
156 8a40a180 bellard
                goto found;
157 8a40a180 bellard
            }
158 8a40a180 bellard
        }
159 8a40a180 bellard
        ptb1 = &tb->phys_hash_next;
160 8a40a180 bellard
    }
161 8a40a180 bellard
 not_found:
162 2e70f6ef pbrook
   /* if no translated code available, then translate it now */
163 2e70f6ef pbrook
    tb = tb_gen_code(env, pc, cs_base, flags, 0);
164 3b46e624 ths
165 8a40a180 bellard
 found:
166 2c90fe2b Kirill Batuzov
    /* Move the last found TB to the head of the list */
167 2c90fe2b Kirill Batuzov
    if (likely(*ptb1)) {
168 2c90fe2b Kirill Batuzov
        *ptb1 = tb->phys_hash_next;
169 5e5f07e0 Evgeny Voevodin
        tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
170 5e5f07e0 Evgeny Voevodin
        tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
171 2c90fe2b Kirill Batuzov
    }
172 8a40a180 bellard
    /* we add the TB in the virtual pc hash table */
173 8a40a180 bellard
    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
174 8a40a180 bellard
    return tb;
175 8a40a180 bellard
}
176 8a40a180 bellard
177 9349b4f9 Andreas Färber
static inline TranslationBlock *tb_find_fast(CPUArchState *env)
178 8a40a180 bellard
{
179 8a40a180 bellard
    TranslationBlock *tb;
180 8a40a180 bellard
    target_ulong cs_base, pc;
181 6b917547 aliguori
    int flags;
182 8a40a180 bellard
183 8a40a180 bellard
    /* we record a subset of the CPU state. It will
184 8a40a180 bellard
       always be the same before a given translated block
185 8a40a180 bellard
       is executed. */
186 6b917547 aliguori
    cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
187 bce61846 bellard
    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
188 551bd27f ths
    if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
189 551bd27f ths
                 tb->flags != flags)) {
190 cea5f9a2 Blue Swirl
        tb = tb_find_slow(env, pc, cs_base, flags);
191 8a40a180 bellard
    }
192 8a40a180 bellard
    return tb;
193 8a40a180 bellard
}
194 8a40a180 bellard
195 1009d2ed Jan Kiszka
static CPUDebugExcpHandler *debug_excp_handler;
196 1009d2ed Jan Kiszka
197 84e3b602 Igor Mammedov
void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
198 1009d2ed Jan Kiszka
{
199 1009d2ed Jan Kiszka
    debug_excp_handler = handler;
200 1009d2ed Jan Kiszka
}
201 1009d2ed Jan Kiszka
202 9349b4f9 Andreas Färber
static void cpu_handle_debug_exception(CPUArchState *env)
203 1009d2ed Jan Kiszka
{
204 1009d2ed Jan Kiszka
    CPUWatchpoint *wp;
205 1009d2ed Jan Kiszka
206 1009d2ed Jan Kiszka
    if (!env->watchpoint_hit) {
207 1009d2ed Jan Kiszka
        QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
208 1009d2ed Jan Kiszka
            wp->flags &= ~BP_WATCHPOINT_HIT;
209 1009d2ed Jan Kiszka
        }
210 1009d2ed Jan Kiszka
    }
211 1009d2ed Jan Kiszka
    if (debug_excp_handler) {
212 1009d2ed Jan Kiszka
        debug_excp_handler(env);
213 1009d2ed Jan Kiszka
    }
214 1009d2ed Jan Kiszka
}
215 1009d2ed Jan Kiszka
216 7d13299d bellard
/* main execution loop */
217 7d13299d bellard
218 1a28cac3 Marcelo Tosatti
volatile sig_atomic_t exit_request;
219 1a28cac3 Marcelo Tosatti
220 9349b4f9 Andreas Färber
int cpu_exec(CPUArchState *env)
221 7d13299d bellard
{
222 c356a1bc Andreas Färber
    CPUState *cpu = ENV_GET_CPU(env);
223 97a8ea5a Andreas Färber
#if !(defined(CONFIG_USER_ONLY) && \
224 97a8ea5a Andreas Färber
      (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
225 97a8ea5a Andreas Färber
    CPUClass *cc = CPU_GET_CLASS(cpu);
226 97a8ea5a Andreas Färber
#endif
227 693fa551 Andreas Färber
#ifdef TARGET_I386
228 693fa551 Andreas Färber
    X86CPU *x86_cpu = X86_CPU(cpu);
229 693fa551 Andreas Färber
#endif
230 8a40a180 bellard
    int ret, interrupt_request;
231 8a40a180 bellard
    TranslationBlock *tb;
232 c27004ec bellard
    uint8_t *tc_ptr;
233 3e9bd63a Richard Henderson
    uintptr_t next_tb;
234 8c6939c0 bellard
235 259186a7 Andreas Färber
    if (cpu->halted) {
236 3993c6bd Andreas Färber
        if (!cpu_has_work(cpu)) {
237 eda48c34 Paolo Bonzini
            return EXCP_HALTED;
238 eda48c34 Paolo Bonzini
        }
239 eda48c34 Paolo Bonzini
240 259186a7 Andreas Färber
        cpu->halted = 0;
241 eda48c34 Paolo Bonzini
    }
242 5a1e3cfc bellard
243 4917cf44 Andreas Färber
    current_cpu = cpu;
244 e4533c7a bellard
245 4917cf44 Andreas Färber
    /* As long as current_cpu is null, up to the assignment just above,
246 ec9bd89f Olivier Hainque
     * requests by other threads to exit the execution loop are expected to
247 ec9bd89f Olivier Hainque
     * be issued using the exit_request global. We must make sure that our
248 4917cf44 Andreas Färber
     * evaluation of the global value is performed past the current_cpu
249 ec9bd89f Olivier Hainque
     * value transition point, which requires a memory barrier as well as
250 ec9bd89f Olivier Hainque
     * an instruction scheduling constraint on modern architectures.  */
251 ec9bd89f Olivier Hainque
    smp_mb();
252 ec9bd89f Olivier Hainque
253 c629a4bc Jan Kiszka
    if (unlikely(exit_request)) {
254 fcd7d003 Andreas Färber
        cpu->exit_request = 1;
255 1a28cac3 Marcelo Tosatti
    }
256 1a28cac3 Marcelo Tosatti
257 ecb644f4 ths
#if defined(TARGET_I386)
258 6792a57b Jan Kiszka
    /* put eflags in CPU temporary format */
259 6792a57b Jan Kiszka
    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
260 80cf2c81 liguang
    env->df = 1 - (2 * ((env->eflags >> 10) & 1));
261 6792a57b Jan Kiszka
    CC_OP = CC_OP_EFLAGS;
262 6792a57b Jan Kiszka
    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
263 93ac68bc bellard
#elif defined(TARGET_SPARC)
264 e6e5906b pbrook
#elif defined(TARGET_M68K)
265 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
266 e6e5906b pbrook
    env->cc_dest = env->sr & 0xf;
267 e6e5906b pbrook
    env->cc_x = (env->sr >> 4) & 1;
268 ecb644f4 ths
#elif defined(TARGET_ALPHA)
269 ecb644f4 ths
#elif defined(TARGET_ARM)
270 d2fbca94 Guan Xuetao
#elif defined(TARGET_UNICORE32)
271 ecb644f4 ths
#elif defined(TARGET_PPC)
272 4e85f82c Elie Richa
    env->reserve_addr = -1;
273 81ea0e13 Michael Walle
#elif defined(TARGET_LM32)
274 b779e29e Edgar E. Iglesias
#elif defined(TARGET_MICROBLAZE)
275 6af0bf9c bellard
#elif defined(TARGET_MIPS)
276 d15a9c23 Anthony Green
#elif defined(TARGET_MOXIE)
277 e67db06e Jia Liu
#elif defined(TARGET_OPENRISC)
278 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
279 f1ccf904 ths
#elif defined(TARGET_CRIS)
280 10ec5117 Alexander Graf
#elif defined(TARGET_S390X)
281 2328826b Max Filippov
#elif defined(TARGET_XTENSA)
282 fdf9b3e8 bellard
    /* XXXXX */
283 e4533c7a bellard
#else
284 e4533c7a bellard
#error unsupported target CPU
285 e4533c7a bellard
#endif
286 3fb2ded1 bellard
    env->exception_index = -1;
287 9d27abd9 bellard
288 7d13299d bellard
    /* prepare setjmp context for exception handling */
289 3fb2ded1 bellard
    for(;;) {
290 6ab7e546 Peter Maydell
        if (sigsetjmp(env->jmp_env, 0) == 0) {
291 3fb2ded1 bellard
            /* if an exception is pending, we execute it here */
292 3fb2ded1 bellard
            if (env->exception_index >= 0) {
293 3fb2ded1 bellard
                if (env->exception_index >= EXCP_INTERRUPT) {
294 3fb2ded1 bellard
                    /* exit request from the cpu execution loop */
295 3fb2ded1 bellard
                    ret = env->exception_index;
296 1009d2ed Jan Kiszka
                    if (ret == EXCP_DEBUG) {
297 1009d2ed Jan Kiszka
                        cpu_handle_debug_exception(env);
298 1009d2ed Jan Kiszka
                    }
299 3fb2ded1 bellard
                    break;
300 72d239ed aurel32
                } else {
301 72d239ed aurel32
#if defined(CONFIG_USER_ONLY)
302 3fb2ded1 bellard
                    /* if user mode only, we simulate a fake exception
303 9f083493 ths
                       which will be handled outside the cpu execution
304 3fb2ded1 bellard
                       loop */
305 83479e77 bellard
#if defined(TARGET_I386)
306 97a8ea5a Andreas Färber
                    cc->do_interrupt(cpu);
307 83479e77 bellard
#endif
308 3fb2ded1 bellard
                    ret = env->exception_index;
309 3fb2ded1 bellard
                    break;
310 72d239ed aurel32
#else
311 97a8ea5a Andreas Färber
                    cc->do_interrupt(cpu);
312 301d2908 Paolo Bonzini
                    env->exception_index = -1;
313 72d239ed aurel32
#endif
314 3fb2ded1 bellard
                }
315 5fafdf24 ths
            }
316 9df217a3 bellard
317 b5fc09ae blueswir1
            next_tb = 0; /* force lookup of first TB */
318 3fb2ded1 bellard
            for(;;) {
319 259186a7 Andreas Färber
                interrupt_request = cpu->interrupt_request;
320 e1638bd8 malc
                if (unlikely(interrupt_request)) {
321 ed2803da Andreas Färber
                    if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
322 e1638bd8 malc
                        /* Mask out external interrupts for this step. */
323 3125f763 Richard Henderson
                        interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
324 e1638bd8 malc
                    }
325 6658ffb8 pbrook
                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
326 259186a7 Andreas Färber
                        cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
327 6658ffb8 pbrook
                        env->exception_index = EXCP_DEBUG;
328 1162c041 Blue Swirl
                        cpu_loop_exit(env);
329 6658ffb8 pbrook
                    }
330 a90b7318 balrog
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
331 b779e29e Edgar E. Iglesias
    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
332 d2fbca94 Guan Xuetao
    defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
333 a90b7318 balrog
                    if (interrupt_request & CPU_INTERRUPT_HALT) {
334 259186a7 Andreas Färber
                        cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
335 259186a7 Andreas Färber
                        cpu->halted = 1;
336 a90b7318 balrog
                        env->exception_index = EXCP_HLT;
337 1162c041 Blue Swirl
                        cpu_loop_exit(env);
338 a90b7318 balrog
                    }
339 a90b7318 balrog
#endif
340 68a79315 bellard
#if defined(TARGET_I386)
341 5d62c43a Jan Kiszka
#if !defined(CONFIG_USER_ONLY)
342 5d62c43a Jan Kiszka
                    if (interrupt_request & CPU_INTERRUPT_POLL) {
343 259186a7 Andreas Färber
                        cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
344 693fa551 Andreas Färber
                        apic_poll_irq(x86_cpu->apic_state);
345 5d62c43a Jan Kiszka
                    }
346 5d62c43a Jan Kiszka
#endif
347 b09ea7d5 Gleb Natapov
                    if (interrupt_request & CPU_INTERRUPT_INIT) {
348 77b2bc2c Blue Swirl
                            cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
349 77b2bc2c Blue Swirl
                                                          0);
350 693fa551 Andreas Färber
                            do_cpu_init(x86_cpu);
351 b09ea7d5 Gleb Natapov
                            env->exception_index = EXCP_HALTED;
352 1162c041 Blue Swirl
                            cpu_loop_exit(env);
353 b09ea7d5 Gleb Natapov
                    } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
354 693fa551 Andreas Färber
                            do_cpu_sipi(x86_cpu);
355 b09ea7d5 Gleb Natapov
                    } else if (env->hflags2 & HF2_GIF_MASK) {
356 db620f46 bellard
                        if ((interrupt_request & CPU_INTERRUPT_SMI) &&
357 db620f46 bellard
                            !(env->hflags & HF_SMM_MASK)) {
358 77b2bc2c Blue Swirl
                            cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
359 77b2bc2c Blue Swirl
                                                          0);
360 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
361 693fa551 Andreas Färber
                            do_smm_enter(x86_cpu);
362 db620f46 bellard
                            next_tb = 0;
363 db620f46 bellard
                        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
364 db620f46 bellard
                                   !(env->hflags2 & HF2_NMI_MASK)) {
365 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
366 db620f46 bellard
                            env->hflags2 |= HF2_NMI_MASK;
367 e694d4e2 Blue Swirl
                            do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
368 db620f46 bellard
                            next_tb = 0;
369 e965fc38 陳韋任
                        } else if (interrupt_request & CPU_INTERRUPT_MCE) {
370 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
371 e694d4e2 Blue Swirl
                            do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
372 79c4f6b0 Huang Ying
                            next_tb = 0;
373 db620f46 bellard
                        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
374 db620f46 bellard
                                   (((env->hflags2 & HF2_VINTR_MASK) && 
375 db620f46 bellard
                                     (env->hflags2 & HF2_HIF_MASK)) ||
376 db620f46 bellard
                                    (!(env->hflags2 & HF2_VINTR_MASK) && 
377 db620f46 bellard
                                     (env->eflags & IF_MASK && 
378 db620f46 bellard
                                      !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
379 db620f46 bellard
                            int intno;
380 77b2bc2c Blue Swirl
                            cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
381 77b2bc2c Blue Swirl
                                                          0);
382 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
383 259186a7 Andreas Färber
                                                        CPU_INTERRUPT_VIRQ);
384 db620f46 bellard
                            intno = cpu_get_pic_interrupt(env);
385 4f213879 malc
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
386 4f213879 malc
                            do_interrupt_x86_hardirq(env, intno, 1);
387 4f213879 malc
                            /* ensure that no TB jump will be modified as
388 4f213879 malc
                               the program flow was changed */
389 4f213879 malc
                            next_tb = 0;
390 0573fbfc ths
#if !defined(CONFIG_USER_ONLY)
391 db620f46 bellard
                        } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
392 db620f46 bellard
                                   (env->eflags & IF_MASK) && 
393 db620f46 bellard
                                   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
394 db620f46 bellard
                            int intno;
395 db620f46 bellard
                            /* FIXME: this should respect TPR */
396 77b2bc2c Blue Swirl
                            cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
397 77b2bc2c Blue Swirl
                                                          0);
398 db620f46 bellard
                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
399 93fcfe39 aliguori
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
400 e694d4e2 Blue Swirl
                            do_interrupt_x86_hardirq(env, intno, 1);
401 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
402 db620f46 bellard
                            next_tb = 0;
403 0573fbfc ths
#endif
404 db620f46 bellard
                        }
405 68a79315 bellard
                    }
406 ce09776b bellard
#elif defined(TARGET_PPC)
407 9fddaa0c bellard
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
408 c356a1bc Andreas Färber
                        cpu_reset(cpu);
409 9fddaa0c bellard
                    }
410 47103572 j_mayer
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
411 e9df014c j_mayer
                        ppc_hw_interrupt(env);
412 259186a7 Andreas Färber
                        if (env->pending_interrupts == 0) {
413 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
414 259186a7 Andreas Färber
                        }
415 b5fc09ae blueswir1
                        next_tb = 0;
416 ce09776b bellard
                    }
417 81ea0e13 Michael Walle
#elif defined(TARGET_LM32)
418 81ea0e13 Michael Walle
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
419 81ea0e13 Michael Walle
                        && (env->ie & IE_IE)) {
420 81ea0e13 Michael Walle
                        env->exception_index = EXCP_IRQ;
421 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
422 81ea0e13 Michael Walle
                        next_tb = 0;
423 81ea0e13 Michael Walle
                    }
424 b779e29e Edgar E. Iglesias
#elif defined(TARGET_MICROBLAZE)
425 b779e29e Edgar E. Iglesias
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
426 b779e29e Edgar E. Iglesias
                        && (env->sregs[SR_MSR] & MSR_IE)
427 b779e29e Edgar E. Iglesias
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
428 b779e29e Edgar E. Iglesias
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
429 b779e29e Edgar E. Iglesias
                        env->exception_index = EXCP_IRQ;
430 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
431 b779e29e Edgar E. Iglesias
                        next_tb = 0;
432 b779e29e Edgar E. Iglesias
                    }
433 6af0bf9c bellard
#elif defined(TARGET_MIPS)
434 6af0bf9c bellard
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
435 4cdc1cd1 Aurelien Jarno
                        cpu_mips_hw_interrupts_pending(env)) {
436 6af0bf9c bellard
                        /* Raise it */
437 6af0bf9c bellard
                        env->exception_index = EXCP_EXT_INTERRUPT;
438 6af0bf9c bellard
                        env->error_code = 0;
439 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
440 b5fc09ae blueswir1
                        next_tb = 0;
441 6af0bf9c bellard
                    }
442 b6a71ef7 Jia Liu
#elif defined(TARGET_OPENRISC)
443 b6a71ef7 Jia Liu
                    {
444 b6a71ef7 Jia Liu
                        int idx = -1;
445 b6a71ef7 Jia Liu
                        if ((interrupt_request & CPU_INTERRUPT_HARD)
446 b6a71ef7 Jia Liu
                            && (env->sr & SR_IEE)) {
447 b6a71ef7 Jia Liu
                            idx = EXCP_INT;
448 b6a71ef7 Jia Liu
                        }
449 b6a71ef7 Jia Liu
                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
450 b6a71ef7 Jia Liu
                            && (env->sr & SR_TEE)) {
451 b6a71ef7 Jia Liu
                            idx = EXCP_TICK;
452 b6a71ef7 Jia Liu
                        }
453 b6a71ef7 Jia Liu
                        if (idx >= 0) {
454 b6a71ef7 Jia Liu
                            env->exception_index = idx;
455 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
456 b6a71ef7 Jia Liu
                            next_tb = 0;
457 b6a71ef7 Jia Liu
                        }
458 b6a71ef7 Jia Liu
                    }
459 e95c8d51 bellard
#elif defined(TARGET_SPARC)
460 d532b26c Igor V. Kovalenko
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
461 d532b26c Igor V. Kovalenko
                        if (cpu_interrupts_enabled(env) &&
462 d532b26c Igor V. Kovalenko
                            env->interrupt_index > 0) {
463 d532b26c Igor V. Kovalenko
                            int pil = env->interrupt_index & 0xf;
464 d532b26c Igor V. Kovalenko
                            int type = env->interrupt_index & 0xf0;
465 d532b26c Igor V. Kovalenko
466 d532b26c Igor V. Kovalenko
                            if (((type == TT_EXTINT) &&
467 d532b26c Igor V. Kovalenko
                                  cpu_pil_allowed(env, pil)) ||
468 d532b26c Igor V. Kovalenko
                                  type != TT_EXTINT) {
469 d532b26c Igor V. Kovalenko
                                env->exception_index = env->interrupt_index;
470 97a8ea5a Andreas Färber
                                cc->do_interrupt(cpu);
471 d532b26c Igor V. Kovalenko
                                next_tb = 0;
472 d532b26c Igor V. Kovalenko
                            }
473 d532b26c Igor V. Kovalenko
                        }
474 e965fc38 陳韋任
                    }
475 b5ff1b31 bellard
#elif defined(TARGET_ARM)
476 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_FIQ
477 b5ff1b31 bellard
                        && !(env->uncached_cpsr & CPSR_F)) {
478 b5ff1b31 bellard
                        env->exception_index = EXCP_FIQ;
479 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
480 b5fc09ae blueswir1
                        next_tb = 0;
481 b5ff1b31 bellard
                    }
482 9ee6e8bb pbrook
                    /* ARMv7-M interrupt return works by loading a magic value
483 9ee6e8bb pbrook
                       into the PC.  On real hardware the load causes the
484 9ee6e8bb pbrook
                       return to occur.  The qemu implementation performs the
485 9ee6e8bb pbrook
                       jump normally, then does the exception return when the
486 9ee6e8bb pbrook
                       CPU tries to execute code at the magic address.
487 9ee6e8bb pbrook
                       This will cause the magic PC value to be pushed to
488 a1c7273b Stefan Weil
                       the stack if an interrupt occurred at the wrong time.
489 9ee6e8bb pbrook
                       We avoid this by disabling interrupts when
490 9ee6e8bb pbrook
                       pc contains a magic address.  */
491 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_HARD
492 9ee6e8bb pbrook
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
493 9ee6e8bb pbrook
                            || !(env->uncached_cpsr & CPSR_I))) {
494 b5ff1b31 bellard
                        env->exception_index = EXCP_IRQ;
495 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
496 b5fc09ae blueswir1
                        next_tb = 0;
497 b5ff1b31 bellard
                    }
498 d2fbca94 Guan Xuetao
#elif defined(TARGET_UNICORE32)
499 d2fbca94 Guan Xuetao
                    if (interrupt_request & CPU_INTERRUPT_HARD
500 d2fbca94 Guan Xuetao
                        && !(env->uncached_asr & ASR_I)) {
501 d48813dd Guan Xuetao
                        env->exception_index = UC32_EXCP_INTR;
502 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
503 d2fbca94 Guan Xuetao
                        next_tb = 0;
504 d2fbca94 Guan Xuetao
                    }
505 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
506 e96e2044 ths
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
507 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
508 b5fc09ae blueswir1
                        next_tb = 0;
509 e96e2044 ths
                    }
510 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
511 6a80e088 Richard Henderson
                    {
512 6a80e088 Richard Henderson
                        int idx = -1;
513 6a80e088 Richard Henderson
                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
514 e965fc38 陳韋任
                        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
515 6a80e088 Richard Henderson
                        case 0 ... 3:
516 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_HARD) {
517 6a80e088 Richard Henderson
                                idx = EXCP_DEV_INTERRUPT;
518 6a80e088 Richard Henderson
                            }
519 6a80e088 Richard Henderson
                            /* FALLTHRU */
520 6a80e088 Richard Henderson
                        case 4:
521 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
522 6a80e088 Richard Henderson
                                idx = EXCP_CLK_INTERRUPT;
523 6a80e088 Richard Henderson
                            }
524 6a80e088 Richard Henderson
                            /* FALLTHRU */
525 6a80e088 Richard Henderson
                        case 5:
526 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_SMP) {
527 6a80e088 Richard Henderson
                                idx = EXCP_SMP_INTERRUPT;
528 6a80e088 Richard Henderson
                            }
529 6a80e088 Richard Henderson
                            /* FALLTHRU */
530 6a80e088 Richard Henderson
                        case 6:
531 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
532 6a80e088 Richard Henderson
                                idx = EXCP_MCHK;
533 6a80e088 Richard Henderson
                            }
534 6a80e088 Richard Henderson
                        }
535 6a80e088 Richard Henderson
                        if (idx >= 0) {
536 6a80e088 Richard Henderson
                            env->exception_index = idx;
537 6a80e088 Richard Henderson
                            env->error_code = 0;
538 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
539 6a80e088 Richard Henderson
                            next_tb = 0;
540 6a80e088 Richard Henderson
                        }
541 eddf68a6 j_mayer
                    }
542 f1ccf904 ths
#elif defined(TARGET_CRIS)
543 1b1a38b0 edgar_igl
                    if (interrupt_request & CPU_INTERRUPT_HARD
544 fb9fb692 Edgar E. Iglesias
                        && (env->pregs[PR_CCS] & I_FLAG)
545 fb9fb692 Edgar E. Iglesias
                        && !env->locked_irq) {
546 1b1a38b0 edgar_igl
                        env->exception_index = EXCP_IRQ;
547 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
548 1b1a38b0 edgar_igl
                        next_tb = 0;
549 1b1a38b0 edgar_igl
                    }
550 8219314b Lars Persson
                    if (interrupt_request & CPU_INTERRUPT_NMI) {
551 8219314b Lars Persson
                        unsigned int m_flag_archval;
552 8219314b Lars Persson
                        if (env->pregs[PR_VR] < 32) {
553 8219314b Lars Persson
                            m_flag_archval = M_FLAG_V10;
554 8219314b Lars Persson
                        } else {
555 8219314b Lars Persson
                            m_flag_archval = M_FLAG_V32;
556 8219314b Lars Persson
                        }
557 8219314b Lars Persson
                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
558 8219314b Lars Persson
                            env->exception_index = EXCP_NMI;
559 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
560 8219314b Lars Persson
                            next_tb = 0;
561 8219314b Lars Persson
                        }
562 f1ccf904 ths
                    }
563 0633879f pbrook
#elif defined(TARGET_M68K)
564 0633879f pbrook
                    if (interrupt_request & CPU_INTERRUPT_HARD
565 0633879f pbrook
                        && ((env->sr & SR_I) >> SR_I_SHIFT)
566 0633879f pbrook
                            < env->pending_level) {
567 0633879f pbrook
                        /* Real hardware gets the interrupt vector via an
568 0633879f pbrook
                           IACK cycle at this point.  Current emulated
569 0633879f pbrook
                           hardware doesn't rely on this, so we
570 0633879f pbrook
                           provide/save the vector when the interrupt is
571 0633879f pbrook
                           first signalled.  */
572 0633879f pbrook
                        env->exception_index = env->pending_vector;
573 3c688828 Blue Swirl
                        do_interrupt_m68k_hardirq(env);
574 b5fc09ae blueswir1
                        next_tb = 0;
575 0633879f pbrook
                    }
576 3110e292 Alexander Graf
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
577 3110e292 Alexander Graf
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
578 3110e292 Alexander Graf
                        (env->psw.mask & PSW_MASK_EXT)) {
579 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
580 3110e292 Alexander Graf
                        next_tb = 0;
581 3110e292 Alexander Graf
                    }
582 40643d7c Max Filippov
#elif defined(TARGET_XTENSA)
583 40643d7c Max Filippov
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
584 40643d7c Max Filippov
                        env->exception_index = EXC_IRQ;
585 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
586 40643d7c Max Filippov
                        next_tb = 0;
587 40643d7c Max Filippov
                    }
588 68a79315 bellard
#endif
589 ff2712ba Stefan Weil
                   /* Don't use the cached interrupt_request value,
590 9d05095e bellard
                      do_interrupt may have updated the EXITTB flag. */
591 259186a7 Andreas Färber
                    if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
592 259186a7 Andreas Färber
                        cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
593 bf3e8bf1 bellard
                        /* ensure that no TB jump will be modified as
594 bf3e8bf1 bellard
                           the program flow was changed */
595 b5fc09ae blueswir1
                        next_tb = 0;
596 bf3e8bf1 bellard
                    }
597 be214e6c aurel32
                }
598 fcd7d003 Andreas Färber
                if (unlikely(cpu->exit_request)) {
599 fcd7d003 Andreas Färber
                    cpu->exit_request = 0;
600 be214e6c aurel32
                    env->exception_index = EXCP_INTERRUPT;
601 1162c041 Blue Swirl
                    cpu_loop_exit(env);
602 3fb2ded1 bellard
                }
603 5e5f07e0 Evgeny Voevodin
                spin_lock(&tcg_ctx.tb_ctx.tb_lock);
604 cea5f9a2 Blue Swirl
                tb = tb_find_fast(env);
605 d5975363 pbrook
                /* Note: we do it here to avoid a gcc bug on Mac OS X when
606 d5975363 pbrook
                   doing it in tb_find_slow */
607 5e5f07e0 Evgeny Voevodin
                if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
608 d5975363 pbrook
                    /* as some TB could have been invalidated because
609 d5975363 pbrook
                       of memory exceptions while generating the code, we
610 d5975363 pbrook
                       must recompute the hash index here */
611 d5975363 pbrook
                    next_tb = 0;
612 5e5f07e0 Evgeny Voevodin
                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
613 d5975363 pbrook
                }
614 c30d1aea Peter Maydell
                if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
615 c30d1aea Peter Maydell
                    qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
616 c30d1aea Peter Maydell
                             tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
617 c30d1aea Peter Maydell
                }
618 8a40a180 bellard
                /* see if we can patch the calling TB. When the TB
619 8a40a180 bellard
                   spans two pages, we cannot safely do a direct
620 8a40a180 bellard
                   jump. */
621 040f2fb2 Paolo Bonzini
                if (next_tb != 0 && tb->page_addr[1] == -1) {
622 0980011b Peter Maydell
                    tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
623 0980011b Peter Maydell
                                next_tb & TB_EXIT_MASK, tb);
624 3fb2ded1 bellard
                }
625 5e5f07e0 Evgeny Voevodin
                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
626 55e8b85e malc
627 55e8b85e malc
                /* cpu_interrupt might be called while translating the
628 55e8b85e malc
                   TB, but before it is linked into a potentially
629 55e8b85e malc
                   infinite loop and becomes env->current_tb. Avoid
630 55e8b85e malc
                   starting execution if there is a pending interrupt. */
631 d77953b9 Andreas Färber
                cpu->current_tb = tb;
632 b0052d15 Jan Kiszka
                barrier();
633 fcd7d003 Andreas Färber
                if (likely(!cpu->exit_request)) {
634 2e70f6ef pbrook
                    tc_ptr = tb->tc_ptr;
635 e965fc38 陳韋任
                    /* execute the generated code */
636 77211379 Peter Maydell
                    next_tb = cpu_tb_exec(cpu, tc_ptr);
637 378df4b2 Peter Maydell
                    switch (next_tb & TB_EXIT_MASK) {
638 378df4b2 Peter Maydell
                    case TB_EXIT_REQUESTED:
639 378df4b2 Peter Maydell
                        /* Something asked us to stop executing
640 378df4b2 Peter Maydell
                         * chained TBs; just continue round the main
641 378df4b2 Peter Maydell
                         * loop. Whatever requested the exit will also
642 378df4b2 Peter Maydell
                         * have set something else (eg exit_request or
643 378df4b2 Peter Maydell
                         * interrupt_request) which we will handle
644 378df4b2 Peter Maydell
                         * next time around the loop.
645 378df4b2 Peter Maydell
                         */
646 378df4b2 Peter Maydell
                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
647 378df4b2 Peter Maydell
                        next_tb = 0;
648 378df4b2 Peter Maydell
                        break;
649 378df4b2 Peter Maydell
                    case TB_EXIT_ICOUNT_EXPIRED:
650 378df4b2 Peter Maydell
                    {
651 bf20dc07 ths
                        /* Instruction counter expired.  */
652 2e70f6ef pbrook
                        int insns_left;
653 0980011b Peter Maydell
                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
654 2e70f6ef pbrook
                        insns_left = env->icount_decr.u32;
655 2e70f6ef pbrook
                        if (env->icount_extra && insns_left >= 0) {
656 2e70f6ef pbrook
                            /* Refill decrementer and continue execution.  */
657 2e70f6ef pbrook
                            env->icount_extra += insns_left;
658 2e70f6ef pbrook
                            if (env->icount_extra > 0xffff) {
659 2e70f6ef pbrook
                                insns_left = 0xffff;
660 2e70f6ef pbrook
                            } else {
661 2e70f6ef pbrook
                                insns_left = env->icount_extra;
662 2e70f6ef pbrook
                            }
663 2e70f6ef pbrook
                            env->icount_extra -= insns_left;
664 2e70f6ef pbrook
                            env->icount_decr.u16.low = insns_left;
665 2e70f6ef pbrook
                        } else {
666 2e70f6ef pbrook
                            if (insns_left > 0) {
667 2e70f6ef pbrook
                                /* Execute remaining instructions.  */
668 cea5f9a2 Blue Swirl
                                cpu_exec_nocache(env, insns_left, tb);
669 2e70f6ef pbrook
                            }
670 2e70f6ef pbrook
                            env->exception_index = EXCP_INTERRUPT;
671 2e70f6ef pbrook
                            next_tb = 0;
672 1162c041 Blue Swirl
                            cpu_loop_exit(env);
673 2e70f6ef pbrook
                        }
674 378df4b2 Peter Maydell
                        break;
675 378df4b2 Peter Maydell
                    }
676 378df4b2 Peter Maydell
                    default:
677 378df4b2 Peter Maydell
                        break;
678 2e70f6ef pbrook
                    }
679 2e70f6ef pbrook
                }
680 d77953b9 Andreas Färber
                cpu->current_tb = NULL;
681 4cbf74b6 bellard
                /* reset soft MMU for next block (it can currently
682 4cbf74b6 bellard
                   only be set by a memory fault) */
683 50a518e3 ths
            } /* for(;;) */
684 0d101938 Jan Kiszka
        } else {
685 0d101938 Jan Kiszka
            /* Reload env after longjmp - the compiler may have smashed all
686 0d101938 Jan Kiszka
             * local variables as longjmp is marked 'noreturn'. */
687 4917cf44 Andreas Färber
            cpu = current_cpu;
688 4917cf44 Andreas Färber
            env = cpu->env_ptr;
689 6c78f29a Juergen Lock
#if !(defined(CONFIG_USER_ONLY) && \
690 6c78f29a Juergen Lock
      (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
691 6c78f29a Juergen Lock
            cc = CPU_GET_CLASS(cpu);
692 6c78f29a Juergen Lock
#endif
693 693fa551 Andreas Färber
#ifdef TARGET_I386
694 693fa551 Andreas Färber
            x86_cpu = X86_CPU(cpu);
695 693fa551 Andreas Färber
#endif
696 7d13299d bellard
        }
697 3fb2ded1 bellard
    } /* for(;;) */
698 3fb2ded1 bellard
699 7d13299d bellard
700 e4533c7a bellard
#if defined(TARGET_I386)
701 9de5e440 bellard
    /* restore flags in standard format */
702 e694d4e2 Blue Swirl
    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
703 80cf2c81 liguang
        | (env->df & DF_MASK);
704 e4533c7a bellard
#elif defined(TARGET_ARM)
705 b7bcbe95 bellard
    /* XXX: Save/restore host fpu exception state?.  */
706 d2fbca94 Guan Xuetao
#elif defined(TARGET_UNICORE32)
707 93ac68bc bellard
#elif defined(TARGET_SPARC)
708 67867308 bellard
#elif defined(TARGET_PPC)
709 81ea0e13 Michael Walle
#elif defined(TARGET_LM32)
710 e6e5906b pbrook
#elif defined(TARGET_M68K)
711 e6e5906b pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
712 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
713 e6e5906b pbrook
    env->sr = (env->sr & 0xffe0)
714 e6e5906b pbrook
              | env->cc_dest | (env->cc_x << 4);
715 b779e29e Edgar E. Iglesias
#elif defined(TARGET_MICROBLAZE)
716 6af0bf9c bellard
#elif defined(TARGET_MIPS)
717 d15a9c23 Anthony Green
#elif defined(TARGET_MOXIE)
718 e67db06e Jia Liu
#elif defined(TARGET_OPENRISC)
719 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
720 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
721 f1ccf904 ths
#elif defined(TARGET_CRIS)
722 10ec5117 Alexander Graf
#elif defined(TARGET_S390X)
723 2328826b Max Filippov
#elif defined(TARGET_XTENSA)
724 fdf9b3e8 bellard
    /* XXXXX */
725 e4533c7a bellard
#else
726 e4533c7a bellard
#error unsupported target CPU
727 e4533c7a bellard
#endif
728 1057eaa7 pbrook
729 4917cf44 Andreas Färber
    /* fail safe : never use current_cpu outside cpu_exec() */
730 4917cf44 Andreas Färber
    current_cpu = NULL;
731 7d13299d bellard
    return ret;
732 7d13299d bellard
}