Statistics
| Branch: | Revision:

root / cpu-exec.c @ 5500316d

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