]> Git Repo - qemu.git/blob - cpu-exec.c
pc: Split pc_init_pci_1_0() off pc_init_pci_1_2()
[qemu.git] / cpu-exec.c
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/disas.h"
22 #include "tcg.h"
23 #include "qemu/atomic.h"
24 #include "sysemu/qtest.h"
25
26 bool qemu_cpu_has_work(CPUState *cpu)
27 {
28     return cpu_has_work(cpu);
29 }
30
31 void cpu_loop_exit(CPUArchState *env)
32 {
33     CPUState *cpu = ENV_GET_CPU(env);
34
35     cpu->current_tb = NULL;
36     siglongjmp(env->jmp_env, 1);
37 }
38
39 /* exit the current TB from a signal handler. The host registers are
40    restored in a state compatible with the CPU emulator
41  */
42 #if defined(CONFIG_SOFTMMU)
43 void cpu_resume_from_signal(CPUArchState *env, void *puc)
44 {
45     /* XXX: restore cpu registers saved in host registers */
46
47     env->exception_index = -1;
48     siglongjmp(env->jmp_env, 1);
49 }
50 #endif
51
52 /* Execute a TB, and fix up the CPU state afterwards if necessary */
53 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
54 {
55     CPUArchState *env = cpu->env_ptr;
56     tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr);
57     if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
58         /* We didn't start executing this TB (eg because the instruction
59          * counter hit zero); we must restore the guest PC to the address
60          * of the start of the TB.
61          */
62         TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
63         cpu_pc_from_tb(env, tb);
64     }
65     if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
66         /* We were asked to stop executing TBs (probably a pending
67          * interrupt. We've now stopped, so clear the flag.
68          */
69         cpu->tcg_exit_req = 0;
70     }
71     return next_tb;
72 }
73
74 /* Execute the code without caching the generated code. An interpreter
75    could be used if available. */
76 static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
77                              TranslationBlock *orig_tb)
78 {
79     CPUState *cpu = ENV_GET_CPU(env);
80     TranslationBlock *tb;
81
82     /* Should never happen.
83        We only end up here when an existing TB is too long.  */
84     if (max_cycles > CF_COUNT_MASK)
85         max_cycles = CF_COUNT_MASK;
86
87     tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
88                      max_cycles);
89     cpu->current_tb = tb;
90     /* execute the generated code */
91     cpu_tb_exec(cpu, tb->tc_ptr);
92     cpu->current_tb = NULL;
93     tb_phys_invalidate(tb, -1);
94     tb_free(tb);
95 }
96
97 static TranslationBlock *tb_find_slow(CPUArchState *env,
98                                       target_ulong pc,
99                                       target_ulong cs_base,
100                                       uint64_t flags)
101 {
102     TranslationBlock *tb, **ptb1;
103     unsigned int h;
104     tb_page_addr_t phys_pc, phys_page1;
105     target_ulong virt_page2;
106
107     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
108
109     /* find translated block using physical mappings */
110     phys_pc = get_page_addr_code(env, pc);
111     phys_page1 = phys_pc & TARGET_PAGE_MASK;
112     h = tb_phys_hash_func(phys_pc);
113     ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
114     for(;;) {
115         tb = *ptb1;
116         if (!tb)
117             goto not_found;
118         if (tb->pc == pc &&
119             tb->page_addr[0] == phys_page1 &&
120             tb->cs_base == cs_base &&
121             tb->flags == flags) {
122             /* check next page if needed */
123             if (tb->page_addr[1] != -1) {
124                 tb_page_addr_t phys_page2;
125
126                 virt_page2 = (pc & TARGET_PAGE_MASK) +
127                     TARGET_PAGE_SIZE;
128                 phys_page2 = get_page_addr_code(env, virt_page2);
129                 if (tb->page_addr[1] == phys_page2)
130                     goto found;
131             } else {
132                 goto found;
133             }
134         }
135         ptb1 = &tb->phys_hash_next;
136     }
137  not_found:
138    /* if no translated code available, then translate it now */
139     tb = tb_gen_code(env, pc, cs_base, flags, 0);
140
141  found:
142     /* Move the last found TB to the head of the list */
143     if (likely(*ptb1)) {
144         *ptb1 = tb->phys_hash_next;
145         tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
146         tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
147     }
148     /* we add the TB in the virtual pc hash table */
149     env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
150     return tb;
151 }
152
153 static inline TranslationBlock *tb_find_fast(CPUArchState *env)
154 {
155     TranslationBlock *tb;
156     target_ulong cs_base, pc;
157     int flags;
158
159     /* we record a subset of the CPU state. It will
160        always be the same before a given translated block
161        is executed. */
162     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
163     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
164     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
165                  tb->flags != flags)) {
166         tb = tb_find_slow(env, pc, cs_base, flags);
167     }
168     return tb;
169 }
170
171 static CPUDebugExcpHandler *debug_excp_handler;
172
173 void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
174 {
175     debug_excp_handler = handler;
176 }
177
178 static void cpu_handle_debug_exception(CPUArchState *env)
179 {
180     CPUWatchpoint *wp;
181
182     if (!env->watchpoint_hit) {
183         QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
184             wp->flags &= ~BP_WATCHPOINT_HIT;
185         }
186     }
187     if (debug_excp_handler) {
188         debug_excp_handler(env);
189     }
190 }
191
192 /* main execution loop */
193
194 volatile sig_atomic_t exit_request;
195
196 int cpu_exec(CPUArchState *env)
197 {
198     CPUState *cpu = ENV_GET_CPU(env);
199 #if !(defined(CONFIG_USER_ONLY) && \
200       (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
201     CPUClass *cc = CPU_GET_CLASS(cpu);
202 #endif
203     int ret, interrupt_request;
204     TranslationBlock *tb;
205     uint8_t *tc_ptr;
206     tcg_target_ulong next_tb;
207
208     if (cpu->halted) {
209         if (!cpu_has_work(cpu)) {
210             return EXCP_HALTED;
211         }
212
213         cpu->halted = 0;
214     }
215
216     cpu_single_env = env;
217
218     /* As long as cpu_single_env is null, up to the assignment just above,
219      * requests by other threads to exit the execution loop are expected to
220      * be issued using the exit_request global. We must make sure that our
221      * evaluation of the global value is performed past the cpu_single_env
222      * value transition point, which requires a memory barrier as well as
223      * an instruction scheduling constraint on modern architectures.  */
224     smp_mb();
225
226     if (unlikely(exit_request)) {
227         cpu->exit_request = 1;
228     }
229
230 #if defined(TARGET_I386)
231     /* put eflags in CPU temporary format */
232     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
233     DF = 1 - (2 * ((env->eflags >> 10) & 1));
234     CC_OP = CC_OP_EFLAGS;
235     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
236 #elif defined(TARGET_SPARC)
237 #elif defined(TARGET_M68K)
238     env->cc_op = CC_OP_FLAGS;
239     env->cc_dest = env->sr & 0xf;
240     env->cc_x = (env->sr >> 4) & 1;
241 #elif defined(TARGET_ALPHA)
242 #elif defined(TARGET_ARM)
243 #elif defined(TARGET_UNICORE32)
244 #elif defined(TARGET_PPC)
245     env->reserve_addr = -1;
246 #elif defined(TARGET_LM32)
247 #elif defined(TARGET_MICROBLAZE)
248 #elif defined(TARGET_MIPS)
249 #elif defined(TARGET_MOXIE)
250 #elif defined(TARGET_OPENRISC)
251 #elif defined(TARGET_SH4)
252 #elif defined(TARGET_CRIS)
253 #elif defined(TARGET_S390X)
254 #elif defined(TARGET_XTENSA)
255     /* XXXXX */
256 #else
257 #error unsupported target CPU
258 #endif
259     env->exception_index = -1;
260
261     /* prepare setjmp context for exception handling */
262     for(;;) {
263         if (sigsetjmp(env->jmp_env, 0) == 0) {
264             /* if an exception is pending, we execute it here */
265             if (env->exception_index >= 0) {
266                 if (env->exception_index >= EXCP_INTERRUPT) {
267                     /* exit request from the cpu execution loop */
268                     ret = env->exception_index;
269                     if (ret == EXCP_DEBUG) {
270                         cpu_handle_debug_exception(env);
271                     }
272                     break;
273                 } else {
274 #if defined(CONFIG_USER_ONLY)
275                     /* if user mode only, we simulate a fake exception
276                        which will be handled outside the cpu execution
277                        loop */
278 #if defined(TARGET_I386)
279                     cc->do_interrupt(cpu);
280 #endif
281                     ret = env->exception_index;
282                     break;
283 #else
284                     cc->do_interrupt(cpu);
285                     env->exception_index = -1;
286 #endif
287                 }
288             }
289
290             next_tb = 0; /* force lookup of first TB */
291             for(;;) {
292                 interrupt_request = cpu->interrupt_request;
293                 if (unlikely(interrupt_request)) {
294                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
295                         /* Mask out external interrupts for this step. */
296                         interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
297                     }
298                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
299                         cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
300                         env->exception_index = EXCP_DEBUG;
301                         cpu_loop_exit(env);
302                     }
303 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
304     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
305     defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
306                     if (interrupt_request & CPU_INTERRUPT_HALT) {
307                         cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
308                         cpu->halted = 1;
309                         env->exception_index = EXCP_HLT;
310                         cpu_loop_exit(env);
311                     }
312 #endif
313 #if defined(TARGET_I386)
314 #if !defined(CONFIG_USER_ONLY)
315                     if (interrupt_request & CPU_INTERRUPT_POLL) {
316                         cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
317                         apic_poll_irq(env->apic_state);
318                     }
319 #endif
320                     if (interrupt_request & CPU_INTERRUPT_INIT) {
321                             cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
322                                                           0);
323                             do_cpu_init(x86_env_get_cpu(env));
324                             env->exception_index = EXCP_HALTED;
325                             cpu_loop_exit(env);
326                     } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
327                             do_cpu_sipi(x86_env_get_cpu(env));
328                     } else if (env->hflags2 & HF2_GIF_MASK) {
329                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
330                             !(env->hflags & HF_SMM_MASK)) {
331                             cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
332                                                           0);
333                             cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
334                             do_smm_enter(env);
335                             next_tb = 0;
336                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
337                                    !(env->hflags2 & HF2_NMI_MASK)) {
338                             cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
339                             env->hflags2 |= HF2_NMI_MASK;
340                             do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
341                             next_tb = 0;
342                         } else if (interrupt_request & CPU_INTERRUPT_MCE) {
343                             cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
344                             do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
345                             next_tb = 0;
346                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
347                                    (((env->hflags2 & HF2_VINTR_MASK) && 
348                                      (env->hflags2 & HF2_HIF_MASK)) ||
349                                     (!(env->hflags2 & HF2_VINTR_MASK) && 
350                                      (env->eflags & IF_MASK && 
351                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
352                             int intno;
353                             cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
354                                                           0);
355                             cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
356                                                         CPU_INTERRUPT_VIRQ);
357                             intno = cpu_get_pic_interrupt(env);
358                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
359                             do_interrupt_x86_hardirq(env, intno, 1);
360                             /* ensure that no TB jump will be modified as
361                                the program flow was changed */
362                             next_tb = 0;
363 #if !defined(CONFIG_USER_ONLY)
364                         } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
365                                    (env->eflags & IF_MASK) && 
366                                    !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
367                             int intno;
368                             /* FIXME: this should respect TPR */
369                             cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
370                                                           0);
371                             intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
372                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
373                             do_interrupt_x86_hardirq(env, intno, 1);
374                             cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
375                             next_tb = 0;
376 #endif
377                         }
378                     }
379 #elif defined(TARGET_PPC)
380                     if ((interrupt_request & CPU_INTERRUPT_RESET)) {
381                         cpu_reset(cpu);
382                     }
383                     if (interrupt_request & CPU_INTERRUPT_HARD) {
384                         ppc_hw_interrupt(env);
385                         if (env->pending_interrupts == 0) {
386                             cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
387                         }
388                         next_tb = 0;
389                     }
390 #elif defined(TARGET_LM32)
391                     if ((interrupt_request & CPU_INTERRUPT_HARD)
392                         && (env->ie & IE_IE)) {
393                         env->exception_index = EXCP_IRQ;
394                         cc->do_interrupt(cpu);
395                         next_tb = 0;
396                     }
397 #elif defined(TARGET_MICROBLAZE)
398                     if ((interrupt_request & CPU_INTERRUPT_HARD)
399                         && (env->sregs[SR_MSR] & MSR_IE)
400                         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
401                         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
402                         env->exception_index = EXCP_IRQ;
403                         cc->do_interrupt(cpu);
404                         next_tb = 0;
405                     }
406 #elif defined(TARGET_MIPS)
407                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
408                         cpu_mips_hw_interrupts_pending(env)) {
409                         /* Raise it */
410                         env->exception_index = EXCP_EXT_INTERRUPT;
411                         env->error_code = 0;
412                         cc->do_interrupt(cpu);
413                         next_tb = 0;
414                     }
415 #elif defined(TARGET_OPENRISC)
416                     {
417                         int idx = -1;
418                         if ((interrupt_request & CPU_INTERRUPT_HARD)
419                             && (env->sr & SR_IEE)) {
420                             idx = EXCP_INT;
421                         }
422                         if ((interrupt_request & CPU_INTERRUPT_TIMER)
423                             && (env->sr & SR_TEE)) {
424                             idx = EXCP_TICK;
425                         }
426                         if (idx >= 0) {
427                             env->exception_index = idx;
428                             cc->do_interrupt(cpu);
429                             next_tb = 0;
430                         }
431                     }
432 #elif defined(TARGET_SPARC)
433                     if (interrupt_request & CPU_INTERRUPT_HARD) {
434                         if (cpu_interrupts_enabled(env) &&
435                             env->interrupt_index > 0) {
436                             int pil = env->interrupt_index & 0xf;
437                             int type = env->interrupt_index & 0xf0;
438
439                             if (((type == TT_EXTINT) &&
440                                   cpu_pil_allowed(env, pil)) ||
441                                   type != TT_EXTINT) {
442                                 env->exception_index = env->interrupt_index;
443                                 cc->do_interrupt(cpu);
444                                 next_tb = 0;
445                             }
446                         }
447                     }
448 #elif defined(TARGET_ARM)
449                     if (interrupt_request & CPU_INTERRUPT_FIQ
450                         && !(env->uncached_cpsr & CPSR_F)) {
451                         env->exception_index = EXCP_FIQ;
452                         cc->do_interrupt(cpu);
453                         next_tb = 0;
454                     }
455                     /* ARMv7-M interrupt return works by loading a magic value
456                        into the PC.  On real hardware the load causes the
457                        return to occur.  The qemu implementation performs the
458                        jump normally, then does the exception return when the
459                        CPU tries to execute code at the magic address.
460                        This will cause the magic PC value to be pushed to
461                        the stack if an interrupt occurred at the wrong time.
462                        We avoid this by disabling interrupts when
463                        pc contains a magic address.  */
464                     if (interrupt_request & CPU_INTERRUPT_HARD
465                         && ((IS_M(env) && env->regs[15] < 0xfffffff0)
466                             || !(env->uncached_cpsr & CPSR_I))) {
467                         env->exception_index = EXCP_IRQ;
468                         cc->do_interrupt(cpu);
469                         next_tb = 0;
470                     }
471 #elif defined(TARGET_UNICORE32)
472                     if (interrupt_request & CPU_INTERRUPT_HARD
473                         && !(env->uncached_asr & ASR_I)) {
474                         env->exception_index = UC32_EXCP_INTR;
475                         cc->do_interrupt(cpu);
476                         next_tb = 0;
477                     }
478 #elif defined(TARGET_SH4)
479                     if (interrupt_request & CPU_INTERRUPT_HARD) {
480                         cc->do_interrupt(cpu);
481                         next_tb = 0;
482                     }
483 #elif defined(TARGET_ALPHA)
484                     {
485                         int idx = -1;
486                         /* ??? This hard-codes the OSF/1 interrupt levels.  */
487                         switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
488                         case 0 ... 3:
489                             if (interrupt_request & CPU_INTERRUPT_HARD) {
490                                 idx = EXCP_DEV_INTERRUPT;
491                             }
492                             /* FALLTHRU */
493                         case 4:
494                             if (interrupt_request & CPU_INTERRUPT_TIMER) {
495                                 idx = EXCP_CLK_INTERRUPT;
496                             }
497                             /* FALLTHRU */
498                         case 5:
499                             if (interrupt_request & CPU_INTERRUPT_SMP) {
500                                 idx = EXCP_SMP_INTERRUPT;
501                             }
502                             /* FALLTHRU */
503                         case 6:
504                             if (interrupt_request & CPU_INTERRUPT_MCHK) {
505                                 idx = EXCP_MCHK;
506                             }
507                         }
508                         if (idx >= 0) {
509                             env->exception_index = idx;
510                             env->error_code = 0;
511                             cc->do_interrupt(cpu);
512                             next_tb = 0;
513                         }
514                     }
515 #elif defined(TARGET_CRIS)
516                     if (interrupt_request & CPU_INTERRUPT_HARD
517                         && (env->pregs[PR_CCS] & I_FLAG)
518                         && !env->locked_irq) {
519                         env->exception_index = EXCP_IRQ;
520                         cc->do_interrupt(cpu);
521                         next_tb = 0;
522                     }
523                     if (interrupt_request & CPU_INTERRUPT_NMI) {
524                         unsigned int m_flag_archval;
525                         if (env->pregs[PR_VR] < 32) {
526                             m_flag_archval = M_FLAG_V10;
527                         } else {
528                             m_flag_archval = M_FLAG_V32;
529                         }
530                         if ((env->pregs[PR_CCS] & m_flag_archval)) {
531                             env->exception_index = EXCP_NMI;
532                             cc->do_interrupt(cpu);
533                             next_tb = 0;
534                         }
535                     }
536 #elif defined(TARGET_M68K)
537                     if (interrupt_request & CPU_INTERRUPT_HARD
538                         && ((env->sr & SR_I) >> SR_I_SHIFT)
539                             < env->pending_level) {
540                         /* Real hardware gets the interrupt vector via an
541                            IACK cycle at this point.  Current emulated
542                            hardware doesn't rely on this, so we
543                            provide/save the vector when the interrupt is
544                            first signalled.  */
545                         env->exception_index = env->pending_vector;
546                         do_interrupt_m68k_hardirq(env);
547                         next_tb = 0;
548                     }
549 #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
550                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
551                         (env->psw.mask & PSW_MASK_EXT)) {
552                         cc->do_interrupt(cpu);
553                         next_tb = 0;
554                     }
555 #elif defined(TARGET_XTENSA)
556                     if (interrupt_request & CPU_INTERRUPT_HARD) {
557                         env->exception_index = EXC_IRQ;
558                         cc->do_interrupt(cpu);
559                         next_tb = 0;
560                     }
561 #endif
562                    /* Don't use the cached interrupt_request value,
563                       do_interrupt may have updated the EXITTB flag. */
564                     if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
565                         cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
566                         /* ensure that no TB jump will be modified as
567                            the program flow was changed */
568                         next_tb = 0;
569                     }
570                 }
571                 if (unlikely(cpu->exit_request)) {
572                     cpu->exit_request = 0;
573                     env->exception_index = EXCP_INTERRUPT;
574                     cpu_loop_exit(env);
575                 }
576 #if defined(DEBUG_DISAS)
577                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
578                     /* restore flags in standard format */
579 #if defined(TARGET_I386)
580                     log_cpu_state(env, CPU_DUMP_CCOP);
581 #elif defined(TARGET_M68K)
582                     cpu_m68k_flush_flags(env, env->cc_op);
583                     env->cc_op = CC_OP_FLAGS;
584                     env->sr = (env->sr & 0xffe0)
585                               | env->cc_dest | (env->cc_x << 4);
586                     log_cpu_state(env, 0);
587 #else
588                     log_cpu_state(env, 0);
589 #endif
590                 }
591 #endif /* DEBUG_DISAS */
592                 spin_lock(&tcg_ctx.tb_ctx.tb_lock);
593                 tb = tb_find_fast(env);
594                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
595                    doing it in tb_find_slow */
596                 if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
597                     /* as some TB could have been invalidated because
598                        of memory exceptions while generating the code, we
599                        must recompute the hash index here */
600                     next_tb = 0;
601                     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
602                 }
603                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
604                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
605                              tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
606                 }
607                 /* see if we can patch the calling TB. When the TB
608                    spans two pages, we cannot safely do a direct
609                    jump. */
610                 if (next_tb != 0 && tb->page_addr[1] == -1) {
611                     tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
612                                 next_tb & TB_EXIT_MASK, tb);
613                 }
614                 spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
615
616                 /* cpu_interrupt might be called while translating the
617                    TB, but before it is linked into a potentially
618                    infinite loop and becomes env->current_tb. Avoid
619                    starting execution if there is a pending interrupt. */
620                 cpu->current_tb = tb;
621                 barrier();
622                 if (likely(!cpu->exit_request)) {
623                     tc_ptr = tb->tc_ptr;
624                     /* execute the generated code */
625                     next_tb = cpu_tb_exec(cpu, tc_ptr);
626                     switch (next_tb & TB_EXIT_MASK) {
627                     case TB_EXIT_REQUESTED:
628                         /* Something asked us to stop executing
629                          * chained TBs; just continue round the main
630                          * loop. Whatever requested the exit will also
631                          * have set something else (eg exit_request or
632                          * interrupt_request) which we will handle
633                          * next time around the loop.
634                          */
635                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
636                         next_tb = 0;
637                         break;
638                     case TB_EXIT_ICOUNT_EXPIRED:
639                     {
640                         /* Instruction counter expired.  */
641                         int insns_left;
642                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
643                         insns_left = env->icount_decr.u32;
644                         if (env->icount_extra && insns_left >= 0) {
645                             /* Refill decrementer and continue execution.  */
646                             env->icount_extra += insns_left;
647                             if (env->icount_extra > 0xffff) {
648                                 insns_left = 0xffff;
649                             } else {
650                                 insns_left = env->icount_extra;
651                             }
652                             env->icount_extra -= insns_left;
653                             env->icount_decr.u16.low = insns_left;
654                         } else {
655                             if (insns_left > 0) {
656                                 /* Execute remaining instructions.  */
657                                 cpu_exec_nocache(env, insns_left, tb);
658                             }
659                             env->exception_index = EXCP_INTERRUPT;
660                             next_tb = 0;
661                             cpu_loop_exit(env);
662                         }
663                         break;
664                     }
665                     default:
666                         break;
667                     }
668                 }
669                 cpu->current_tb = NULL;
670                 /* reset soft MMU for next block (it can currently
671                    only be set by a memory fault) */
672             } /* for(;;) */
673         } else {
674             /* Reload env after longjmp - the compiler may have smashed all
675              * local variables as longjmp is marked 'noreturn'. */
676             env = cpu_single_env;
677         }
678     } /* for(;;) */
679
680
681 #if defined(TARGET_I386)
682     /* restore flags in standard format */
683     env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
684         | (DF & DF_MASK);
685 #elif defined(TARGET_ARM)
686     /* XXX: Save/restore host fpu exception state?.  */
687 #elif defined(TARGET_UNICORE32)
688 #elif defined(TARGET_SPARC)
689 #elif defined(TARGET_PPC)
690 #elif defined(TARGET_LM32)
691 #elif defined(TARGET_M68K)
692     cpu_m68k_flush_flags(env, env->cc_op);
693     env->cc_op = CC_OP_FLAGS;
694     env->sr = (env->sr & 0xffe0)
695               | env->cc_dest | (env->cc_x << 4);
696 #elif defined(TARGET_MICROBLAZE)
697 #elif defined(TARGET_MIPS)
698 #elif defined(TARGET_MOXIE)
699 #elif defined(TARGET_OPENRISC)
700 #elif defined(TARGET_SH4)
701 #elif defined(TARGET_ALPHA)
702 #elif defined(TARGET_CRIS)
703 #elif defined(TARGET_S390X)
704 #elif defined(TARGET_XTENSA)
705     /* XXXXX */
706 #else
707 #error unsupported target CPU
708 #endif
709
710     /* fail safe : never use cpu_single_env outside cpu_exec() */
711     cpu_single_env = NULL;
712     return ret;
713 }
This page took 0.06482 seconds and 4 git commands to generate.