Statistics
| Branch: | Revision:

root / cpu-exec.c @ feature-archipelago

History | View | Annotate | Download (29.4 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 fdfba1a2 Edgar E. Iglesias
                            intno = ldl_phys(cpu->as,
399 fdfba1a2 Edgar E. Iglesias
                                             env->vm_vmcb
400 fdfba1a2 Edgar E. Iglesias
                                             + offsetof(struct vmcb,
401 fdfba1a2 Edgar E. Iglesias
                                                        control.int_vector));
402 93fcfe39 aliguori
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
403 e694d4e2 Blue Swirl
                            do_interrupt_x86_hardirq(env, intno, 1);
404 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
405 db620f46 bellard
                            next_tb = 0;
406 0573fbfc ths
#endif
407 db620f46 bellard
                        }
408 68a79315 bellard
                    }
409 ce09776b bellard
#elif defined(TARGET_PPC)
410 9fddaa0c bellard
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
411 c356a1bc Andreas Färber
                        cpu_reset(cpu);
412 9fddaa0c bellard
                    }
413 47103572 j_mayer
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
414 e9df014c j_mayer
                        ppc_hw_interrupt(env);
415 259186a7 Andreas Färber
                        if (env->pending_interrupts == 0) {
416 259186a7 Andreas Färber
                            cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
417 259186a7 Andreas Färber
                        }
418 b5fc09ae blueswir1
                        next_tb = 0;
419 ce09776b bellard
                    }
420 81ea0e13 Michael Walle
#elif defined(TARGET_LM32)
421 81ea0e13 Michael Walle
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
422 81ea0e13 Michael Walle
                        && (env->ie & IE_IE)) {
423 81ea0e13 Michael Walle
                        env->exception_index = EXCP_IRQ;
424 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
425 81ea0e13 Michael Walle
                        next_tb = 0;
426 81ea0e13 Michael Walle
                    }
427 b779e29e Edgar E. Iglesias
#elif defined(TARGET_MICROBLAZE)
428 b779e29e Edgar E. Iglesias
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
429 b779e29e Edgar E. Iglesias
                        && (env->sregs[SR_MSR] & MSR_IE)
430 b779e29e Edgar E. Iglesias
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
431 b779e29e Edgar E. Iglesias
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
432 b779e29e Edgar E. Iglesias
                        env->exception_index = EXCP_IRQ;
433 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
434 b779e29e Edgar E. Iglesias
                        next_tb = 0;
435 b779e29e Edgar E. Iglesias
                    }
436 6af0bf9c bellard
#elif defined(TARGET_MIPS)
437 6af0bf9c bellard
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
438 4cdc1cd1 Aurelien Jarno
                        cpu_mips_hw_interrupts_pending(env)) {
439 6af0bf9c bellard
                        /* Raise it */
440 6af0bf9c bellard
                        env->exception_index = EXCP_EXT_INTERRUPT;
441 6af0bf9c bellard
                        env->error_code = 0;
442 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
443 b5fc09ae blueswir1
                        next_tb = 0;
444 6af0bf9c bellard
                    }
445 b6a71ef7 Jia Liu
#elif defined(TARGET_OPENRISC)
446 b6a71ef7 Jia Liu
                    {
447 b6a71ef7 Jia Liu
                        int idx = -1;
448 b6a71ef7 Jia Liu
                        if ((interrupt_request & CPU_INTERRUPT_HARD)
449 b6a71ef7 Jia Liu
                            && (env->sr & SR_IEE)) {
450 b6a71ef7 Jia Liu
                            idx = EXCP_INT;
451 b6a71ef7 Jia Liu
                        }
452 b6a71ef7 Jia Liu
                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
453 b6a71ef7 Jia Liu
                            && (env->sr & SR_TEE)) {
454 b6a71ef7 Jia Liu
                            idx = EXCP_TICK;
455 b6a71ef7 Jia Liu
                        }
456 b6a71ef7 Jia Liu
                        if (idx >= 0) {
457 b6a71ef7 Jia Liu
                            env->exception_index = idx;
458 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
459 b6a71ef7 Jia Liu
                            next_tb = 0;
460 b6a71ef7 Jia Liu
                        }
461 b6a71ef7 Jia Liu
                    }
462 e95c8d51 bellard
#elif defined(TARGET_SPARC)
463 d532b26c Igor V. Kovalenko
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
464 d532b26c Igor V. Kovalenko
                        if (cpu_interrupts_enabled(env) &&
465 d532b26c Igor V. Kovalenko
                            env->interrupt_index > 0) {
466 d532b26c Igor V. Kovalenko
                            int pil = env->interrupt_index & 0xf;
467 d532b26c Igor V. Kovalenko
                            int type = env->interrupt_index & 0xf0;
468 d532b26c Igor V. Kovalenko
469 d532b26c Igor V. Kovalenko
                            if (((type == TT_EXTINT) &&
470 d532b26c Igor V. Kovalenko
                                  cpu_pil_allowed(env, pil)) ||
471 d532b26c Igor V. Kovalenko
                                  type != TT_EXTINT) {
472 d532b26c Igor V. Kovalenko
                                env->exception_index = env->interrupt_index;
473 97a8ea5a Andreas Färber
                                cc->do_interrupt(cpu);
474 d532b26c Igor V. Kovalenko
                                next_tb = 0;
475 d532b26c Igor V. Kovalenko
                            }
476 d532b26c Igor V. Kovalenko
                        }
477 e965fc38 陳韋任
                    }
478 b5ff1b31 bellard
#elif defined(TARGET_ARM)
479 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_FIQ
480 4cc35614 Peter Maydell
                        && !(env->daif & PSTATE_F)) {
481 b5ff1b31 bellard
                        env->exception_index = EXCP_FIQ;
482 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
483 b5fc09ae blueswir1
                        next_tb = 0;
484 b5ff1b31 bellard
                    }
485 9ee6e8bb pbrook
                    /* ARMv7-M interrupt return works by loading a magic value
486 9ee6e8bb pbrook
                       into the PC.  On real hardware the load causes the
487 9ee6e8bb pbrook
                       return to occur.  The qemu implementation performs the
488 9ee6e8bb pbrook
                       jump normally, then does the exception return when the
489 9ee6e8bb pbrook
                       CPU tries to execute code at the magic address.
490 9ee6e8bb pbrook
                       This will cause the magic PC value to be pushed to
491 a1c7273b Stefan Weil
                       the stack if an interrupt occurred at the wrong time.
492 9ee6e8bb pbrook
                       We avoid this by disabling interrupts when
493 9ee6e8bb pbrook
                       pc contains a magic address.  */
494 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_HARD
495 9ee6e8bb pbrook
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
496 4cc35614 Peter Maydell
                            || !(env->daif & PSTATE_I))) {
497 b5ff1b31 bellard
                        env->exception_index = EXCP_IRQ;
498 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
499 b5fc09ae blueswir1
                        next_tb = 0;
500 b5ff1b31 bellard
                    }
501 d2fbca94 Guan Xuetao
#elif defined(TARGET_UNICORE32)
502 d2fbca94 Guan Xuetao
                    if (interrupt_request & CPU_INTERRUPT_HARD
503 d2fbca94 Guan Xuetao
                        && !(env->uncached_asr & ASR_I)) {
504 d48813dd Guan Xuetao
                        env->exception_index = UC32_EXCP_INTR;
505 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
506 d2fbca94 Guan Xuetao
                        next_tb = 0;
507 d2fbca94 Guan Xuetao
                    }
508 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
509 e96e2044 ths
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
510 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
511 b5fc09ae blueswir1
                        next_tb = 0;
512 e96e2044 ths
                    }
513 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
514 6a80e088 Richard Henderson
                    {
515 6a80e088 Richard Henderson
                        int idx = -1;
516 6a80e088 Richard Henderson
                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
517 e965fc38 陳韋任
                        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
518 6a80e088 Richard Henderson
                        case 0 ... 3:
519 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_HARD) {
520 6a80e088 Richard Henderson
                                idx = EXCP_DEV_INTERRUPT;
521 6a80e088 Richard Henderson
                            }
522 6a80e088 Richard Henderson
                            /* FALLTHRU */
523 6a80e088 Richard Henderson
                        case 4:
524 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
525 6a80e088 Richard Henderson
                                idx = EXCP_CLK_INTERRUPT;
526 6a80e088 Richard Henderson
                            }
527 6a80e088 Richard Henderson
                            /* FALLTHRU */
528 6a80e088 Richard Henderson
                        case 5:
529 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_SMP) {
530 6a80e088 Richard Henderson
                                idx = EXCP_SMP_INTERRUPT;
531 6a80e088 Richard Henderson
                            }
532 6a80e088 Richard Henderson
                            /* FALLTHRU */
533 6a80e088 Richard Henderson
                        case 6:
534 6a80e088 Richard Henderson
                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
535 6a80e088 Richard Henderson
                                idx = EXCP_MCHK;
536 6a80e088 Richard Henderson
                            }
537 6a80e088 Richard Henderson
                        }
538 6a80e088 Richard Henderson
                        if (idx >= 0) {
539 6a80e088 Richard Henderson
                            env->exception_index = idx;
540 6a80e088 Richard Henderson
                            env->error_code = 0;
541 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
542 6a80e088 Richard Henderson
                            next_tb = 0;
543 6a80e088 Richard Henderson
                        }
544 eddf68a6 j_mayer
                    }
545 f1ccf904 ths
#elif defined(TARGET_CRIS)
546 1b1a38b0 edgar_igl
                    if (interrupt_request & CPU_INTERRUPT_HARD
547 fb9fb692 Edgar E. Iglesias
                        && (env->pregs[PR_CCS] & I_FLAG)
548 fb9fb692 Edgar E. Iglesias
                        && !env->locked_irq) {
549 1b1a38b0 edgar_igl
                        env->exception_index = EXCP_IRQ;
550 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
551 1b1a38b0 edgar_igl
                        next_tb = 0;
552 1b1a38b0 edgar_igl
                    }
553 8219314b Lars Persson
                    if (interrupt_request & CPU_INTERRUPT_NMI) {
554 8219314b Lars Persson
                        unsigned int m_flag_archval;
555 8219314b Lars Persson
                        if (env->pregs[PR_VR] < 32) {
556 8219314b Lars Persson
                            m_flag_archval = M_FLAG_V10;
557 8219314b Lars Persson
                        } else {
558 8219314b Lars Persson
                            m_flag_archval = M_FLAG_V32;
559 8219314b Lars Persson
                        }
560 8219314b Lars Persson
                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
561 8219314b Lars Persson
                            env->exception_index = EXCP_NMI;
562 97a8ea5a Andreas Färber
                            cc->do_interrupt(cpu);
563 8219314b Lars Persson
                            next_tb = 0;
564 8219314b Lars Persson
                        }
565 f1ccf904 ths
                    }
566 0633879f pbrook
#elif defined(TARGET_M68K)
567 0633879f pbrook
                    if (interrupt_request & CPU_INTERRUPT_HARD
568 0633879f pbrook
                        && ((env->sr & SR_I) >> SR_I_SHIFT)
569 0633879f pbrook
                            < env->pending_level) {
570 0633879f pbrook
                        /* Real hardware gets the interrupt vector via an
571 0633879f pbrook
                           IACK cycle at this point.  Current emulated
572 0633879f pbrook
                           hardware doesn't rely on this, so we
573 0633879f pbrook
                           provide/save the vector when the interrupt is
574 0633879f pbrook
                           first signalled.  */
575 0633879f pbrook
                        env->exception_index = env->pending_vector;
576 3c688828 Blue Swirl
                        do_interrupt_m68k_hardirq(env);
577 b5fc09ae blueswir1
                        next_tb = 0;
578 0633879f pbrook
                    }
579 3110e292 Alexander Graf
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
580 3110e292 Alexander Graf
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
581 3110e292 Alexander Graf
                        (env->psw.mask & PSW_MASK_EXT)) {
582 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
583 3110e292 Alexander Graf
                        next_tb = 0;
584 3110e292 Alexander Graf
                    }
585 40643d7c Max Filippov
#elif defined(TARGET_XTENSA)
586 40643d7c Max Filippov
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
587 40643d7c Max Filippov
                        env->exception_index = EXC_IRQ;
588 97a8ea5a Andreas Färber
                        cc->do_interrupt(cpu);
589 40643d7c Max Filippov
                        next_tb = 0;
590 40643d7c Max Filippov
                    }
591 68a79315 bellard
#endif
592 ff2712ba Stefan Weil
                   /* Don't use the cached interrupt_request value,
593 9d05095e bellard
                      do_interrupt may have updated the EXITTB flag. */
594 259186a7 Andreas Färber
                    if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
595 259186a7 Andreas Färber
                        cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
596 bf3e8bf1 bellard
                        /* ensure that no TB jump will be modified as
597 bf3e8bf1 bellard
                           the program flow was changed */
598 b5fc09ae blueswir1
                        next_tb = 0;
599 bf3e8bf1 bellard
                    }
600 be214e6c aurel32
                }
601 fcd7d003 Andreas Färber
                if (unlikely(cpu->exit_request)) {
602 fcd7d003 Andreas Färber
                    cpu->exit_request = 0;
603 be214e6c aurel32
                    env->exception_index = EXCP_INTERRUPT;
604 1162c041 Blue Swirl
                    cpu_loop_exit(env);
605 3fb2ded1 bellard
                }
606 5e5f07e0 Evgeny Voevodin
                spin_lock(&tcg_ctx.tb_ctx.tb_lock);
607 cea5f9a2 Blue Swirl
                tb = tb_find_fast(env);
608 d5975363 pbrook
                /* Note: we do it here to avoid a gcc bug on Mac OS X when
609 d5975363 pbrook
                   doing it in tb_find_slow */
610 5e5f07e0 Evgeny Voevodin
                if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
611 d5975363 pbrook
                    /* as some TB could have been invalidated because
612 d5975363 pbrook
                       of memory exceptions while generating the code, we
613 d5975363 pbrook
                       must recompute the hash index here */
614 d5975363 pbrook
                    next_tb = 0;
615 5e5f07e0 Evgeny Voevodin
                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
616 d5975363 pbrook
                }
617 c30d1aea Peter Maydell
                if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
618 c30d1aea Peter Maydell
                    qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
619 c30d1aea Peter Maydell
                             tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
620 c30d1aea Peter Maydell
                }
621 8a40a180 bellard
                /* see if we can patch the calling TB. When the TB
622 8a40a180 bellard
                   spans two pages, we cannot safely do a direct
623 8a40a180 bellard
                   jump. */
624 040f2fb2 Paolo Bonzini
                if (next_tb != 0 && tb->page_addr[1] == -1) {
625 0980011b Peter Maydell
                    tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
626 0980011b Peter Maydell
                                next_tb & TB_EXIT_MASK, tb);
627 3fb2ded1 bellard
                }
628 5e5f07e0 Evgeny Voevodin
                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
629 55e8b85e malc
630 55e8b85e malc
                /* cpu_interrupt might be called while translating the
631 55e8b85e malc
                   TB, but before it is linked into a potentially
632 55e8b85e malc
                   infinite loop and becomes env->current_tb. Avoid
633 55e8b85e malc
                   starting execution if there is a pending interrupt. */
634 d77953b9 Andreas Färber
                cpu->current_tb = tb;
635 b0052d15 Jan Kiszka
                barrier();
636 fcd7d003 Andreas Färber
                if (likely(!cpu->exit_request)) {
637 2e70f6ef pbrook
                    tc_ptr = tb->tc_ptr;
638 e965fc38 陳韋任
                    /* execute the generated code */
639 77211379 Peter Maydell
                    next_tb = cpu_tb_exec(cpu, tc_ptr);
640 378df4b2 Peter Maydell
                    switch (next_tb & TB_EXIT_MASK) {
641 378df4b2 Peter Maydell
                    case TB_EXIT_REQUESTED:
642 378df4b2 Peter Maydell
                        /* Something asked us to stop executing
643 378df4b2 Peter Maydell
                         * chained TBs; just continue round the main
644 378df4b2 Peter Maydell
                         * loop. Whatever requested the exit will also
645 378df4b2 Peter Maydell
                         * have set something else (eg exit_request or
646 378df4b2 Peter Maydell
                         * interrupt_request) which we will handle
647 378df4b2 Peter Maydell
                         * next time around the loop.
648 378df4b2 Peter Maydell
                         */
649 378df4b2 Peter Maydell
                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
650 378df4b2 Peter Maydell
                        next_tb = 0;
651 378df4b2 Peter Maydell
                        break;
652 378df4b2 Peter Maydell
                    case TB_EXIT_ICOUNT_EXPIRED:
653 378df4b2 Peter Maydell
                    {
654 bf20dc07 ths
                        /* Instruction counter expired.  */
655 2e70f6ef pbrook
                        int insns_left;
656 0980011b Peter Maydell
                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
657 2e70f6ef pbrook
                        insns_left = env->icount_decr.u32;
658 2e70f6ef pbrook
                        if (env->icount_extra && insns_left >= 0) {
659 2e70f6ef pbrook
                            /* Refill decrementer and continue execution.  */
660 2e70f6ef pbrook
                            env->icount_extra += insns_left;
661 2e70f6ef pbrook
                            if (env->icount_extra > 0xffff) {
662 2e70f6ef pbrook
                                insns_left = 0xffff;
663 2e70f6ef pbrook
                            } else {
664 2e70f6ef pbrook
                                insns_left = env->icount_extra;
665 2e70f6ef pbrook
                            }
666 2e70f6ef pbrook
                            env->icount_extra -= insns_left;
667 2e70f6ef pbrook
                            env->icount_decr.u16.low = insns_left;
668 2e70f6ef pbrook
                        } else {
669 2e70f6ef pbrook
                            if (insns_left > 0) {
670 2e70f6ef pbrook
                                /* Execute remaining instructions.  */
671 cea5f9a2 Blue Swirl
                                cpu_exec_nocache(env, insns_left, tb);
672 2e70f6ef pbrook
                            }
673 2e70f6ef pbrook
                            env->exception_index = EXCP_INTERRUPT;
674 2e70f6ef pbrook
                            next_tb = 0;
675 1162c041 Blue Swirl
                            cpu_loop_exit(env);
676 2e70f6ef pbrook
                        }
677 378df4b2 Peter Maydell
                        break;
678 378df4b2 Peter Maydell
                    }
679 378df4b2 Peter Maydell
                    default:
680 378df4b2 Peter Maydell
                        break;
681 2e70f6ef pbrook
                    }
682 2e70f6ef pbrook
                }
683 d77953b9 Andreas Färber
                cpu->current_tb = NULL;
684 4cbf74b6 bellard
                /* reset soft MMU for next block (it can currently
685 4cbf74b6 bellard
                   only be set by a memory fault) */
686 50a518e3 ths
            } /* for(;;) */
687 0d101938 Jan Kiszka
        } else {
688 0d101938 Jan Kiszka
            /* Reload env after longjmp - the compiler may have smashed all
689 0d101938 Jan Kiszka
             * local variables as longjmp is marked 'noreturn'. */
690 4917cf44 Andreas Färber
            cpu = current_cpu;
691 4917cf44 Andreas Färber
            env = cpu->env_ptr;
692 6c78f29a Juergen Lock
#if !(defined(CONFIG_USER_ONLY) && \
693 6c78f29a Juergen Lock
      (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
694 6c78f29a Juergen Lock
            cc = CPU_GET_CLASS(cpu);
695 6c78f29a Juergen Lock
#endif
696 693fa551 Andreas Färber
#ifdef TARGET_I386
697 693fa551 Andreas Färber
            x86_cpu = X86_CPU(cpu);
698 693fa551 Andreas Färber
#endif
699 7d13299d bellard
        }
700 3fb2ded1 bellard
    } /* for(;;) */
701 3fb2ded1 bellard
702 7d13299d bellard
703 e4533c7a bellard
#if defined(TARGET_I386)
704 9de5e440 bellard
    /* restore flags in standard format */
705 e694d4e2 Blue Swirl
    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
706 80cf2c81 liguang
        | (env->df & DF_MASK);
707 e4533c7a bellard
#elif defined(TARGET_ARM)
708 b7bcbe95 bellard
    /* XXX: Save/restore host fpu exception state?.  */
709 d2fbca94 Guan Xuetao
#elif defined(TARGET_UNICORE32)
710 93ac68bc bellard
#elif defined(TARGET_SPARC)
711 67867308 bellard
#elif defined(TARGET_PPC)
712 81ea0e13 Michael Walle
#elif defined(TARGET_LM32)
713 e6e5906b pbrook
#elif defined(TARGET_M68K)
714 e6e5906b pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
715 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
716 e6e5906b pbrook
    env->sr = (env->sr & 0xffe0)
717 e6e5906b pbrook
              | env->cc_dest | (env->cc_x << 4);
718 b779e29e Edgar E. Iglesias
#elif defined(TARGET_MICROBLAZE)
719 6af0bf9c bellard
#elif defined(TARGET_MIPS)
720 d15a9c23 Anthony Green
#elif defined(TARGET_MOXIE)
721 e67db06e Jia Liu
#elif defined(TARGET_OPENRISC)
722 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
723 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
724 f1ccf904 ths
#elif defined(TARGET_CRIS)
725 10ec5117 Alexander Graf
#elif defined(TARGET_S390X)
726 2328826b Max Filippov
#elif defined(TARGET_XTENSA)
727 fdf9b3e8 bellard
    /* XXXXX */
728 e4533c7a bellard
#else
729 e4533c7a bellard
#error unsupported target CPU
730 e4533c7a bellard
#endif
731 1057eaa7 pbrook
732 4917cf44 Andreas Färber
    /* fail safe : never use current_cpu outside cpu_exec() */
733 4917cf44 Andreas Färber
    current_cpu = NULL;
734 7d13299d bellard
    return ret;
735 7d13299d bellard
}