Home | History | Annotate | Download | only in qemu
      1 /*
      2  *  i386 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 "exec.h"
     21 #include "disas.h"
     22 #include "tcg.h"
     23 #include "kvm.h"
     24 
     25 #if !defined(CONFIG_SOFTMMU)
     26 #undef EAX
     27 #undef ECX
     28 #undef EDX
     29 #undef EBX
     30 #undef ESP
     31 #undef EBP
     32 #undef ESI
     33 #undef EDI
     34 #undef EIP
     35 #include <signal.h>
     36 #ifdef __linux__
     37 #include <sys/ucontext.h>
     38 #endif
     39 #endif
     40 
     41 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
     42 // Work around ugly bugs in glibc that mangle global register contents
     43 #undef env
     44 #define env cpu_single_env
     45 #endif
     46 
     47 int tb_invalidated_flag;
     48 
     49 //#define CONFIG_DEBUG_EXEC
     50 //#define DEBUG_SIGNAL
     51 
     52 int qemu_cpu_has_work(CPUState *env)
     53 {
     54     return cpu_has_work(env);
     55 }
     56 
     57 void cpu_loop_exit(void)
     58 {
     59     /* NOTE: the register at this point must be saved by hand because
     60        longjmp restore them */
     61     regs_to_env();
     62     longjmp(env->jmp_env, 1);
     63 }
     64 
     65 /* exit the current TB from a signal handler. The host registers are
     66    restored in a state compatible with the CPU emulator
     67  */
     68 void cpu_resume_from_signal(CPUState *env1, void *puc)
     69 {
     70 #if !defined(CONFIG_SOFTMMU)
     71 #ifdef __linux__
     72     struct ucontext *uc = puc;
     73 #elif defined(__OpenBSD__)
     74     struct sigcontext *uc = puc;
     75 #endif
     76 #endif
     77 
     78     env = env1;
     79 
     80     /* XXX: restore cpu registers saved in host registers */
     81 
     82 #if !defined(CONFIG_SOFTMMU)
     83     if (puc) {
     84         /* XXX: use siglongjmp ? */
     85 #ifdef __linux__
     86         sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
     87 #elif defined(__OpenBSD__)
     88         sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
     89 #endif
     90     }
     91 #endif
     92     env->exception_index = -1;
     93     longjmp(env->jmp_env, 1);
     94 }
     95 
     96 /* Execute the code without caching the generated code. An interpreter
     97    could be used if available. */
     98 static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
     99 {
    100     unsigned long next_tb;
    101     TranslationBlock *tb;
    102 
    103     /* Should never happen.
    104        We only end up here when an existing TB is too long.  */
    105     if (max_cycles > CF_COUNT_MASK)
    106         max_cycles = CF_COUNT_MASK;
    107 
    108     tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
    109                      max_cycles);
    110     env->current_tb = tb;
    111     /* execute the generated code */
    112     next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
    113 
    114     if ((next_tb & 3) == 2) {
    115         /* Restore PC.  This may happen if async event occurs before
    116            the TB starts executing.  */
    117         cpu_pc_from_tb(env, tb);
    118     }
    119     tb_phys_invalidate(tb, -1);
    120     tb_free(tb);
    121 }
    122 
    123 static TranslationBlock *tb_find_slow(target_ulong pc,
    124                                       target_ulong cs_base,
    125                                       uint64_t flags)
    126 {
    127     TranslationBlock *tb, **ptb1;
    128     unsigned int h;
    129     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
    130 
    131     tb_invalidated_flag = 0;
    132 
    133     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
    134 
    135     /* find translated block using physical mappings */
    136     phys_pc = get_phys_addr_code(env, pc);
    137     phys_page1 = phys_pc & TARGET_PAGE_MASK;
    138     phys_page2 = -1;
    139     h = tb_phys_hash_func(phys_pc);
    140     ptb1 = &tb_phys_hash[h];
    141     for(;;) {
    142         tb = *ptb1;
    143         if (!tb)
    144             goto not_found;
    145         if (tb->pc == pc &&
    146             tb->page_addr[0] == phys_page1 &&
    147             tb->cs_base == cs_base &&
    148             tb->flags == flags) {
    149             /* check next page if needed */
    150             if (tb->page_addr[1] != -1) {
    151                 virt_page2 = (pc & TARGET_PAGE_MASK) +
    152                     TARGET_PAGE_SIZE;
    153                 phys_page2 = get_phys_addr_code(env, virt_page2);
    154                 if (tb->page_addr[1] == phys_page2)
    155                     goto found;
    156             } else {
    157                 goto found;
    158             }
    159         }
    160         ptb1 = &tb->phys_hash_next;
    161     }
    162  not_found:
    163    /* if no translated code available, then translate it now */
    164     tb = tb_gen_code(env, pc, cs_base, flags, 0);
    165 
    166  found:
    167     /* we add the TB in the virtual pc hash table */
    168     env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
    169     return tb;
    170 }
    171 
    172 static inline TranslationBlock *tb_find_fast(void)
    173 {
    174     TranslationBlock *tb;
    175     target_ulong cs_base, pc;
    176     int flags;
    177 
    178     /* we record a subset of the CPU state. It will
    179        always be the same before a given translated block
    180        is executed. */
    181     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
    182     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
    183     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
    184                  tb->flags != flags)) {
    185         tb = tb_find_slow(pc, cs_base, flags);
    186     }
    187     return tb;
    188 }
    189 
    190 static CPUDebugExcpHandler *debug_excp_handler;
    191 
    192 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
    193 {
    194     CPUDebugExcpHandler *old_handler = debug_excp_handler;
    195 
    196     debug_excp_handler = handler;
    197     return old_handler;
    198 }
    199 
    200 static void cpu_handle_debug_exception(CPUState *env)
    201 {
    202     CPUWatchpoint *wp;
    203 
    204     if (!env->watchpoint_hit)
    205         QTAILQ_FOREACH(wp, &env->watchpoints, entry)
    206             wp->flags &= ~BP_WATCHPOINT_HIT;
    207 
    208     if (debug_excp_handler)
    209         debug_excp_handler(env);
    210 }
    211 
    212 /* main execution loop */
    213 
    214 int cpu_exec(CPUState *env1)
    215 {
    216 #define DECLARE_HOST_REGS 1
    217 #include "hostregs_helper.h"
    218     int ret, interrupt_request;
    219     TranslationBlock *tb;
    220     uint8_t *tc_ptr;
    221     unsigned long next_tb;
    222 
    223     if (cpu_halted(env1) == EXCP_HALTED)
    224         return EXCP_HALTED;
    225 
    226     cpu_single_env = env1;
    227 
    228     /* first we save global registers */
    229 #define SAVE_HOST_REGS 1
    230 #include "hostregs_helper.h"
    231     env = env1;
    232 
    233     env_to_regs();
    234 #if defined(TARGET_I386)
    235     /* put eflags in CPU temporary format */
    236     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    237     DF = 1 - (2 * ((env->eflags >> 10) & 1));
    238     CC_OP = CC_OP_EFLAGS;
    239     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    240 #elif defined(TARGET_SPARC)
    241 #elif defined(TARGET_M68K)
    242     env->cc_op = CC_OP_FLAGS;
    243     env->cc_dest = env->sr & 0xf;
    244     env->cc_x = (env->sr >> 4) & 1;
    245 #elif defined(TARGET_ALPHA)
    246 #elif defined(TARGET_ARM)
    247 #elif defined(TARGET_PPC)
    248 #elif defined(TARGET_MICROBLAZE)
    249 #elif defined(TARGET_MIPS)
    250 #elif defined(TARGET_SH4)
    251 #elif defined(TARGET_CRIS)
    252 #elif defined(TARGET_S390X)
    253     /* XXXXX */
    254 #else
    255 #error unsupported target CPU
    256 #endif
    257     env->exception_index = -1;
    258 
    259     /* prepare setjmp context for exception handling */
    260     for(;;) {
    261         if (setjmp(env->jmp_env) == 0) {
    262 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
    263 #undef env
    264                     env = cpu_single_env;
    265 #define env cpu_single_env
    266 #endif
    267             env->current_tb = NULL;
    268             /* if an exception is pending, we execute it here */
    269             if (env->exception_index >= 0) {
    270                 if (env->exception_index >= EXCP_INTERRUPT) {
    271                     /* exit request from the cpu execution loop */
    272                     ret = env->exception_index;
    273                     if (ret == EXCP_DEBUG)
    274                         cpu_handle_debug_exception(env);
    275                     break;
    276                 } else {
    277 #if defined(CONFIG_USER_ONLY)
    278                     /* if user mode only, we simulate a fake exception
    279                        which will be handled outside the cpu execution
    280                        loop */
    281 #if defined(TARGET_I386)
    282                     do_interrupt_user(env->exception_index,
    283                                       env->exception_is_int,
    284                                       env->error_code,
    285                                       env->exception_next_eip);
    286                     /* successfully delivered */
    287                     env->old_exception = -1;
    288 #endif
    289                     ret = env->exception_index;
    290                     break;
    291 #else
    292 #if defined(TARGET_I386)
    293                     /* simulate a real cpu exception. On i386, it can
    294                        trigger new exceptions, but we do not handle
    295                        double or triple faults yet. */
    296                     do_interrupt(env->exception_index,
    297                                  env->exception_is_int,
    298                                  env->error_code,
    299                                  env->exception_next_eip, 0);
    300                     /* successfully delivered */
    301                     env->old_exception = -1;
    302 #elif defined(TARGET_PPC)
    303                     do_interrupt(env);
    304 #elif defined(TARGET_MICROBLAZE)
    305                     do_interrupt(env);
    306 #elif defined(TARGET_MIPS)
    307                     do_interrupt(env);
    308 #elif defined(TARGET_SPARC)
    309                     do_interrupt(env);
    310 #elif defined(TARGET_ARM)
    311                     do_interrupt(env);
    312 #elif defined(TARGET_SH4)
    313 		    do_interrupt(env);
    314 #elif defined(TARGET_ALPHA)
    315                     do_interrupt(env);
    316 #elif defined(TARGET_CRIS)
    317                     do_interrupt(env);
    318 #elif defined(TARGET_M68K)
    319                     do_interrupt(0);
    320 #endif
    321                     env->exception_index = -1;
    322 #endif
    323                 }
    324             }
    325 
    326             if (kvm_enabled()) {
    327                 kvm_cpu_exec(env);
    328                 longjmp(env->jmp_env, 1);
    329             }
    330 
    331             next_tb = 0; /* force lookup of first TB */
    332             for(;;) {
    333                 interrupt_request = env->interrupt_request;
    334                 if (unlikely(interrupt_request)) {
    335                     if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
    336                         /* Mask out external interrupts for this step. */
    337                         interrupt_request &= ~(CPU_INTERRUPT_HARD |
    338                                                CPU_INTERRUPT_FIQ |
    339                                                CPU_INTERRUPT_SMI |
    340                                                CPU_INTERRUPT_NMI);
    341                     }
    342                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
    343                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
    344                         env->exception_index = EXCP_DEBUG;
    345                         cpu_loop_exit();
    346                     }
    347 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
    348     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
    349     defined(TARGET_MICROBLAZE)
    350                     if (interrupt_request & CPU_INTERRUPT_HALT) {
    351                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;
    352                         env->halted = 1;
    353                         env->exception_index = EXCP_HLT;
    354                         cpu_loop_exit();
    355                     }
    356 #endif
    357 #if defined(TARGET_I386)
    358                     if (interrupt_request & CPU_INTERRUPT_INIT) {
    359                             svm_check_intercept(SVM_EXIT_INIT);
    360                             do_cpu_init(env);
    361                             env->exception_index = EXCP_HALTED;
    362                             cpu_loop_exit();
    363                     } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
    364                             do_cpu_sipi(env);
    365                     } else if (env->hflags2 & HF2_GIF_MASK) {
    366                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
    367                             !(env->hflags & HF_SMM_MASK)) {
    368                             svm_check_intercept(SVM_EXIT_SMI);
    369                             env->interrupt_request &= ~CPU_INTERRUPT_SMI;
    370                             do_smm_enter();
    371                             next_tb = 0;
    372                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
    373                                    !(env->hflags2 & HF2_NMI_MASK)) {
    374                             env->interrupt_request &= ~CPU_INTERRUPT_NMI;
    375                             env->hflags2 |= HF2_NMI_MASK;
    376                             do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
    377                             next_tb = 0;
    378 			} else if (interrupt_request & CPU_INTERRUPT_MCE) {
    379                             env->interrupt_request &= ~CPU_INTERRUPT_MCE;
    380                             do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
    381                             next_tb = 0;
    382                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
    383                                    (((env->hflags2 & HF2_VINTR_MASK) &&
    384                                      (env->hflags2 & HF2_HIF_MASK)) ||
    385                                     (!(env->hflags2 & HF2_VINTR_MASK) &&
    386                                      (env->eflags & IF_MASK &&
    387                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
    388                             int intno;
    389                             svm_check_intercept(SVM_EXIT_INTR);
    390                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
    391                             intno = cpu_get_pic_interrupt(env);
    392                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
    393 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
    394 #undef env
    395                     env = cpu_single_env;
    396 #define env cpu_single_env
    397 #endif
    398                             do_interrupt(intno, 0, 0, 0, 1);
    399                             /* ensure that no TB jump will be modified as
    400                                the program flow was changed */
    401                             next_tb = 0;
    402 #if !defined(CONFIG_USER_ONLY)
    403                         } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
    404                                    (env->eflags & IF_MASK) &&
    405                                    !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
    406                             int intno;
    407                             /* FIXME: this should respect TPR */
    408                             svm_check_intercept(SVM_EXIT_VINTR);
    409                             intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
    410                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
    411                             do_interrupt(intno, 0, 0, 0, 1);
    412                             env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
    413                             next_tb = 0;
    414 #endif
    415                         }
    416                     }
    417 #elif defined(TARGET_PPC)
    418 #if 0
    419                     if ((interrupt_request & CPU_INTERRUPT_RESET)) {
    420                         cpu_reset(env);
    421                     }
    422 #endif
    423                     if (interrupt_request & CPU_INTERRUPT_HARD) {
    424                         ppc_hw_interrupt(env);
    425                         if (env->pending_interrupts == 0)
    426                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    427                         next_tb = 0;
    428                     }
    429 #elif defined(TARGET_MICROBLAZE)
    430                     if ((interrupt_request & CPU_INTERRUPT_HARD)
    431                         && (env->sregs[SR_MSR] & MSR_IE)
    432                         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
    433                         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
    434                         env->exception_index = EXCP_IRQ;
    435                         do_interrupt(env);
    436                         next_tb = 0;
    437                     }
    438 #elif defined(TARGET_MIPS)
    439                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
    440                         (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
    441                         (env->CP0_Status & (1 << CP0St_IE)) &&
    442                         !(env->CP0_Status & (1 << CP0St_EXL)) &&
    443                         !(env->CP0_Status & (1 << CP0St_ERL)) &&
    444                         !(env->hflags & MIPS_HFLAG_DM)) {
    445                         /* Raise it */
    446                         env->exception_index = EXCP_EXT_INTERRUPT;
    447                         env->error_code = 0;
    448                         do_interrupt(env);
    449                         next_tb = 0;
    450                     }
    451 #elif defined(TARGET_SPARC)
    452                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
    453 			(env->psret != 0)) {
    454 			int pil = env->interrupt_index & 15;
    455 			int type = env->interrupt_index & 0xf0;
    456 
    457 			if (((type == TT_EXTINT) &&
    458 			     (pil == 15 || pil > env->psrpil)) ||
    459 			    type != TT_EXTINT) {
    460 			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    461                             env->exception_index = env->interrupt_index;
    462                             do_interrupt(env);
    463 			    env->interrupt_index = 0;
    464 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
    465                             cpu_check_irqs(env);
    466 #endif
    467                         next_tb = 0;
    468 			}
    469 		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
    470 			//do_interrupt(0, 0, 0, 0, 0);
    471 			env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
    472 		    }
    473 #elif defined(TARGET_ARM)
    474                     if (interrupt_request & CPU_INTERRUPT_FIQ
    475                         && !(env->uncached_cpsr & CPSR_F)) {
    476                         env->exception_index = EXCP_FIQ;
    477                         do_interrupt(env);
    478                         next_tb = 0;
    479                     }
    480                     /* ARMv7-M interrupt return works by loading a magic value
    481                        into the PC.  On real hardware the load causes the
    482                        return to occur.  The qemu implementation performs the
    483                        jump normally, then does the exception return when the
    484                        CPU tries to execute code at the magic address.
    485                        This will cause the magic PC value to be pushed to
    486                        the stack if an interrupt occured at the wrong time.
    487                        We avoid this by disabling interrupts when
    488                        pc contains a magic address.  */
    489                     if (interrupt_request & CPU_INTERRUPT_HARD
    490                         && ((IS_M(env) && env->regs[15] < 0xfffffff0)
    491                             || !(env->uncached_cpsr & CPSR_I))) {
    492                         env->exception_index = EXCP_IRQ;
    493                         do_interrupt(env);
    494                         next_tb = 0;
    495                     }
    496 #elif defined(TARGET_SH4)
    497                     if (interrupt_request & CPU_INTERRUPT_HARD) {
    498                         do_interrupt(env);
    499                         next_tb = 0;
    500                     }
    501 #elif defined(TARGET_ALPHA)
    502                     if (interrupt_request & CPU_INTERRUPT_HARD) {
    503                         do_interrupt(env);
    504                         next_tb = 0;
    505                     }
    506 #elif defined(TARGET_CRIS)
    507                     if (interrupt_request & CPU_INTERRUPT_HARD
    508                         && (env->pregs[PR_CCS] & I_FLAG)) {
    509                         env->exception_index = EXCP_IRQ;
    510                         do_interrupt(env);
    511                         next_tb = 0;
    512                     }
    513                     if (interrupt_request & CPU_INTERRUPT_NMI
    514                         && (env->pregs[PR_CCS] & M_FLAG)) {
    515                         env->exception_index = EXCP_NMI;
    516                         do_interrupt(env);
    517                         next_tb = 0;
    518                     }
    519 #elif defined(TARGET_M68K)
    520                     if (interrupt_request & CPU_INTERRUPT_HARD
    521                         && ((env->sr & SR_I) >> SR_I_SHIFT)
    522                             < env->pending_level) {
    523                         /* Real hardware gets the interrupt vector via an
    524                            IACK cycle at this point.  Current emulated
    525                            hardware doesn't rely on this, so we
    526                            provide/save the vector when the interrupt is
    527                            first signalled.  */
    528                         env->exception_index = env->pending_vector;
    529                         do_interrupt(1);
    530                         next_tb = 0;
    531                     }
    532 #endif
    533                    /* Don't use the cached interupt_request value,
    534                       do_interrupt may have updated the EXITTB flag. */
    535                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
    536                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
    537                         /* ensure that no TB jump will be modified as
    538                            the program flow was changed */
    539                         next_tb = 0;
    540                     }
    541                 }
    542                 if (unlikely(env->exit_request)) {
    543                     env->exit_request = 0;
    544                     env->exception_index = EXCP_INTERRUPT;
    545                     cpu_loop_exit();
    546                 }
    547 #ifdef DEBUG_EXEC
    548                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
    549                     /* restore flags in standard format */
    550                     regs_to_env();
    551 #if defined(TARGET_I386)
    552                     env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
    553                     log_cpu_state(env, X86_DUMP_CCOP);
    554                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
    555 #elif defined(TARGET_ARM)
    556                     log_cpu_state(env, 0);
    557 #elif defined(TARGET_SPARC)
    558                     log_cpu_state(env, 0);
    559 #elif defined(TARGET_PPC)
    560                     log_cpu_state(env, 0);
    561 #elif defined(TARGET_M68K)
    562                     cpu_m68k_flush_flags(env, env->cc_op);
    563                     env->cc_op = CC_OP_FLAGS;
    564                     env->sr = (env->sr & 0xffe0)
    565                               | env->cc_dest | (env->cc_x << 4);
    566                     log_cpu_state(env, 0);
    567 #elif defined(TARGET_MICROBLAZE)
    568                     log_cpu_state(env, 0);
    569 #elif defined(TARGET_MIPS)
    570                     log_cpu_state(env, 0);
    571 #elif defined(TARGET_SH4)
    572 		    log_cpu_state(env, 0);
    573 #elif defined(TARGET_ALPHA)
    574                     log_cpu_state(env, 0);
    575 #elif defined(TARGET_CRIS)
    576                     log_cpu_state(env, 0);
    577 #else
    578 #error unsupported target CPU
    579 #endif
    580                 }
    581 #endif
    582                 spin_lock(&tb_lock);
    583                 tb = tb_find_fast();
    584                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
    585                    doing it in tb_find_slow */
    586                 if (tb_invalidated_flag) {
    587                     /* as some TB could have been invalidated because
    588                        of memory exceptions while generating the code, we
    589                        must recompute the hash index here */
    590                     next_tb = 0;
    591                     tb_invalidated_flag = 0;
    592                 }
    593 #ifdef DEBUG_EXEC
    594                 qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
    595                              (long)tb->tc_ptr, tb->pc,
    596                              lookup_symbol(tb->pc));
    597 #endif
    598                 /* see if we can patch the calling TB. When the TB
    599                    spans two pages, we cannot safely do a direct
    600                    jump. */
    601                 {
    602                     if (next_tb != 0 &&
    603 #ifdef CONFIG_KQEMU
    604                         (env->kqemu_enabled != 2) &&
    605 #endif
    606                         tb->page_addr[1] == -1) {
    607                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
    608                 }
    609                 }
    610                 spin_unlock(&tb_lock);
    611                 env->current_tb = tb;
    612 
    613                 /* cpu_interrupt might be called while translating the
    614                    TB, but before it is linked into a potentially
    615                    infinite loop and becomes env->current_tb. Avoid
    616                    starting execution if there is a pending interrupt. */
    617                 if (unlikely (env->exit_request))
    618                     env->current_tb = NULL;
    619 
    620                 while (env->current_tb) {
    621                     tc_ptr = tb->tc_ptr;
    622                 /* execute the generated code */
    623 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
    624 #undef env
    625                     env = cpu_single_env;
    626 #define env cpu_single_env
    627 #endif
    628                     next_tb = tcg_qemu_tb_exec(tc_ptr);
    629                     env->current_tb = NULL;
    630                     if ((next_tb & 3) == 2) {
    631                         /* Instruction counter expired.  */
    632                         int insns_left;
    633                         tb = (TranslationBlock *)(long)(next_tb & ~3);
    634                         /* Restore PC.  */
    635                         cpu_pc_from_tb(env, tb);
    636                         insns_left = env->icount_decr.u32;
    637                         if (env->icount_extra && insns_left >= 0) {
    638                             /* Refill decrementer and continue execution.  */
    639                             env->icount_extra += insns_left;
    640                             if (env->icount_extra > 0xffff) {
    641                                 insns_left = 0xffff;
    642                             } else {
    643                                 insns_left = env->icount_extra;
    644                             }
    645                             env->icount_extra -= insns_left;
    646                             env->icount_decr.u16.low = insns_left;
    647                         } else {
    648                             if (insns_left > 0) {
    649                                 /* Execute remaining instructions.  */
    650                                 cpu_exec_nocache(insns_left, tb);
    651                             }
    652                             env->exception_index = EXCP_INTERRUPT;
    653                             next_tb = 0;
    654                             cpu_loop_exit();
    655                         }
    656                     }
    657                 }
    658                 /* reset soft MMU for next block (it can currently
    659                    only be set by a memory fault) */
    660 #if defined(CONFIG_KQEMU)
    661 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
    662                 if (kqemu_is_ok(env) &&
    663                     (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
    664                     cpu_loop_exit();
    665                 }
    666 #endif
    667             } /* for(;;) */
    668         } else {
    669             env_to_regs();
    670         }
    671     } /* for(;;) */
    672 
    673 
    674 #if defined(TARGET_I386)
    675     /* restore flags in standard format */
    676     env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
    677 #elif defined(TARGET_ARM)
    678     /* XXX: Save/restore host fpu exception state?.  */
    679 #elif defined(TARGET_SPARC)
    680 #elif defined(TARGET_PPC)
    681 #elif defined(TARGET_M68K)
    682     cpu_m68k_flush_flags(env, env->cc_op);
    683     env->cc_op = CC_OP_FLAGS;
    684     env->sr = (env->sr & 0xffe0)
    685               | env->cc_dest | (env->cc_x << 4);
    686 #elif defined(TARGET_MICROBLAZE)
    687 #elif defined(TARGET_MIPS)
    688 #elif defined(TARGET_SH4)
    689 #elif defined(TARGET_ALPHA)
    690 #elif defined(TARGET_CRIS)
    691     /* XXXXX */
    692 #else
    693 #error unsupported target CPU
    694 #endif
    695 
    696     /* restore global registers */
    697 #include "hostregs_helper.h"
    698 
    699     /* fail safe : never use cpu_single_env outside cpu_exec() */
    700     cpu_single_env = NULL;
    701     return ret;
    702 }
    703 
    704 /* must only be called from the generated code as an exception can be
    705    generated */
    706 void tb_invalidate_page_range(target_ulong start, target_ulong end)
    707 {
    708     /* XXX: cannot enable it yet because it yields to MMU exception
    709        where NIP != read address on PowerPC */
    710 #if 0
    711     target_ulong phys_addr;
    712     phys_addr = get_phys_addr_code(env, start);
    713     tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
    714 #endif
    715 }
    716 
    717 #if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
    718 
    719 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
    720 {
    721     CPUX86State *saved_env;
    722 
    723     saved_env = env;
    724     env = s;
    725     if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
    726         selector &= 0xffff;
    727         cpu_x86_load_seg_cache(env, seg_reg, selector,
    728                                (selector << 4), 0xffff, 0);
    729     } else {
    730         helper_load_seg(seg_reg, selector);
    731     }
    732     env = saved_env;
    733 }
    734 
    735 void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
    736 {
    737     CPUX86State *saved_env;
    738 
    739     saved_env = env;
    740     env = s;
    741 
    742     helper_fsave(ptr, data32);
    743 
    744     env = saved_env;
    745 }
    746 
    747 void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
    748 {
    749     CPUX86State *saved_env;
    750 
    751     saved_env = env;
    752     env = s;
    753 
    754     helper_frstor(ptr, data32);
    755 
    756     env = saved_env;
    757 }
    758 
    759 #endif /* TARGET_I386 */
    760 
    761 #if !defined(CONFIG_SOFTMMU)
    762 
    763 #if defined(TARGET_I386)
    764 
    765 /* 'pc' is the host PC at which the exception was raised. 'address' is
    766    the effective address of the memory exception. 'is_write' is 1 if a
    767    write caused the exception and otherwise 0'. 'old_set' is the
    768    signal set which should be restored */
    769 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    770                                     int is_write, sigset_t *old_set,
    771                                     void *puc)
    772 {
    773     TranslationBlock *tb;
    774     int ret;
    775 
    776     if (cpu_single_env)
    777         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    778 #if defined(DEBUG_SIGNAL)
    779     qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    780                 pc, address, is_write, *(unsigned long *)old_set);
    781 #endif
    782     /* XXX: locking issue */
    783     if (is_write && page_unprotect(h2g(address), pc, puc)) {
    784         return 1;
    785     }
    786 
    787     /* see if it is an MMU fault */
    788     ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    789     if (ret < 0)
    790         return 0; /* not an MMU fault */
    791     if (ret == 0)
    792         return 1; /* the MMU fault was handled without causing real CPU fault */
    793     /* now we have a real cpu fault */
    794     tb = tb_find_pc(pc);
    795     if (tb) {
    796         /* the PC is inside the translated code. It means that we have
    797            a virtual CPU fault */
    798         cpu_restore_state(tb, env, pc, puc);
    799     }
    800     if (ret == 1) {
    801 #if 0
    802         printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
    803                env->eip, env->cr[2], env->error_code);
    804 #endif
    805         /* we restore the process signal mask as the sigreturn should
    806            do it (XXX: use sigsetjmp) */
    807         sigprocmask(SIG_SETMASK, old_set, NULL);
    808         raise_exception_err(env->exception_index, env->error_code);
    809     } else {
    810         /* activate soft MMU for this block */
    811         env->hflags |= HF_SOFTMMU_MASK;
    812         cpu_resume_from_signal(env, puc);
    813     }
    814     /* never comes here */
    815     return 1;
    816 }
    817 
    818 #elif defined(TARGET_ARM)
    819 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    820                                     int is_write, sigset_t *old_set,
    821                                     void *puc)
    822 {
    823     TranslationBlock *tb;
    824     int ret;
    825 
    826     if (cpu_single_env)
    827         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    828 #if defined(DEBUG_SIGNAL)
    829     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    830            pc, address, is_write, *(unsigned long *)old_set);
    831 #endif
    832     /* XXX: locking issue */
    833     if (is_write && page_unprotect(h2g(address), pc, puc)) {
    834         return 1;
    835     }
    836     /* see if it is an MMU fault */
    837     ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    838     if (ret < 0)
    839         return 0; /* not an MMU fault */
    840     if (ret == 0)
    841         return 1; /* the MMU fault was handled without causing real CPU fault */
    842     /* now we have a real cpu fault */
    843     tb = tb_find_pc(pc);
    844     if (tb) {
    845         /* the PC is inside the translated code. It means that we have
    846            a virtual CPU fault */
    847         cpu_restore_state(tb, env, pc, puc);
    848     }
    849     /* we restore the process signal mask as the sigreturn should
    850        do it (XXX: use sigsetjmp) */
    851     sigprocmask(SIG_SETMASK, old_set, NULL);
    852     cpu_loop_exit();
    853     /* never comes here */
    854     return 1;
    855 }
    856 #elif defined(TARGET_SPARC)
    857 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    858                                     int is_write, sigset_t *old_set,
    859                                     void *puc)
    860 {
    861     TranslationBlock *tb;
    862     int ret;
    863 
    864     if (cpu_single_env)
    865         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    866 #if defined(DEBUG_SIGNAL)
    867     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    868            pc, address, is_write, *(unsigned long *)old_set);
    869 #endif
    870     /* XXX: locking issue */
    871     if (is_write && page_unprotect(h2g(address), pc, puc)) {
    872         return 1;
    873     }
    874     /* see if it is an MMU fault */
    875     ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    876     if (ret < 0)
    877         return 0; /* not an MMU fault */
    878     if (ret == 0)
    879         return 1; /* the MMU fault was handled without causing real CPU fault */
    880     /* now we have a real cpu fault */
    881     tb = tb_find_pc(pc);
    882     if (tb) {
    883         /* the PC is inside the translated code. It means that we have
    884            a virtual CPU fault */
    885         cpu_restore_state(tb, env, pc, puc);
    886     }
    887     /* we restore the process signal mask as the sigreturn should
    888        do it (XXX: use sigsetjmp) */
    889     sigprocmask(SIG_SETMASK, old_set, NULL);
    890     cpu_loop_exit();
    891     /* never comes here */
    892     return 1;
    893 }
    894 #elif defined (TARGET_PPC)
    895 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    896                                     int is_write, sigset_t *old_set,
    897                                     void *puc)
    898 {
    899     TranslationBlock *tb;
    900     int ret;
    901 
    902     if (cpu_single_env)
    903         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    904 #if defined(DEBUG_SIGNAL)
    905     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    906            pc, address, is_write, *(unsigned long *)old_set);
    907 #endif
    908     /* XXX: locking issue */
    909     if (is_write && page_unprotect(h2g(address), pc, puc)) {
    910         return 1;
    911     }
    912 
    913     /* see if it is an MMU fault */
    914     ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    915     if (ret < 0)
    916         return 0; /* not an MMU fault */
    917     if (ret == 0)
    918         return 1; /* the MMU fault was handled without causing real CPU fault */
    919 
    920     /* now we have a real cpu fault */
    921     tb = tb_find_pc(pc);
    922     if (tb) {
    923         /* the PC is inside the translated code. It means that we have
    924            a virtual CPU fault */
    925         cpu_restore_state(tb, env, pc, puc);
    926     }
    927     if (ret == 1) {
    928 #if 0
    929         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
    930                env->nip, env->error_code, tb);
    931 #endif
    932     /* we restore the process signal mask as the sigreturn should
    933        do it (XXX: use sigsetjmp) */
    934         sigprocmask(SIG_SETMASK, old_set, NULL);
    935         cpu_loop_exit();
    936     } else {
    937         /* activate soft MMU for this block */
    938         cpu_resume_from_signal(env, puc);
    939     }
    940     /* never comes here */
    941     return 1;
    942 }
    943 
    944 #elif defined(TARGET_M68K)
    945 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    946                                     int is_write, sigset_t *old_set,
    947                                     void *puc)
    948 {
    949     TranslationBlock *tb;
    950     int ret;
    951 
    952     if (cpu_single_env)
    953         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    954 #if defined(DEBUG_SIGNAL)
    955     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    956            pc, address, is_write, *(unsigned long *)old_set);
    957 #endif
    958     /* XXX: locking issue */
    959     if (is_write && page_unprotect(address, pc, puc)) {
    960         return 1;
    961     }
    962     /* see if it is an MMU fault */
    963     ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    964     if (ret < 0)
    965         return 0; /* not an MMU fault */
    966     if (ret == 0)
    967         return 1; /* the MMU fault was handled without causing real CPU fault */
    968     /* now we have a real cpu fault */
    969     tb = tb_find_pc(pc);
    970     if (tb) {
    971         /* the PC is inside the translated code. It means that we have
    972            a virtual CPU fault */
    973         cpu_restore_state(tb, env, pc, puc);
    974     }
    975     /* we restore the process signal mask as the sigreturn should
    976        do it (XXX: use sigsetjmp) */
    977     sigprocmask(SIG_SETMASK, old_set, NULL);
    978     cpu_loop_exit();
    979     /* never comes here */
    980     return 1;
    981 }
    982 
    983 #elif defined (TARGET_MIPS)
    984 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    985                                     int is_write, sigset_t *old_set,
    986                                     void *puc)
    987 {
    988     TranslationBlock *tb;
    989     int ret;
    990 
    991     if (cpu_single_env)
    992         env = cpu_single_env; /* XXX: find a correct solution for multithread */
    993 #if defined(DEBUG_SIGNAL)
    994     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
    995            pc, address, is_write, *(unsigned long *)old_set);
    996 #endif
    997     /* XXX: locking issue */
    998     if (is_write && page_unprotect(h2g(address), pc, puc)) {
    999         return 1;
   1000     }
   1001 
   1002     /* see if it is an MMU fault */
   1003     ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
   1004     if (ret < 0)
   1005         return 0; /* not an MMU fault */
   1006     if (ret == 0)
   1007         return 1; /* the MMU fault was handled without causing real CPU fault */
   1008 
   1009     /* now we have a real cpu fault */
   1010     tb = tb_find_pc(pc);
   1011     if (tb) {
   1012         /* the PC is inside the translated code. It means that we have
   1013            a virtual CPU fault */
   1014         cpu_restore_state(tb, env, pc, puc);
   1015     }
   1016     if (ret == 1) {
   1017 #if 0
   1018         printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
   1019                env->PC, env->error_code, tb);
   1020 #endif
   1021     /* we restore the process signal mask as the sigreturn should
   1022        do it (XXX: use sigsetjmp) */
   1023         sigprocmask(SIG_SETMASK, old_set, NULL);
   1024         cpu_loop_exit();
   1025     } else {
   1026         /* activate soft MMU for this block */
   1027         cpu_resume_from_signal(env, puc);
   1028     }
   1029     /* never comes here */
   1030     return 1;
   1031 }
   1032 
   1033 #elif defined (TARGET_MICROBLAZE)
   1034 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
   1035                                     int is_write, sigset_t *old_set,
   1036                                     void *puc)
   1037 {
   1038     TranslationBlock *tb;
   1039     int ret;
   1040 
   1041     if (cpu_single_env)
   1042         env = cpu_single_env; /* XXX: find a correct solution for multithread */
   1043 #if defined(DEBUG_SIGNAL)
   1044     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
   1045            pc, address, is_write, *(unsigned long *)old_set);
   1046 #endif
   1047     /* XXX: locking issue */
   1048     if (is_write && page_unprotect(h2g(address), pc, puc)) {
   1049         return 1;
   1050     }
   1051 
   1052     /* see if it is an MMU fault */
   1053     ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
   1054     if (ret < 0)
   1055         return 0; /* not an MMU fault */
   1056     if (ret == 0)
   1057         return 1; /* the MMU fault was handled without causing real CPU fault */
   1058 
   1059     /* now we have a real cpu fault */
   1060     tb = tb_find_pc(pc);
   1061     if (tb) {
   1062         /* the PC is inside the translated code. It means that we have
   1063            a virtual CPU fault */
   1064         cpu_restore_state(tb, env, pc, puc);
   1065     }
   1066     if (ret == 1) {
   1067 #if 0
   1068         printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
   1069                env->PC, env->error_code, tb);
   1070 #endif
   1071     /* we restore the process signal mask as the sigreturn should
   1072        do it (XXX: use sigsetjmp) */
   1073         sigprocmask(SIG_SETMASK, old_set, NULL);
   1074         cpu_loop_exit();
   1075     } else {
   1076         /* activate soft MMU for this block */
   1077         cpu_resume_from_signal(env, puc);
   1078     }
   1079     /* never comes here */
   1080     return 1;
   1081 }
   1082 
   1083 #elif defined (TARGET_SH4)
   1084 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
   1085                                     int is_write, sigset_t *old_set,
   1086                                     void *puc)
   1087 {
   1088     TranslationBlock *tb;
   1089     int ret;
   1090 
   1091     if (cpu_single_env)
   1092         env = cpu_single_env; /* XXX: find a correct solution for multithread */
   1093 #if defined(DEBUG_SIGNAL)
   1094     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
   1095            pc, address, is_write, *(unsigned long *)old_set);
   1096 #endif
   1097     /* XXX: locking issue */
   1098     if (is_write && page_unprotect(h2g(address), pc, puc)) {
   1099         return 1;
   1100     }
   1101 
   1102     /* see if it is an MMU fault */
   1103     ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
   1104     if (ret < 0)
   1105         return 0; /* not an MMU fault */
   1106     if (ret == 0)
   1107         return 1; /* the MMU fault was handled without causing real CPU fault */
   1108 
   1109     /* now we have a real cpu fault */
   1110     tb = tb_find_pc(pc);
   1111     if (tb) {
   1112         /* the PC is inside the translated code. It means that we have
   1113            a virtual CPU fault */
   1114         cpu_restore_state(tb, env, pc, puc);
   1115     }
   1116 #if 0
   1117         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
   1118                env->nip, env->error_code, tb);
   1119 #endif
   1120     /* we restore the process signal mask as the sigreturn should
   1121        do it (XXX: use sigsetjmp) */
   1122     sigprocmask(SIG_SETMASK, old_set, NULL);
   1123     cpu_loop_exit();
   1124     /* never comes here */
   1125     return 1;
   1126 }
   1127 
   1128 #elif defined (TARGET_ALPHA)
   1129 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
   1130                                     int is_write, sigset_t *old_set,
   1131                                     void *puc)
   1132 {
   1133     TranslationBlock *tb;
   1134     int ret;
   1135 
   1136     if (cpu_single_env)
   1137         env = cpu_single_env; /* XXX: find a correct solution for multithread */
   1138 #if defined(DEBUG_SIGNAL)
   1139     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
   1140            pc, address, is_write, *(unsigned long *)old_set);
   1141 #endif
   1142     /* XXX: locking issue */
   1143     if (is_write && page_unprotect(h2g(address), pc, puc)) {
   1144         return 1;
   1145     }
   1146 
   1147     /* see if it is an MMU fault */
   1148     ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
   1149     if (ret < 0)
   1150         return 0; /* not an MMU fault */
   1151     if (ret == 0)
   1152         return 1; /* the MMU fault was handled without causing real CPU fault */
   1153 
   1154     /* now we have a real cpu fault */
   1155     tb = tb_find_pc(pc);
   1156     if (tb) {
   1157         /* the PC is inside the translated code. It means that we have
   1158            a virtual CPU fault */
   1159         cpu_restore_state(tb, env, pc, puc);
   1160     }
   1161 #if 0
   1162         printf("PF exception: NIP=0x%08x error=0x%x %p\n",
   1163                env->nip, env->error_code, tb);
   1164 #endif
   1165     /* we restore the process signal mask as the sigreturn should
   1166        do it (XXX: use sigsetjmp) */
   1167     sigprocmask(SIG_SETMASK, old_set, NULL);
   1168     cpu_loop_exit();
   1169     /* never comes here */
   1170     return 1;
   1171 }
   1172 #elif defined (TARGET_CRIS)
   1173 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
   1174                                     int is_write, sigset_t *old_set,
   1175                                     void *puc)
   1176 {
   1177     TranslationBlock *tb;
   1178     int ret;
   1179 
   1180     if (cpu_single_env)
   1181         env = cpu_single_env; /* XXX: find a correct solution for multithread */
   1182 #if defined(DEBUG_SIGNAL)
   1183     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
   1184            pc, address, is_write, *(unsigned long *)old_set);
   1185 #endif
   1186     /* XXX: locking issue */
   1187     if (is_write && page_unprotect(h2g(address), pc, puc)) {
   1188         return 1;
   1189     }
   1190 
   1191     /* see if it is an MMU fault */
   1192     ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
   1193     if (ret < 0)
   1194         return 0; /* not an MMU fault */
   1195     if (ret == 0)
   1196         return 1; /* the MMU fault was handled without causing real CPU fault */
   1197 
   1198     /* now we have a real cpu fault */
   1199     tb = tb_find_pc(pc);
   1200     if (tb) {
   1201         /* the PC is inside the translated code. It means that we have
   1202            a virtual CPU fault */
   1203         cpu_restore_state(tb, env, pc, puc);
   1204     }
   1205     /* we restore the process signal mask as the sigreturn should
   1206        do it (XXX: use sigsetjmp) */
   1207     sigprocmask(SIG_SETMASK, old_set, NULL);
   1208     cpu_loop_exit();
   1209     /* never comes here */
   1210     return 1;
   1211 }
   1212 
   1213 #else
   1214 #error unsupported target CPU
   1215 #endif
   1216 
   1217 #if defined(__i386__)
   1218 
   1219 #if defined(__APPLE__)
   1220 # include <sys/ucontext.h>
   1221 
   1222 # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
   1223 # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
   1224 # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
   1225 # define MASK_sig(context)    ((context)->uc_sigmask)
   1226 #elif defined(__OpenBSD__)
   1227 # define EIP_sig(context)     ((context)->sc_eip)
   1228 # define TRAP_sig(context)    ((context)->sc_trapno)
   1229 # define ERROR_sig(context)   ((context)->sc_err)
   1230 # define MASK_sig(context)    ((context)->sc_mask)
   1231 #else
   1232 # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
   1233 # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
   1234 # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
   1235 # define MASK_sig(context)    ((context)->uc_sigmask)
   1236 #endif
   1237 
   1238 int cpu_signal_handler(int host_signum, void *pinfo,
   1239                        void *puc)
   1240 {
   1241     siginfo_t *info = pinfo;
   1242 #if defined(__OpenBSD__)
   1243     struct sigcontext *uc = puc;
   1244 #else
   1245     struct ucontext *uc = puc;
   1246 #endif
   1247     unsigned long pc;
   1248     int trapno;
   1249 
   1250 #ifndef REG_EIP
   1251 /* for glibc 2.1 */
   1252 #define REG_EIP    EIP
   1253 #define REG_ERR    ERR
   1254 #define REG_TRAPNO TRAPNO
   1255 #endif
   1256     pc = EIP_sig(uc);
   1257     trapno = TRAP_sig(uc);
   1258     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1259                              trapno == 0xe ?
   1260                              (ERROR_sig(uc) >> 1) & 1 : 0,
   1261                              &MASK_sig(uc), puc);
   1262 }
   1263 
   1264 #elif defined(__x86_64__)
   1265 
   1266 #ifdef __NetBSD__
   1267 #define PC_sig(context)       _UC_MACHINE_PC(context)
   1268 #define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
   1269 #define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
   1270 #define MASK_sig(context)     ((context)->uc_sigmask)
   1271 #elif defined(__OpenBSD__)
   1272 #define PC_sig(context)       ((context)->sc_rip)
   1273 #define TRAP_sig(context)     ((context)->sc_trapno)
   1274 #define ERROR_sig(context)    ((context)->sc_err)
   1275 #define MASK_sig(context)     ((context)->sc_mask)
   1276 #else
   1277 #define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
   1278 #define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
   1279 #define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
   1280 #define MASK_sig(context)     ((context)->uc_sigmask)
   1281 #endif
   1282 
   1283 int cpu_signal_handler(int host_signum, void *pinfo,
   1284                        void *puc)
   1285 {
   1286     siginfo_t *info = pinfo;
   1287     unsigned long pc;
   1288 #ifdef __NetBSD__
   1289     ucontext_t *uc = puc;
   1290 #elif defined(__OpenBSD__)
   1291     struct sigcontext *uc = puc;
   1292 #else
   1293     struct ucontext *uc = puc;
   1294 #endif
   1295 
   1296     pc = PC_sig(uc);
   1297     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1298                              TRAP_sig(uc) == 0xe ?
   1299                              (ERROR_sig(uc) >> 1) & 1 : 0,
   1300                              &MASK_sig(uc), puc);
   1301 }
   1302 
   1303 #elif defined(_ARCH_PPC)
   1304 
   1305 /***********************************************************************
   1306  * signal context platform-specific definitions
   1307  * From Wine
   1308  */
   1309 #ifdef linux
   1310 /* All Registers access - only for local access */
   1311 # define REG_sig(reg_name, context)		((context)->uc_mcontext.regs->reg_name)
   1312 /* Gpr Registers access  */
   1313 # define GPR_sig(reg_num, context)		REG_sig(gpr[reg_num], context)
   1314 # define IAR_sig(context)			REG_sig(nip, context)	/* Program counter */
   1315 # define MSR_sig(context)			REG_sig(msr, context)   /* Machine State Register (Supervisor) */
   1316 # define CTR_sig(context)			REG_sig(ctr, context)   /* Count register */
   1317 # define XER_sig(context)			REG_sig(xer, context) /* User's integer exception register */
   1318 # define LR_sig(context)			REG_sig(link, context) /* Link register */
   1319 # define CR_sig(context)			REG_sig(ccr, context) /* Condition register */
   1320 /* Float Registers access  */
   1321 # define FLOAT_sig(reg_num, context)		(((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
   1322 # define FPSCR_sig(context)			(*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
   1323 /* Exception Registers access */
   1324 # define DAR_sig(context)			REG_sig(dar, context)
   1325 # define DSISR_sig(context)			REG_sig(dsisr, context)
   1326 # define TRAP_sig(context)			REG_sig(trap, context)
   1327 #endif /* linux */
   1328 
   1329 #ifdef __APPLE__
   1330 # include <sys/ucontext.h>
   1331 typedef struct ucontext SIGCONTEXT;
   1332 /* All Registers access - only for local access */
   1333 # define REG_sig(reg_name, context)		((context)->uc_mcontext->ss.reg_name)
   1334 # define FLOATREG_sig(reg_name, context)	((context)->uc_mcontext->fs.reg_name)
   1335 # define EXCEPREG_sig(reg_name, context)	((context)->uc_mcontext->es.reg_name)
   1336 # define VECREG_sig(reg_name, context)		((context)->uc_mcontext->vs.reg_name)
   1337 /* Gpr Registers access */
   1338 # define GPR_sig(reg_num, context)		REG_sig(r##reg_num, context)
   1339 # define IAR_sig(context)			REG_sig(srr0, context)	/* Program counter */
   1340 # define MSR_sig(context)			REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
   1341 # define CTR_sig(context)			REG_sig(ctr, context)
   1342 # define XER_sig(context)			REG_sig(xer, context) /* Link register */
   1343 # define LR_sig(context)			REG_sig(lr, context)  /* User's integer exception register */
   1344 # define CR_sig(context)			REG_sig(cr, context)  /* Condition register */
   1345 /* Float Registers access */
   1346 # define FLOAT_sig(reg_num, context)		FLOATREG_sig(fpregs[reg_num], context)
   1347 # define FPSCR_sig(context)			((double)FLOATREG_sig(fpscr, context))
   1348 /* Exception Registers access */
   1349 # define DAR_sig(context)			EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
   1350 # define DSISR_sig(context)			EXCEPREG_sig(dsisr, context)
   1351 # define TRAP_sig(context)			EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
   1352 #endif /* __APPLE__ */
   1353 
   1354 int cpu_signal_handler(int host_signum, void *pinfo,
   1355                        void *puc)
   1356 {
   1357     siginfo_t *info = pinfo;
   1358     struct ucontext *uc = puc;
   1359     unsigned long pc;
   1360     int is_write;
   1361 
   1362     pc = IAR_sig(uc);
   1363     is_write = 0;
   1364 #if 0
   1365     /* ppc 4xx case */
   1366     if (DSISR_sig(uc) & 0x00800000)
   1367         is_write = 1;
   1368 #else
   1369     if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
   1370         is_write = 1;
   1371 #endif
   1372     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1373                              is_write, &uc->uc_sigmask, puc);
   1374 }
   1375 
   1376 #elif defined(__alpha__)
   1377 
   1378 int cpu_signal_handler(int host_signum, void *pinfo,
   1379                            void *puc)
   1380 {
   1381     siginfo_t *info = pinfo;
   1382     struct ucontext *uc = puc;
   1383     uint32_t *pc = uc->uc_mcontext.sc_pc;
   1384     uint32_t insn = *pc;
   1385     int is_write = 0;
   1386 
   1387     /* XXX: need kernel patch to get write flag faster */
   1388     switch (insn >> 26) {
   1389     case 0x0d: // stw
   1390     case 0x0e: // stb
   1391     case 0x0f: // stq_u
   1392     case 0x24: // stf
   1393     case 0x25: // stg
   1394     case 0x26: // sts
   1395     case 0x27: // stt
   1396     case 0x2c: // stl
   1397     case 0x2d: // stq
   1398     case 0x2e: // stl_c
   1399     case 0x2f: // stq_c
   1400 	is_write = 1;
   1401     }
   1402 
   1403     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1404                              is_write, &uc->uc_sigmask, puc);
   1405 }
   1406 #elif defined(__sparc__)
   1407 
   1408 int cpu_signal_handler(int host_signum, void *pinfo,
   1409                        void *puc)
   1410 {
   1411     siginfo_t *info = pinfo;
   1412     int is_write;
   1413     uint32_t insn;
   1414 #if !defined(__arch64__) || defined(CONFIG_SOLARIS)
   1415     uint32_t *regs = (uint32_t *)(info + 1);
   1416     void *sigmask = (regs + 20);
   1417     /* XXX: is there a standard glibc define ? */
   1418     unsigned long pc = regs[1];
   1419 #else
   1420 #ifdef __linux__
   1421     struct sigcontext *sc = puc;
   1422     unsigned long pc = sc->sigc_regs.tpc;
   1423     void *sigmask = (void *)sc->sigc_mask;
   1424 #elif defined(__OpenBSD__)
   1425     struct sigcontext *uc = puc;
   1426     unsigned long pc = uc->sc_pc;
   1427     void *sigmask = (void *)(long)uc->sc_mask;
   1428 #endif
   1429 #endif
   1430 
   1431     /* XXX: need kernel patch to get write flag faster */
   1432     is_write = 0;
   1433     insn = *(uint32_t *)pc;
   1434     if ((insn >> 30) == 3) {
   1435       switch((insn >> 19) & 0x3f) {
   1436       case 0x05: // stb
   1437       case 0x15: // stba
   1438       case 0x06: // sth
   1439       case 0x16: // stha
   1440       case 0x04: // st
   1441       case 0x14: // sta
   1442       case 0x07: // std
   1443       case 0x17: // stda
   1444       case 0x0e: // stx
   1445       case 0x1e: // stxa
   1446       case 0x24: // stf
   1447       case 0x34: // stfa
   1448       case 0x27: // stdf
   1449       case 0x37: // stdfa
   1450       case 0x26: // stqf
   1451       case 0x36: // stqfa
   1452       case 0x25: // stfsr
   1453       case 0x3c: // casa
   1454       case 0x3e: // casxa
   1455 	is_write = 1;
   1456 	break;
   1457       }
   1458     }
   1459     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1460                              is_write, sigmask, NULL);
   1461 }
   1462 
   1463 #elif defined(__arm__)
   1464 
   1465 int cpu_signal_handler(int host_signum, void *pinfo,
   1466                        void *puc)
   1467 {
   1468     siginfo_t *info = pinfo;
   1469     struct ucontext *uc = puc;
   1470     unsigned long pc;
   1471     int is_write;
   1472 
   1473 #if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
   1474     pc = uc->uc_mcontext.gregs[R15];
   1475 #else
   1476     pc = uc->uc_mcontext.arm_pc;
   1477 #endif
   1478     /* XXX: compute is_write */
   1479     is_write = 0;
   1480     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1481                              is_write,
   1482                              &uc->uc_sigmask, puc);
   1483 }
   1484 
   1485 #elif defined(__mc68000)
   1486 
   1487 int cpu_signal_handler(int host_signum, void *pinfo,
   1488                        void *puc)
   1489 {
   1490     siginfo_t *info = pinfo;
   1491     struct ucontext *uc = puc;
   1492     unsigned long pc;
   1493     int is_write;
   1494 
   1495     pc = uc->uc_mcontext.gregs[16];
   1496     /* XXX: compute is_write */
   1497     is_write = 0;
   1498     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1499                              is_write,
   1500                              &uc->uc_sigmask, puc);
   1501 }
   1502 
   1503 #elif defined(__ia64)
   1504 
   1505 #ifndef __ISR_VALID
   1506   /* This ought to be in <bits/siginfo.h>... */
   1507 # define __ISR_VALID	1
   1508 #endif
   1509 
   1510 int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
   1511 {
   1512     siginfo_t *info = pinfo;
   1513     struct ucontext *uc = puc;
   1514     unsigned long ip;
   1515     int is_write = 0;
   1516 
   1517     ip = uc->uc_mcontext.sc_ip;
   1518     switch (host_signum) {
   1519       case SIGILL:
   1520       case SIGFPE:
   1521       case SIGSEGV:
   1522       case SIGBUS:
   1523       case SIGTRAP:
   1524 	  if (info->si_code && (info->si_segvflags & __ISR_VALID))
   1525 	      /* ISR.W (write-access) is bit 33:  */
   1526 	      is_write = (info->si_isr >> 33) & 1;
   1527 	  break;
   1528 
   1529       default:
   1530 	  break;
   1531     }
   1532     return handle_cpu_signal(ip, (unsigned long)info->si_addr,
   1533                              is_write,
   1534                              &uc->uc_sigmask, puc);
   1535 }
   1536 
   1537 #elif defined(__s390__)
   1538 
   1539 int cpu_signal_handler(int host_signum, void *pinfo,
   1540                        void *puc)
   1541 {
   1542     siginfo_t *info = pinfo;
   1543     struct ucontext *uc = puc;
   1544     unsigned long pc;
   1545     int is_write;
   1546 
   1547     pc = uc->uc_mcontext.psw.addr;
   1548     /* XXX: compute is_write */
   1549     is_write = 0;
   1550     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1551                              is_write, &uc->uc_sigmask, puc);
   1552 }
   1553 
   1554 #elif defined(__mips__)
   1555 
   1556 int cpu_signal_handler(int host_signum, void *pinfo,
   1557                        void *puc)
   1558 {
   1559     siginfo_t *info = pinfo;
   1560     struct ucontext *uc = puc;
   1561     greg_t pc = uc->uc_mcontext.pc;
   1562     int is_write;
   1563 
   1564     /* XXX: compute is_write */
   1565     is_write = 0;
   1566     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1567                              is_write, &uc->uc_sigmask, puc);
   1568 }
   1569 
   1570 #elif defined(__hppa__)
   1571 
   1572 int cpu_signal_handler(int host_signum, void *pinfo,
   1573                        void *puc)
   1574 {
   1575     struct siginfo *info = pinfo;
   1576     struct ucontext *uc = puc;
   1577     unsigned long pc;
   1578     int is_write;
   1579 
   1580     pc = uc->uc_mcontext.sc_iaoq[0];
   1581     /* FIXME: compute is_write */
   1582     is_write = 0;
   1583     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
   1584                              is_write,
   1585                              &uc->uc_sigmask, puc);
   1586 }
   1587 
   1588 #else
   1589 
   1590 #error host CPU specific signal handler needed
   1591 
   1592 #endif
   1593 
   1594 #endif /* !defined(CONFIG_SOFTMMU) */
   1595