Statistics
| Branch: | Revision:

root / cpu-exec.c @ 13ef70f6

History | View | Annotate | Download (26.9 kB)

1
/*
2
 *  emulator main execution loop
3
 *
4
 *  Copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include "config.h"
20
#include "cpu.h"
21
#include "disas.h"
22
#include "tcg.h"
23
#include "qemu-barrier.h"
24
#include "qtest.h"
25

    
26
int tb_invalidated_flag;
27

    
28
//#define CONFIG_DEBUG_EXEC
29

    
30
bool qemu_cpu_has_work(CPUArchState *env)
31
{
32
    return cpu_has_work(env);
33
}
34

    
35
void cpu_loop_exit(CPUArchState *env)
36
{
37
    env->current_tb = NULL;
38
    longjmp(env->jmp_env, 1);
39
}
40

    
41
/* exit the current TB from a signal handler. The host registers are
42
   restored in a state compatible with the CPU emulator
43
 */
44
#if defined(CONFIG_SOFTMMU)
45
void cpu_resume_from_signal(CPUArchState *env, void *puc)
46
{
47
    /* XXX: restore cpu registers saved in host registers */
48

    
49
    env->exception_index = -1;
50
    longjmp(env->jmp_env, 1);
51
}
52
#endif
53

    
54
/* Execute the code without caching the generated code. An interpreter
55
   could be used if available. */
56
static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
57
                             TranslationBlock *orig_tb)
58
{
59
    tcg_target_ulong next_tb;
60
    TranslationBlock *tb;
61

    
62
    /* Should never happen.
63
       We only end up here when an existing TB is too long.  */
64
    if (max_cycles > CF_COUNT_MASK)
65
        max_cycles = CF_COUNT_MASK;
66

    
67
    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
68
                     max_cycles);
69
    env->current_tb = tb;
70
    /* execute the generated code */
71
    next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
72
    env->current_tb = NULL;
73

    
74
    if ((next_tb & 3) == 2) {
75
        /* Restore PC.  This may happen if async event occurs before
76
           the TB starts executing.  */
77
        cpu_pc_from_tb(env, tb);
78
    }
79
    tb_phys_invalidate(tb, -1);
80
    tb_free(tb);
81
}
82

    
83
static TranslationBlock *tb_find_slow(CPUArchState *env,
84
                                      target_ulong pc,
85
                                      target_ulong cs_base,
86
                                      uint64_t flags)
87
{
88
    TranslationBlock *tb, **ptb1;
89
    unsigned int h;
90
    tb_page_addr_t phys_pc, phys_page1;
91
    target_ulong virt_page2;
92

    
93
    tb_invalidated_flag = 0;
94

    
95
    /* find translated block using physical mappings */
96
    phys_pc = get_page_addr_code(env, pc);
97
    phys_page1 = phys_pc & TARGET_PAGE_MASK;
98
    h = tb_phys_hash_func(phys_pc);
99
    ptb1 = &tb_phys_hash[h];
100
    for(;;) {
101
        tb = *ptb1;
102
        if (!tb)
103
            goto not_found;
104
        if (tb->pc == pc &&
105
            tb->page_addr[0] == phys_page1 &&
106
            tb->cs_base == cs_base &&
107
            tb->flags == flags) {
108
            /* check next page if needed */
109
            if (tb->page_addr[1] != -1) {
110
                tb_page_addr_t phys_page2;
111

    
112
                virt_page2 = (pc & TARGET_PAGE_MASK) +
113
                    TARGET_PAGE_SIZE;
114
                phys_page2 = get_page_addr_code(env, virt_page2);
115
                if (tb->page_addr[1] == phys_page2)
116
                    goto found;
117
            } else {
118
                goto found;
119
            }
120
        }
121
        ptb1 = &tb->phys_hash_next;
122
    }
123
 not_found:
124
   /* if no translated code available, then translate it now */
125
    tb = tb_gen_code(env, pc, cs_base, flags, 0);
126

    
127
 found:
128
    /* Move the last found TB to the head of the list */
129
    if (likely(*ptb1)) {
130
        *ptb1 = tb->phys_hash_next;
131
        tb->phys_hash_next = tb_phys_hash[h];
132
        tb_phys_hash[h] = tb;
133
    }
134
    /* we add the TB in the virtual pc hash table */
135
    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
136
    return tb;
137
}
138

    
139
static inline TranslationBlock *tb_find_fast(CPUArchState *env)
140
{
141
    TranslationBlock *tb;
142
    target_ulong cs_base, pc;
143
    int flags;
144

    
145
    /* we record a subset of the CPU state. It will
146
       always be the same before a given translated block
147
       is executed. */
148
    cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
149
    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
150
    if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
151
                 tb->flags != flags)) {
152
        tb = tb_find_slow(env, pc, cs_base, flags);
153
    }
154
    return tb;
155
}
156

    
157
static CPUDebugExcpHandler *debug_excp_handler;
158

    
159
void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
160
{
161
    debug_excp_handler = handler;
162
}
163

    
164
static void cpu_handle_debug_exception(CPUArchState *env)
165
{
166
    CPUWatchpoint *wp;
167

    
168
    if (!env->watchpoint_hit) {
169
        QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
170
            wp->flags &= ~BP_WATCHPOINT_HIT;
171
        }
172
    }
173
    if (debug_excp_handler) {
174
        debug_excp_handler(env);
175
    }
176
}
177

    
178
/* main execution loop */
179

    
180
volatile sig_atomic_t exit_request;
181

    
182
int cpu_exec(CPUArchState *env)
183
{
184
#ifdef TARGET_PPC
185
    CPUState *cpu = ENV_GET_CPU(env);
186
#endif
187
    int ret, interrupt_request;
188
    TranslationBlock *tb;
189
    uint8_t *tc_ptr;
190
    tcg_target_ulong next_tb;
191

    
192
    if (env->halted) {
193
        if (!cpu_has_work(env)) {
194
            return EXCP_HALTED;
195
        }
196

    
197
        env->halted = 0;
198
    }
199

    
200
    cpu_single_env = env;
201

    
202
    if (unlikely(exit_request)) {
203
        env->exit_request = 1;
204
    }
205

    
206
#if defined(TARGET_I386)
207
    /* put eflags in CPU temporary format */
208
    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
209
    DF = 1 - (2 * ((env->eflags >> 10) & 1));
210
    CC_OP = CC_OP_EFLAGS;
211
    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
212
#elif defined(TARGET_SPARC)
213
#elif defined(TARGET_M68K)
214
    env->cc_op = CC_OP_FLAGS;
215
    env->cc_dest = env->sr & 0xf;
216
    env->cc_x = (env->sr >> 4) & 1;
217
#elif defined(TARGET_ALPHA)
218
#elif defined(TARGET_ARM)
219
#elif defined(TARGET_UNICORE32)
220
#elif defined(TARGET_PPC)
221
    env->reserve_addr = -1;
222
#elif defined(TARGET_LM32)
223
#elif defined(TARGET_MICROBLAZE)
224
#elif defined(TARGET_MIPS)
225
#elif defined(TARGET_OPENRISC)
226
#elif defined(TARGET_SH4)
227
#elif defined(TARGET_CRIS)
228
#elif defined(TARGET_S390X)
229
#elif defined(TARGET_XTENSA)
230
    /* XXXXX */
231
#else
232
#error unsupported target CPU
233
#endif
234
    env->exception_index = -1;
235

    
236
    /* prepare setjmp context for exception handling */
237
    for(;;) {
238
        if (setjmp(env->jmp_env) == 0) {
239
            /* if an exception is pending, we execute it here */
240
            if (env->exception_index >= 0) {
241
                if (env->exception_index >= EXCP_INTERRUPT) {
242
                    /* exit request from the cpu execution loop */
243
                    ret = env->exception_index;
244
                    if (ret == EXCP_DEBUG) {
245
                        cpu_handle_debug_exception(env);
246
                    }
247
                    break;
248
                } else {
249
#if defined(CONFIG_USER_ONLY)
250
                    /* if user mode only, we simulate a fake exception
251
                       which will be handled outside the cpu execution
252
                       loop */
253
#if defined(TARGET_I386)
254
                    do_interrupt(env);
255
#endif
256
                    ret = env->exception_index;
257
                    break;
258
#else
259
                    do_interrupt(env);
260
                    env->exception_index = -1;
261
#endif
262
                }
263
            }
264

    
265
            next_tb = 0; /* force lookup of first TB */
266
            for(;;) {
267
                interrupt_request = env->interrupt_request;
268
                if (unlikely(interrupt_request)) {
269
                    if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
270
                        /* Mask out external interrupts for this step. */
271
                        interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
272
                    }
273
                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
274
                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
275
                        env->exception_index = EXCP_DEBUG;
276
                        cpu_loop_exit(env);
277
                    }
278
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
279
    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
280
    defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
281
                    if (interrupt_request & CPU_INTERRUPT_HALT) {
282
                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
283
                        env->halted = 1;
284
                        env->exception_index = EXCP_HLT;
285
                        cpu_loop_exit(env);
286
                    }
287
#endif
288
#if defined(TARGET_I386)
289
#if !defined(CONFIG_USER_ONLY)
290
                    if (interrupt_request & CPU_INTERRUPT_POLL) {
291
                        env->interrupt_request &= ~CPU_INTERRUPT_POLL;
292
                        apic_poll_irq(env->apic_state);
293
                    }
294
#endif
295
                    if (interrupt_request & CPU_INTERRUPT_INIT) {
296
                            cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
297
                                                          0);
298
                            do_cpu_init(x86_env_get_cpu(env));
299
                            env->exception_index = EXCP_HALTED;
300
                            cpu_loop_exit(env);
301
                    } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
302
                            do_cpu_sipi(x86_env_get_cpu(env));
303
                    } else if (env->hflags2 & HF2_GIF_MASK) {
304
                        if ((interrupt_request & CPU_INTERRUPT_SMI) &&
305
                            !(env->hflags & HF_SMM_MASK)) {
306
                            cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
307
                                                          0);
308
                            env->interrupt_request &= ~CPU_INTERRUPT_SMI;
309
                            do_smm_enter(env);
310
                            next_tb = 0;
311
                        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
312
                                   !(env->hflags2 & HF2_NMI_MASK)) {
313
                            env->interrupt_request &= ~CPU_INTERRUPT_NMI;
314
                            env->hflags2 |= HF2_NMI_MASK;
315
                            do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
316
                            next_tb = 0;
317
                        } else if (interrupt_request & CPU_INTERRUPT_MCE) {
318
                            env->interrupt_request &= ~CPU_INTERRUPT_MCE;
319
                            do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
320
                            next_tb = 0;
321
                        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
322
                                   (((env->hflags2 & HF2_VINTR_MASK) && 
323
                                     (env->hflags2 & HF2_HIF_MASK)) ||
324
                                    (!(env->hflags2 & HF2_VINTR_MASK) && 
325
                                     (env->eflags & IF_MASK && 
326
                                      !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
327
                            int intno;
328
                            cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
329
                                                          0);
330
                            env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
331
                            intno = cpu_get_pic_interrupt(env);
332
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
333
                            do_interrupt_x86_hardirq(env, intno, 1);
334
                            /* ensure that no TB jump will be modified as
335
                               the program flow was changed */
336
                            next_tb = 0;
337
#if !defined(CONFIG_USER_ONLY)
338
                        } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
339
                                   (env->eflags & IF_MASK) && 
340
                                   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
341
                            int intno;
342
                            /* FIXME: this should respect TPR */
343
                            cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
344
                                                          0);
345
                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
346
                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
347
                            do_interrupt_x86_hardirq(env, intno, 1);
348
                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
349
                            next_tb = 0;
350
#endif
351
                        }
352
                    }
353
#elif defined(TARGET_PPC)
354
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
355
                        cpu_reset(cpu);
356
                    }
357
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
358
                        ppc_hw_interrupt(env);
359
                        if (env->pending_interrupts == 0)
360
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
361
                        next_tb = 0;
362
                    }
363
#elif defined(TARGET_LM32)
364
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
365
                        && (env->ie & IE_IE)) {
366
                        env->exception_index = EXCP_IRQ;
367
                        do_interrupt(env);
368
                        next_tb = 0;
369
                    }
370
#elif defined(TARGET_MICROBLAZE)
371
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
372
                        && (env->sregs[SR_MSR] & MSR_IE)
373
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
374
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
375
                        env->exception_index = EXCP_IRQ;
376
                        do_interrupt(env);
377
                        next_tb = 0;
378
                    }
379
#elif defined(TARGET_MIPS)
380
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
381
                        cpu_mips_hw_interrupts_pending(env)) {
382
                        /* Raise it */
383
                        env->exception_index = EXCP_EXT_INTERRUPT;
384
                        env->error_code = 0;
385
                        do_interrupt(env);
386
                        next_tb = 0;
387
                    }
388
#elif defined(TARGET_OPENRISC)
389
                    {
390
                        int idx = -1;
391
                        if ((interrupt_request & CPU_INTERRUPT_HARD)
392
                            && (env->sr & SR_IEE)) {
393
                            idx = EXCP_INT;
394
                        }
395
                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
396
                            && (env->sr & SR_TEE)) {
397
                            idx = EXCP_TICK;
398
                        }
399
                        if (idx >= 0) {
400
                            env->exception_index = idx;
401
                            do_interrupt(env);
402
                            next_tb = 0;
403
                        }
404
                    }
405
#elif defined(TARGET_SPARC)
406
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
407
                        if (cpu_interrupts_enabled(env) &&
408
                            env->interrupt_index > 0) {
409
                            int pil = env->interrupt_index & 0xf;
410
                            int type = env->interrupt_index & 0xf0;
411

    
412
                            if (((type == TT_EXTINT) &&
413
                                  cpu_pil_allowed(env, pil)) ||
414
                                  type != TT_EXTINT) {
415
                                env->exception_index = env->interrupt_index;
416
                                do_interrupt(env);
417
                                next_tb = 0;
418
                            }
419
                        }
420
                    }
421
#elif defined(TARGET_ARM)
422
                    if (interrupt_request & CPU_INTERRUPT_FIQ
423
                        && !(env->uncached_cpsr & CPSR_F)) {
424
                        env->exception_index = EXCP_FIQ;
425
                        do_interrupt(env);
426
                        next_tb = 0;
427
                    }
428
                    /* ARMv7-M interrupt return works by loading a magic value
429
                       into the PC.  On real hardware the load causes the
430
                       return to occur.  The qemu implementation performs the
431
                       jump normally, then does the exception return when the
432
                       CPU tries to execute code at the magic address.
433
                       This will cause the magic PC value to be pushed to
434
                       the stack if an interrupt occurred at the wrong time.
435
                       We avoid this by disabling interrupts when
436
                       pc contains a magic address.  */
437
                    if (interrupt_request & CPU_INTERRUPT_HARD
438
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
439
                            || !(env->uncached_cpsr & CPSR_I))) {
440
                        env->exception_index = EXCP_IRQ;
441
                        do_interrupt(env);
442
                        next_tb = 0;
443
                    }
444
#elif defined(TARGET_UNICORE32)
445
                    if (interrupt_request & CPU_INTERRUPT_HARD
446
                        && !(env->uncached_asr & ASR_I)) {
447
                        env->exception_index = UC32_EXCP_INTR;
448
                        do_interrupt(env);
449
                        next_tb = 0;
450
                    }
451
#elif defined(TARGET_SH4)
452
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
453
                        do_interrupt(env);
454
                        next_tb = 0;
455
                    }
456
#elif defined(TARGET_ALPHA)
457
                    {
458
                        int idx = -1;
459
                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
460
                        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
461
                        case 0 ... 3:
462
                            if (interrupt_request & CPU_INTERRUPT_HARD) {
463
                                idx = EXCP_DEV_INTERRUPT;
464
                            }
465
                            /* FALLTHRU */
466
                        case 4:
467
                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
468
                                idx = EXCP_CLK_INTERRUPT;
469
                            }
470
                            /* FALLTHRU */
471
                        case 5:
472
                            if (interrupt_request & CPU_INTERRUPT_SMP) {
473
                                idx = EXCP_SMP_INTERRUPT;
474
                            }
475
                            /* FALLTHRU */
476
                        case 6:
477
                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
478
                                idx = EXCP_MCHK;
479
                            }
480
                        }
481
                        if (idx >= 0) {
482
                            env->exception_index = idx;
483
                            env->error_code = 0;
484
                            do_interrupt(env);
485
                            next_tb = 0;
486
                        }
487
                    }
488
#elif defined(TARGET_CRIS)
489
                    if (interrupt_request & CPU_INTERRUPT_HARD
490
                        && (env->pregs[PR_CCS] & I_FLAG)
491
                        && !env->locked_irq) {
492
                        env->exception_index = EXCP_IRQ;
493
                        do_interrupt(env);
494
                        next_tb = 0;
495
                    }
496
                    if (interrupt_request & CPU_INTERRUPT_NMI) {
497
                        unsigned int m_flag_archval;
498
                        if (env->pregs[PR_VR] < 32) {
499
                            m_flag_archval = M_FLAG_V10;
500
                        } else {
501
                            m_flag_archval = M_FLAG_V32;
502
                        }
503
                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
504
                            env->exception_index = EXCP_NMI;
505
                            do_interrupt(env);
506
                            next_tb = 0;
507
                        }
508
                    }
509
#elif defined(TARGET_M68K)
510
                    if (interrupt_request & CPU_INTERRUPT_HARD
511
                        && ((env->sr & SR_I) >> SR_I_SHIFT)
512
                            < env->pending_level) {
513
                        /* Real hardware gets the interrupt vector via an
514
                           IACK cycle at this point.  Current emulated
515
                           hardware doesn't rely on this, so we
516
                           provide/save the vector when the interrupt is
517
                           first signalled.  */
518
                        env->exception_index = env->pending_vector;
519
                        do_interrupt_m68k_hardirq(env);
520
                        next_tb = 0;
521
                    }
522
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
523
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
524
                        (env->psw.mask & PSW_MASK_EXT)) {
525
                        do_interrupt(env);
526
                        next_tb = 0;
527
                    }
528
#elif defined(TARGET_XTENSA)
529
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
530
                        env->exception_index = EXC_IRQ;
531
                        do_interrupt(env);
532
                        next_tb = 0;
533
                    }
534
#endif
535
                   /* Don't use the cached interrupt_request value,
536
                      do_interrupt may have updated the EXITTB flag. */
537
                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
538
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
539
                        /* ensure that no TB jump will be modified as
540
                           the program flow was changed */
541
                        next_tb = 0;
542
                    }
543
                }
544
                if (unlikely(env->exit_request)) {
545
                    env->exit_request = 0;
546
                    env->exception_index = EXCP_INTERRUPT;
547
                    cpu_loop_exit(env);
548
                }
549
#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
550
                if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
551
                    /* restore flags in standard format */
552
#if defined(TARGET_I386)
553
                    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
554
                        | (DF & DF_MASK);
555
                    log_cpu_state(env, X86_DUMP_CCOP);
556
                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
557
#elif defined(TARGET_M68K)
558
                    cpu_m68k_flush_flags(env, env->cc_op);
559
                    env->cc_op = CC_OP_FLAGS;
560
                    env->sr = (env->sr & 0xffe0)
561
                              | env->cc_dest | (env->cc_x << 4);
562
                    log_cpu_state(env, 0);
563
#else
564
                    log_cpu_state(env, 0);
565
#endif
566
                }
567
#endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
568
                spin_lock(&tb_lock);
569
                tb = tb_find_fast(env);
570
                /* Note: we do it here to avoid a gcc bug on Mac OS X when
571
                   doing it in tb_find_slow */
572
                if (tb_invalidated_flag) {
573
                    /* as some TB could have been invalidated because
574
                       of memory exceptions while generating the code, we
575
                       must recompute the hash index here */
576
                    next_tb = 0;
577
                    tb_invalidated_flag = 0;
578
                }
579
#ifdef CONFIG_DEBUG_EXEC
580
                qemu_log_mask(CPU_LOG_EXEC, "Trace %p [" TARGET_FMT_lx "] %s\n",
581
                             tb->tc_ptr, tb->pc,
582
                             lookup_symbol(tb->pc));
583
#endif
584
                /* see if we can patch the calling TB. When the TB
585
                   spans two pages, we cannot safely do a direct
586
                   jump. */
587
                if (next_tb != 0 && tb->page_addr[1] == -1) {
588
                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
589
                }
590
                spin_unlock(&tb_lock);
591

    
592
                /* cpu_interrupt might be called while translating the
593
                   TB, but before it is linked into a potentially
594
                   infinite loop and becomes env->current_tb. Avoid
595
                   starting execution if there is a pending interrupt. */
596
                env->current_tb = tb;
597
                barrier();
598
                if (likely(!env->exit_request)) {
599
                    tc_ptr = tb->tc_ptr;
600
                    /* execute the generated code */
601
                    next_tb = tcg_qemu_tb_exec(env, tc_ptr);
602
                    if ((next_tb & 3) == 2) {
603
                        /* Instruction counter expired.  */
604
                        int insns_left;
605
                        tb = (TranslationBlock *)(next_tb & ~3);
606
                        /* Restore PC.  */
607
                        cpu_pc_from_tb(env, tb);
608
                        insns_left = env->icount_decr.u32;
609
                        if (env->icount_extra && insns_left >= 0) {
610
                            /* Refill decrementer and continue execution.  */
611
                            env->icount_extra += insns_left;
612
                            if (env->icount_extra > 0xffff) {
613
                                insns_left = 0xffff;
614
                            } else {
615
                                insns_left = env->icount_extra;
616
                            }
617
                            env->icount_extra -= insns_left;
618
                            env->icount_decr.u16.low = insns_left;
619
                        } else {
620
                            if (insns_left > 0) {
621
                                /* Execute remaining instructions.  */
622
                                cpu_exec_nocache(env, insns_left, tb);
623
                            }
624
                            env->exception_index = EXCP_INTERRUPT;
625
                            next_tb = 0;
626
                            cpu_loop_exit(env);
627
                        }
628
                    }
629
                }
630
                env->current_tb = NULL;
631
                /* reset soft MMU for next block (it can currently
632
                   only be set by a memory fault) */
633
            } /* for(;;) */
634
        } else {
635
            /* Reload env after longjmp - the compiler may have smashed all
636
             * local variables as longjmp is marked 'noreturn'. */
637
            env = cpu_single_env;
638
        }
639
    } /* for(;;) */
640

    
641

    
642
#if defined(TARGET_I386)
643
    /* restore flags in standard format */
644
    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
645
        | (DF & DF_MASK);
646
#elif defined(TARGET_ARM)
647
    /* XXX: Save/restore host fpu exception state?.  */
648
#elif defined(TARGET_UNICORE32)
649
#elif defined(TARGET_SPARC)
650
#elif defined(TARGET_PPC)
651
#elif defined(TARGET_LM32)
652
#elif defined(TARGET_M68K)
653
    cpu_m68k_flush_flags(env, env->cc_op);
654
    env->cc_op = CC_OP_FLAGS;
655
    env->sr = (env->sr & 0xffe0)
656
              | env->cc_dest | (env->cc_x << 4);
657
#elif defined(TARGET_MICROBLAZE)
658
#elif defined(TARGET_MIPS)
659
#elif defined(TARGET_OPENRISC)
660
#elif defined(TARGET_SH4)
661
#elif defined(TARGET_ALPHA)
662
#elif defined(TARGET_CRIS)
663
#elif defined(TARGET_S390X)
664
#elif defined(TARGET_XTENSA)
665
    /* XXXXX */
666
#else
667
#error unsupported target CPU
668
#endif
669

    
670
    /* fail safe : never use cpu_single_env outside cpu_exec() */
671
    cpu_single_env = NULL;
672
    return ret;
673
}