Diff for /qemu/cpu-exec.c between versions 1.1.1.5 and 1.1.1.6

version 1.1.1.5, 2018/04/24 16:44:47 version 1.1.1.6, 2018/04/24 16:47:11
Line 1 Line 1
 /*  /*
  *  i386 emulator main execution loop   *  i386 emulator main execution loop
  *    *
  *  Copyright (c) 2003-2005 Fabrice Bellard   *  Copyright (c) 2003-2005 Fabrice Bellard
  *   *
  * This library is free software; you can redistribute it and/or   * This library is free software; you can redistribute it and/or
Line 40  int tb_invalidated_flag; Line 40  int tb_invalidated_flag;
 //#define DEBUG_EXEC  //#define DEBUG_EXEC
 //#define DEBUG_SIGNAL  //#define DEBUG_SIGNAL
   
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K)  #define SAVE_GLOBALS()
 /* XXX: unify with i386 target */  #define RESTORE_GLOBALS()
   
   #if defined(__sparc__) && !defined(HOST_SOLARIS)
   #include <features.h>
   #if defined(__GLIBC__) && ((__GLIBC__ < 2) || \
                              ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 90)))
   // Work around ugly bugs in glibc that mangle global register contents
   
   static volatile void *saved_env;
   static volatile unsigned long saved_t0, saved_i7;
   #undef SAVE_GLOBALS
   #define SAVE_GLOBALS() do {                                     \
           saved_env = env;                                        \
           saved_t0 = T0;                                          \
           asm volatile ("st %%i7, [%0]" : : "r" (&saved_i7));     \
       } while(0)
   
   #undef RESTORE_GLOBALS
   #define RESTORE_GLOBALS() do {                                  \
           env = (void *)saved_env;                                \
           T0 = saved_t0;                                          \
           asm volatile ("ld [%0], %%i7" : : "r" (&saved_i7));     \
       } while(0)
   
   static int sparc_setjmp(jmp_buf buf)
   {
       int ret;
   
       SAVE_GLOBALS();
       ret = setjmp(buf);
       RESTORE_GLOBALS();
       return ret;
   }
   #undef setjmp
   #define setjmp(jmp_buf) sparc_setjmp(jmp_buf)
   
   static void sparc_longjmp(jmp_buf buf, int val)
   {
       SAVE_GLOBALS();
       longjmp(buf, val);
   }
   #define longjmp(jmp_buf, val) sparc_longjmp(jmp_buf, val)
   #endif
   #endif
   
 void cpu_loop_exit(void)  void cpu_loop_exit(void)
 {  {
       /* NOTE: the register at this point must be saved by hand because
          longjmp restore them */
       regs_to_env();
     longjmp(env->jmp_env, 1);      longjmp(env->jmp_env, 1);
 }  }
 #endif  
 #if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))  #if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
 #define reg_T2  #define reg_T2
 #endif  #endif
Line 54  void cpu_loop_exit(void) Line 101  void cpu_loop_exit(void)
 /* exit the current TB from a signal handler. The host registers are  /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator     restored in a state compatible with the CPU emulator
  */   */
 void cpu_resume_from_signal(CPUState *env1, void *puc)   void cpu_resume_from_signal(CPUState *env1, void *puc)
 {  {
 #if !defined(CONFIG_SOFTMMU)  #if !defined(CONFIG_SOFTMMU)
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
Line 76  void cpu_resume_from_signal(CPUState *en Line 123  void cpu_resume_from_signal(CPUState *en
   
 static TranslationBlock *tb_find_slow(target_ulong pc,  static TranslationBlock *tb_find_slow(target_ulong pc,
                                       target_ulong cs_base,                                        target_ulong cs_base,
                                       unsigned int flags)                                        uint64_t flags)
 {  {
     TranslationBlock *tb, **ptb1;      TranslationBlock *tb, **ptb1;
     int code_gen_size;      int code_gen_size;
     unsigned int h;      unsigned int h;
     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;      target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
     uint8_t *tc_ptr;      uint8_t *tc_ptr;
       
     spin_lock(&tb_lock);      spin_lock(&tb_lock);
   
     tb_invalidated_flag = 0;      tb_invalidated_flag = 0;
       
     regs_to_env(); /* XXX: do it just before cpu_gen_code() */      regs_to_env(); /* XXX: do it just before cpu_gen_code() */
       
     /* find translated block using physical mappings */      /* find translated block using physical mappings */
     phys_pc = get_phys_addr_code(env, pc);      phys_pc = get_phys_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;      phys_page1 = phys_pc & TARGET_PAGE_MASK;
Line 100  static TranslationBlock *tb_find_slow(ta Line 147  static TranslationBlock *tb_find_slow(ta
         tb = *ptb1;          tb = *ptb1;
         if (!tb)          if (!tb)
             goto not_found;              goto not_found;
         if (tb->pc == pc &&           if (tb->pc == pc &&
             tb->page_addr[0] == phys_page1 &&              tb->page_addr[0] == phys_page1 &&
             tb->cs_base == cs_base &&               tb->cs_base == cs_base &&
             tb->flags == flags) {              tb->flags == flags) {
             /* check next page if needed */              /* check next page if needed */
             if (tb->page_addr[1] != -1) {              if (tb->page_addr[1] != -1) {
                 virt_page2 = (pc & TARGET_PAGE_MASK) +                   virt_page2 = (pc & TARGET_PAGE_MASK) +
                     TARGET_PAGE_SIZE;                      TARGET_PAGE_SIZE;
                 phys_page2 = get_phys_addr_code(env, virt_page2);                  phys_page2 = get_phys_addr_code(env, virt_page2);
                 if (tb->page_addr[1] == phys_page2)                  if (tb->page_addr[1] == phys_page2)
Line 132  static TranslationBlock *tb_find_slow(ta Line 179  static TranslationBlock *tb_find_slow(ta
     tb->tc_ptr = tc_ptr;      tb->tc_ptr = tc_ptr;
     tb->cs_base = cs_base;      tb->cs_base = cs_base;
     tb->flags = flags;      tb->flags = flags;
     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);      SAVE_GLOBALS();
       cpu_gen_code(env, tb, &code_gen_size);
       RESTORE_GLOBALS();
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));      code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
       
     /* check next page if needed */      /* check next page if needed */
     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;      virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
     phys_page2 = -1;      phys_page2 = -1;
Line 142  static TranslationBlock *tb_find_slow(ta Line 191  static TranslationBlock *tb_find_slow(ta
         phys_page2 = get_phys_addr_code(env, virt_page2);          phys_page2 = get_phys_addr_code(env, virt_page2);
     }      }
     tb_link_phys(tb, phys_pc, phys_page2);      tb_link_phys(tb, phys_pc, phys_page2);
       
  found:   found:
     /* we add the TB in the virtual pc hash table */      /* we add the TB in the virtual pc hash table */
     env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;      env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
Line 154  static inline TranslationBlock *tb_find_ Line 203  static inline TranslationBlock *tb_find_
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
     target_ulong cs_base, pc;      target_ulong cs_base, pc;
     unsigned int flags;      uint64_t flags;
   
     /* we record a subset of the CPU state. It will      /* we record a subset of the CPU state. It will
        always be the same before a given translated block         always be the same before a given translated block
Line 162  static inline TranslationBlock *tb_find_ Line 211  static inline TranslationBlock *tb_find_
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
     flags = env->hflags;      flags = env->hflags;
     flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));      flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
       flags |= env->intercept;
     cs_base = env->segs[R_CS].base;      cs_base = env->segs[R_CS].base;
     pc = cs_base + env->eip;      pc = cs_base + env->eip;
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
Line 171  static inline TranslationBlock *tb_find_ Line 221  static inline TranslationBlock *tb_find_
         flags |= (1 << 6);          flags |= (1 << 6);
     if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))      if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
         flags |= (1 << 7);          flags |= (1 << 7);
       flags |= (env->condexec_bits << 8);
     cs_base = 0;      cs_base = 0;
     pc = env->regs[15];      pc = env->regs[15];
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
Line 179  static inline TranslationBlock *tb_find_ Line 230  static inline TranslationBlock *tb_find_
     flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))      flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
         | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);          | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
 #else  #else
     // FPU enable . MMU enabled . MMU no-fault . Supervisor      // FPU enable . Supervisor
     flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)      flags = (env->psref << 4) | env->psrs;
         | env->psrs;  
 #endif  #endif
     cs_base = env->npc;      cs_base = env->npc;
     pc = env->pc;      pc = env->pc;
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
     flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |      flags = env->hflags;
         (msr_se << MSR_SE) | (msr_le << MSR_LE);  
     cs_base = 0;      cs_base = 0;
     pc = env->nip;      pc = env->nip;
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
     flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);      flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
     cs_base = 0;      cs_base = 0;
     pc = env->PC;      pc = env->PC[env->current_tc];
 #elif defined(TARGET_M68K)  #elif defined(TARGET_M68K)
     flags = env->fpcr & M68K_FPCR_PREC;      flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
               | (env->sr & SR_S)            /* Bit  13 */
               | ((env->macsr >> 4) & 0xf);  /* Bits 0-3 */
     cs_base = 0;      cs_base = 0;
     pc = env->pc;      pc = env->pc;
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
     flags = env->sr & (SR_MD | SR_RB);      flags = env->flags;
     cs_base = 0;         /* XXXXX */      cs_base = 0;
       pc = env->pc;
   #elif defined(TARGET_ALPHA)
       flags = env->ps;
       cs_base = 0;
       pc = env->pc;
   #elif defined(TARGET_CRIS)
       flags = 0;
       cs_base = 0;
     pc = env->pc;      pc = env->pc;
 #else  #else
 #error unsupported CPU  #error unsupported CPU
Line 221  static inline TranslationBlock *tb_find_ Line 280  static inline TranslationBlock *tb_find_
     return tb;      return tb;
 }  }
   
   #define BREAK_CHAIN T0 = 0
   
 /* main execution loop */  /* main execution loop */
   
Line 233  int cpu_exec(CPUState *env1) Line 293  int cpu_exec(CPUState *env1)
     uint32_t *saved_regwptr;      uint32_t *saved_regwptr;
 #endif  #endif
 #endif  #endif
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  
     int saved_i7;  
     target_ulong tmp_T0;  
 #endif  
     int ret, interrupt_request;      int ret, interrupt_request;
     void (*gen_func)(void);      void (*gen_func)(void);
     TranslationBlock *tb;      TranslationBlock *tb;
     uint8_t *tc_ptr;      uint8_t *tc_ptr;
   
 #if defined(TARGET_I386)      if (cpu_halted(env1) == EXCP_HALTED)
     /* handle exit of HALTED state */          return EXCP_HALTED;
     if (env1->hflags & HF_HALTED_MASK) {  
         /* disable halt condition */  
         if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&  
             (env1->eflags & IF_MASK)) {  
             env1->hflags &= ~HF_HALTED_MASK;  
         } else {  
             return EXCP_HALTED;  
         }  
     }  
 #elif defined(TARGET_PPC)  
     if (env1->halted) {  
         if (env1->msr[MSR_EE] &&   
             (env1->interrupt_request &   
              (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {  
             env1->halted = 0;  
         } else {  
             return EXCP_HALTED;  
         }  
     }  
 #elif defined(TARGET_SPARC)  
     if (env1->halted) {  
         if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&  
             (env1->psret != 0)) {  
             env1->halted = 0;  
         } else {  
             return EXCP_HALTED;  
         }  
     }  
 #elif defined(TARGET_ARM)  
     if (env1->halted) {  
         /* An interrupt wakes the CPU even if the I and F CPSR bits are  
            set.  */  
         if (env1->interrupt_request  
             & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) {  
             env1->halted = 0;  
         } else {  
             return EXCP_HALTED;  
         }  
     }  
 #elif defined(TARGET_MIPS)  
     if (env1->halted) {  
         if (env1->interrupt_request &  
             (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {  
             env1->halted = 0;  
         } else {  
             return EXCP_HALTED;  
         }  
     }  
 #endif  
   
     cpu_single_env = env1;       cpu_single_env = env1;
   
     /* first we save global registers */      /* first we save global registers */
 #define SAVE_HOST_REGS 1  #define SAVE_HOST_REGS 1
 #include "hostregs_helper.h"  #include "hostregs_helper.h"
     env = env1;      env = env1;
 #if defined(__sparc__) && !defined(HOST_SOLARIS)      SAVE_GLOBALS();
     /* we also save i7 because longjmp may not restore it */  
     asm volatile ("mov %%i7, %0" : "=r" (saved_i7));  
 #endif  
   
 #if defined(TARGET_I386)  
     env_to_regs();      env_to_regs();
   #if defined(TARGET_I386)
     /* put eflags in CPU temporary format */      /* put eflags in CPU temporary format */
     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);      CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((env->eflags >> 10) & 1));      DF = 1 - (2 * ((env->eflags >> 10) & 1));
     CC_OP = CC_OP_EFLAGS;      CC_OP = CC_OP_EFLAGS;
     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);      env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 #elif defined(TARGET_ARM)  
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
 #if defined(reg_REGWPTR)  #if defined(reg_REGWPTR)
     saved_regwptr = REGWPTR;      saved_regwptr = REGWPTR;
 #endif  #endif
 #elif defined(TARGET_PPC)  
 #elif defined(TARGET_M68K)  #elif defined(TARGET_M68K)
     env->cc_op = CC_OP_FLAGS;      env->cc_op = CC_OP_FLAGS;
     env->cc_dest = env->sr & 0xf;      env->cc_dest = env->sr & 0xf;
     env->cc_x = (env->sr >> 4) & 1;      env->cc_x = (env->sr >> 4) & 1;
   #elif defined(TARGET_ALPHA)
   #elif defined(TARGET_ARM)
   #elif defined(TARGET_PPC)
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
   #elif defined(TARGET_CRIS)
     /* XXXXX */      /* XXXXX */
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
Line 345  int cpu_exec(CPUState *env1) Line 351  int cpu_exec(CPUState *env1)
                        which will be handled outside the cpu execution                         which will be handled outside the cpu execution
                        loop */                         loop */
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
                     do_interrupt_user(env->exception_index,                       do_interrupt_user(env->exception_index,
                                       env->exception_is_int,                                         env->exception_is_int,
                                       env->error_code,                                         env->error_code,
                                       env->exception_next_eip);                                        env->exception_next_eip);
 #endif  #endif
                     ret = env->exception_index;                      ret = env->exception_index;
Line 357  int cpu_exec(CPUState *env1) Line 363  int cpu_exec(CPUState *env1)
                     /* simulate a real cpu exception. On i386, it can                      /* simulate a real cpu exception. On i386, it can
                        trigger new exceptions, but we do not handle                         trigger new exceptions, but we do not handle
                        double or triple faults yet. */                         double or triple faults yet. */
                     do_interrupt(env->exception_index,                       do_interrupt(env->exception_index,
                                  env->exception_is_int,                                    env->exception_is_int,
                                  env->error_code,                                    env->error_code,
                                  env->exception_next_eip, 0);                                   env->exception_next_eip, 0);
                       /* successfully delivered */
                       env->old_exception = -1;
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
                     do_interrupt(env);                      do_interrupt(env);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
Line 371  int cpu_exec(CPUState *env1) Line 379  int cpu_exec(CPUState *env1)
                     do_interrupt(env);                      do_interrupt(env);
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
                     do_interrupt(env);                      do_interrupt(env);
   #elif defined(TARGET_ALPHA)
                       do_interrupt(env);
   #elif defined(TARGET_CRIS)
                       do_interrupt(env);
   #elif defined(TARGET_M68K)
                       do_interrupt(0);
 #endif  #endif
                 }                  }
                 env->exception_index = -1;                  env->exception_index = -1;
             }               }
 #ifdef USE_KQEMU  #ifdef USE_KQEMU
             if (kqemu_is_ok(env) && env->interrupt_request == 0) {              if (kqemu_is_ok(env) && env->interrupt_request == 0) {
                 int ret;                  int ret;
Line 403  int cpu_exec(CPUState *env1) Line 417  int cpu_exec(CPUState *env1)
   
             T0 = 0; /* force lookup of first TB */              T0 = 0; /* force lookup of first TB */
             for(;;) {              for(;;) {
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                  SAVE_GLOBALS();
                 /* g1 can be modified by some libc? functions */   
                 tmp_T0 = T0;  
 #endif        
                 interrupt_request = env->interrupt_request;                  interrupt_request = env->interrupt_request;
                 if (__builtin_expect(interrupt_request, 0)) {                  if (__builtin_expect(interrupt_request, 0)
   #if defined(TARGET_I386)
                           && env->hflags & HF_GIF_MASK
   #endif
                                   ) {
                       if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                           env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                           env->exception_index = EXCP_DEBUG;
                           cpu_loop_exit();
                       }
   #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
       defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
                       if (interrupt_request & CPU_INTERRUPT_HALT) {
                           env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                           env->halted = 1;
                           env->exception_index = EXCP_HLT;
                           cpu_loop_exit();
                       }
   #endif
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
                     if ((interrupt_request & CPU_INTERRUPT_SMI) &&                      if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                         !(env->hflags & HF_SMM_MASK)) {                          !(env->hflags & HF_SMM_MASK)) {
                           svm_check_intercept(SVM_EXIT_SMI);
                         env->interrupt_request &= ~CPU_INTERRUPT_SMI;                          env->interrupt_request &= ~CPU_INTERRUPT_SMI;
                         do_smm_enter();                          do_smm_enter();
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                          BREAK_CHAIN;
                         tmp_T0 = 0;  
 #else  
                         T0 = 0;  
 #endif  
                     } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->eflags & IF_MASK) &&                           (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {                          !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                         int intno;                          int intno;
                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;                          svm_check_intercept(SVM_EXIT_INTR);
                           env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                         intno = cpu_get_pic_interrupt(env);                          intno = cpu_get_pic_interrupt(env);
                         if (loglevel & CPU_LOG_TB_IN_ASM) {                          if (loglevel & CPU_LOG_TB_IN_ASM) {
                             fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);                              fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
Line 431  int cpu_exec(CPUState *env1) Line 458  int cpu_exec(CPUState *env1)
                         do_interrupt(intno, 0, 0, 0, 1);                          do_interrupt(intno, 0, 0, 0, 1);
                         /* ensure that no TB jump will be modified as                          /* ensure that no TB jump will be modified as
                            the program flow was changed */                             the program flow was changed */
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                          BREAK_CHAIN;
                         tmp_T0 = 0;  #if !defined(CONFIG_USER_ONLY)
 #else                      } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
                         T0 = 0;                          (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                            int intno;
                            /* FIXME: this should respect TPR */
                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
                            svm_check_intercept(SVM_EXIT_VINTR);
                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
                            if (loglevel & CPU_LOG_TB_IN_ASM)
                                fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
                            do_interrupt(intno, 0, 0, -1, 1);
                            stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
                                     ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
                           BREAK_CHAIN;
 #endif  #endif
                     }                      }
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
Line 443  int cpu_exec(CPUState *env1) Line 481  int cpu_exec(CPUState *env1)
                         cpu_ppc_reset(env);                          cpu_ppc_reset(env);
                     }                      }
 #endif  #endif
                     if (msr_ee != 0) {                      if (interrupt_request & CPU_INTERRUPT_HARD) {
                         if ((interrupt_request & CPU_INTERRUPT_HARD)) {                          ppc_hw_interrupt(env);
                             /* Raise it */                          if (env->pending_interrupts == 0)
                             env->exception_index = EXCP_EXTERNAL;  
                             env->error_code = 0;  
                             do_interrupt(env);  
                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;                              env->interrupt_request &= ~CPU_INTERRUPT_HARD;
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                          BREAK_CHAIN;
                             tmp_T0 = 0;  
 #else  
                             T0 = 0;  
 #endif  
                         } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {  
                             /* Raise it */  
                             env->exception_index = EXCP_DECR;  
                             env->error_code = 0;  
                             do_interrupt(env);  
                             env->interrupt_request &= ~CPU_INTERRUPT_TIMER;  
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  
                             tmp_T0 = 0;  
 #else  
                             T0 = 0;  
 #endif  
                         }  
                     }                      }
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                           (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
                         (env->CP0_Status & (1 << CP0St_IE)) &&                          (env->CP0_Status & (1 << CP0St_IE)) &&
                         (env->CP0_Status & env->CP0_Cause & 0x0000FF00) &&                          !(env->CP0_Status & (1 << CP0St_EXL)) &&
                         !(env->hflags & MIPS_HFLAG_EXL) &&                          !(env->CP0_Status & (1 << CP0St_ERL)) &&
                         !(env->hflags & MIPS_HFLAG_ERL) &&  
                         !(env->hflags & MIPS_HFLAG_DM)) {                          !(env->hflags & MIPS_HFLAG_DM)) {
                         /* Raise it */                          /* Raise it */
                         env->exception_index = EXCP_EXT_INTERRUPT;                          env->exception_index = EXCP_EXT_INTERRUPT;
                         env->error_code = 0;                          env->error_code = 0;
                         do_interrupt(env);                          do_interrupt(env);
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                          BREAK_CHAIN;
                         tmp_T0 = 0;  
 #else  
                         T0 = 0;  
 #endif  
                     }                      }
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      if ((interrupt_request & CPU_INTERRUPT_HARD) &&
Line 497  int cpu_exec(CPUState *env1) Line 512  int cpu_exec(CPUState *env1)
                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;                              env->interrupt_request &= ~CPU_INTERRUPT_HARD;
                             do_interrupt(env->interrupt_index);                              do_interrupt(env->interrupt_index);
                             env->interrupt_index = 0;                              env->interrupt_index = 0;
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
                             tmp_T0 = 0;                              cpu_check_irqs(env);
 #else  
                             T0 = 0;  
 #endif  #endif
                           BREAK_CHAIN;
                         }                          }
                     } else if (interrupt_request & CPU_INTERRUPT_TIMER) {                      } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
                         //do_interrupt(0, 0, 0, 0, 0);                          //do_interrupt(0, 0, 0, 0, 0);
                         env->interrupt_request &= ~CPU_INTERRUPT_TIMER;                          env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
                     } else if (interrupt_request & CPU_INTERRUPT_HALT) {                      }
                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;  
                         env->halted = 1;  
                         env->exception_index = EXCP_HLT;  
                         cpu_loop_exit();  
                     }  
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
                     if (interrupt_request & CPU_INTERRUPT_FIQ                      if (interrupt_request & CPU_INTERRUPT_FIQ
                         && !(env->uncached_cpsr & CPSR_F)) {                          && !(env->uncached_cpsr & CPSR_F)) {
                         env->exception_index = EXCP_FIQ;                          env->exception_index = EXCP_FIQ;
                         do_interrupt(env);                          do_interrupt(env);
                           BREAK_CHAIN;
                     }                      }
                       /* ARMv7-M interrupt return works by loading a magic value
                          into the PC.  On real hardware the load causes the
                          return to occur.  The qemu implementation performs the
                          jump normally, then does the exception return when the
                          CPU tries to execute code at the magic address.
                          This will cause the magic PC value to be pushed to
                          the stack if an interrupt occured at the wrong time.
                          We avoid this by disabling interrupts when
                          pc contains a magic address.  */
                     if (interrupt_request & CPU_INTERRUPT_HARD                      if (interrupt_request & CPU_INTERRUPT_HARD
                         && !(env->uncached_cpsr & CPSR_I)) {                          && ((IS_M(env) && env->regs[15] < 0xfffffff0)
                               || !(env->uncached_cpsr & CPSR_I))) {
                         env->exception_index = EXCP_IRQ;                          env->exception_index = EXCP_IRQ;
                         do_interrupt(env);                          do_interrupt(env);
                           BREAK_CHAIN;
                     }                      }
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
                     /* XXXXX */                      if (interrupt_request & CPU_INTERRUPT_HARD) {
                           do_interrupt(env);
                           BREAK_CHAIN;
                       }
   #elif defined(TARGET_ALPHA)
                       if (interrupt_request & CPU_INTERRUPT_HARD) {
                           do_interrupt(env);
                           BREAK_CHAIN;
                       }
   #elif defined(TARGET_CRIS)
                       if (interrupt_request & CPU_INTERRUPT_HARD) {
                           do_interrupt(env);
                           env->interrupt_request &= ~CPU_INTERRUPT_HARD;
                           BREAK_CHAIN;
                       }
   #elif defined(TARGET_M68K)
                       if (interrupt_request & CPU_INTERRUPT_HARD
                           && ((env->sr & SR_I) >> SR_I_SHIFT)
                               < env->pending_level) {
                           /* Real hardware gets the interrupt vector via an
                              IACK cycle at this point.  Current emulated
                              hardware doesn't rely on this, so we
                              provide/save the vector when the interrupt is
                              first signalled.  */
                           env->exception_index = env->pending_vector;
                           do_interrupt(1);
                           BREAK_CHAIN;
                       }
 #endif  #endif
                    /* Don't use the cached interupt_request value,                     /* Don't use the cached interupt_request value,
                       do_interrupt may have updated the EXITTB flag. */                        do_interrupt may have updated the EXITTB flag. */
Line 532  int cpu_exec(CPUState *env1) Line 580  int cpu_exec(CPUState *env1)
                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;                          env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
                         /* ensure that no TB jump will be modified as                          /* ensure that no TB jump will be modified as
                            the program flow was changed */                             the program flow was changed */
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                          BREAK_CHAIN;
                         tmp_T0 = 0;  
 #else  
                         T0 = 0;  
 #endif  
                     }                      }
                     if (interrupt_request & CPU_INTERRUPT_EXIT) {                      if (interrupt_request & CPU_INTERRUPT_EXIT) {
                         env->interrupt_request &= ~CPU_INTERRUPT_EXIT;                          env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
Line 546  int cpu_exec(CPUState *env1) Line 590  int cpu_exec(CPUState *env1)
                 }                  }
 #ifdef DEBUG_EXEC  #ifdef DEBUG_EXEC
                 if ((loglevel & CPU_LOG_TB_CPU)) {                  if ((loglevel & CPU_LOG_TB_CPU)) {
 #if defined(TARGET_I386)  
                     /* restore flags in standard format */                      /* restore flags in standard format */
 #ifdef reg_EAX                      regs_to_env();
                     env->regs[R_EAX] = EAX;  #if defined(TARGET_I386)
 #endif  
 #ifdef reg_EBX  
                     env->regs[R_EBX] = EBX;  
 #endif  
 #ifdef reg_ECX  
                     env->regs[R_ECX] = ECX;  
 #endif  
 #ifdef reg_EDX  
                     env->regs[R_EDX] = EDX;  
 #endif  
 #ifdef reg_ESI  
                     env->regs[R_ESI] = ESI;  
 #endif  
 #ifdef reg_EDI  
                     env->regs[R_EDI] = EDI;  
 #endif  
 #ifdef reg_EBP  
                     env->regs[R_EBP] = EBP;  
 #endif  
 #ifdef reg_ESP  
                     env->regs[R_ESP] = ESP;  
 #endif  
                     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);                      env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
                     cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);                      cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);                      env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
Line 593  int cpu_exec(CPUState *env1) Line 614  int cpu_exec(CPUState *env1)
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
   #elif defined(TARGET_ALPHA)
                       cpu_dump_state(env, logfile, fprintf, 0);
   #elif defined(TARGET_CRIS)
                       cpu_dump_state(env, logfile, fprintf, 0);
 #else  #else
 #error unsupported target CPU   #error unsupported target CPU
 #endif  #endif
                 }                  }
 #endif  #endif
Line 606  int cpu_exec(CPUState *env1) Line 631  int cpu_exec(CPUState *env1)
                             lookup_symbol(tb->pc));                              lookup_symbol(tb->pc));
                 }                  }
 #endif  #endif
 #if defined(__sparc__) && !defined(HOST_SOLARIS)                  RESTORE_GLOBALS();
                 T0 = tmp_T0;  
 #endif        
                 /* see if we can patch the calling TB. When the TB                  /* see if we can patch the calling TB. When the TB
                    spans two pages, we cannot safely do a direct                     spans two pages, we cannot safely do a direct
                    jump. */                     jump. */
Line 617  int cpu_exec(CPUState *env1) Line 640  int cpu_exec(CPUState *env1)
 #if USE_KQEMU  #if USE_KQEMU
                         (env->kqemu_enabled != 2) &&                          (env->kqemu_enabled != 2) &&
 #endif  #endif
                         tb->page_addr[1] == -1                          tb->page_addr[1] == -1) {
 #if defined(TARGET_I386) && defined(USE_CODE_COPY)  
                     && (tb->cflags & CF_CODE_COPY) ==   
                     (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)  
 #endif  
                     ) {  
                     spin_lock(&tb_lock);                      spin_lock(&tb_lock);
                     tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);                      tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
 #if defined(USE_CODE_COPY)  
                     /* propagates the FP use info */  
                     ((TranslationBlock *)(T0 & ~3))->cflags |=   
                         (tb->cflags & CF_FP_USED);  
 #endif  
                     spin_unlock(&tb_lock);                      spin_unlock(&tb_lock);
                 }                  }
                 }                  }
Line 641  int cpu_exec(CPUState *env1) Line 654  int cpu_exec(CPUState *env1)
                 __asm__ __volatile__("call      %0\n\t"                  __asm__ __volatile__("call      %0\n\t"
                                      "mov       %%o7,%%i0"                                       "mov       %%o7,%%i0"
                                      : /* no outputs */                                       : /* no outputs */
                                      : "r" (gen_func)                                        : "r" (gen_func)
                                      : "i0", "i1", "i2", "i3", "i4", "i5",                                       : "i0", "i1", "i2", "i3", "i4", "i5",
                                          "o0", "o1", "o2", "o3", "o4", "o5",
                                        "l0", "l1", "l2", "l3", "l4", "l5",                                         "l0", "l1", "l2", "l3", "l4", "l5",
                                        "l6", "l7");                                         "l6", "l7");
 #elif defined(__arm__)  #elif defined(__arm__)
Line 652  int cpu_exec(CPUState *env1) Line 666  int cpu_exec(CPUState *env1)
                               : /* no outputs */                                : /* no outputs */
                               : "r" (gen_func)                                : "r" (gen_func)
                               : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");                                : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
 #elif defined(TARGET_I386) && defined(USE_CODE_COPY)  
 {  
     if (!(tb->cflags & CF_CODE_COPY)) {  
         if ((tb->cflags & CF_FP_USED) && env->native_fp_regs) {  
             save_native_fp_state(env);  
         }  
         gen_func();  
     } else {  
         if ((tb->cflags & CF_FP_USED) && !env->native_fp_regs) {  
             restore_native_fp_state(env);  
         }  
         /* we work with native eflags */  
         CC_SRC = cc_table[CC_OP].compute_all();  
         CC_OP = CC_OP_EFLAGS;  
         asm(".globl exec_loop\n"  
             "\n"  
             "debug1:\n"  
             "    pushl %%ebp\n"  
             "    fs movl %10, %9\n"  
             "    fs movl %11, %%eax\n"  
             "    andl $0x400, %%eax\n"  
             "    fs orl %8, %%eax\n"  
             "    pushl %%eax\n"  
             "    popf\n"  
             "    fs movl %%esp, %12\n"  
             "    fs movl %0, %%eax\n"  
             "    fs movl %1, %%ecx\n"  
             "    fs movl %2, %%edx\n"  
             "    fs movl %3, %%ebx\n"  
             "    fs movl %4, %%esp\n"  
             "    fs movl %5, %%ebp\n"  
             "    fs movl %6, %%esi\n"  
             "    fs movl %7, %%edi\n"  
             "    fs jmp *%9\n"  
             "exec_loop:\n"  
             "    fs movl %%esp, %4\n"  
             "    fs movl %12, %%esp\n"  
             "    fs movl %%eax, %0\n"  
             "    fs movl %%ecx, %1\n"  
             "    fs movl %%edx, %2\n"  
             "    fs movl %%ebx, %3\n"  
             "    fs movl %%ebp, %5\n"  
             "    fs movl %%esi, %6\n"  
             "    fs movl %%edi, %7\n"  
             "    pushf\n"  
             "    popl %%eax\n"  
             "    movl %%eax, %%ecx\n"  
             "    andl $0x400, %%ecx\n"  
             "    shrl $9, %%ecx\n"  
             "    andl $0x8d5, %%eax\n"  
             "    fs movl %%eax, %8\n"  
             "    movl $1, %%eax\n"  
             "    subl %%ecx, %%eax\n"  
             "    fs movl %%eax, %11\n"  
             "    fs movl %9, %%ebx\n" /* get T0 value */  
             "    popl %%ebp\n"  
             :  
             : "m" (*(uint8_t *)offsetof(CPUState, regs[0])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[1])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[2])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[3])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[4])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[5])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[6])),  
             "m" (*(uint8_t *)offsetof(CPUState, regs[7])),  
             "m" (*(uint8_t *)offsetof(CPUState, cc_src)),  
             "m" (*(uint8_t *)offsetof(CPUState, tmp0)),  
             "a" (gen_func),  
             "m" (*(uint8_t *)offsetof(CPUState, df)),  
             "m" (*(uint8_t *)offsetof(CPUState, saved_esp))  
             : "%ecx", "%edx"  
             );  
     }  
 }  
 #elif defined(__ia64)  #elif defined(__ia64)
                 struct fptr {                  struct fptr {
                         void *ip;                          void *ip;
Line 755  int cpu_exec(CPUState *env1) Line 695  int cpu_exec(CPUState *env1)
                     cpu_loop_exit();                      cpu_loop_exit();
                 }                  }
 #endif  #endif
             }              } /* for(;;) */
         } else {          } else {
             env_to_regs();              env_to_regs();
         }          }
Line 763  int cpu_exec(CPUState *env1) Line 703  int cpu_exec(CPUState *env1)
   
   
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
 #if defined(USE_CODE_COPY)  
     if (env->native_fp_regs) {  
         save_native_fp_state(env);  
     }  
 #endif  
     /* restore flags in standard format */      /* restore flags in standard format */
     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);      env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
Line 784  int cpu_exec(CPUState *env1) Line 719  int cpu_exec(CPUState *env1)
               | env->cc_dest | (env->cc_x << 4);                | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
   #elif defined(TARGET_ALPHA)
   #elif defined(TARGET_CRIS)
     /* XXXXX */      /* XXXXX */
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
 #endif  #endif
   
     /* restore global registers */      /* restore global registers */
 #if defined(__sparc__) && !defined(HOST_SOLARIS)      RESTORE_GLOBALS();
     asm volatile ("mov %0, %%i7" : : "r" (saved_i7));  
 #endif  
 #include "hostregs_helper.h"  #include "hostregs_helper.h"
   
     /* fail safe : never use cpu_single_env outside cpu_exec() */      /* fail safe : never use cpu_single_env outside cpu_exec() */
     cpu_single_env = NULL;       cpu_single_env = NULL;
     return ret;      return ret;
 }  }
   
Line 823  void cpu_x86_load_seg(CPUX86State *s, in Line 758  void cpu_x86_load_seg(CPUX86State *s, in
     env = s;      env = s;
     if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {      if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
         selector &= 0xffff;          selector &= 0xffff;
         cpu_x86_load_seg_cache(env, seg_reg, selector,           cpu_x86_load_seg_cache(env, seg_reg, selector,
                                (selector << 4), 0xffff, 0);                                 (selector << 4), 0xffff, 0);
     } else {      } else {
         load_seg(seg_reg, selector);          load_seg(seg_reg, selector);
Line 831  void cpu_x86_load_seg(CPUX86State *s, in Line 766  void cpu_x86_load_seg(CPUX86State *s, in
     env = saved_env;      env = saved_env;
 }  }
   
 void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32)  void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
 {  {
     CPUX86State *saved_env;      CPUX86State *saved_env;
   
     saved_env = env;      saved_env = env;
     env = s;      env = s;
       
     helper_fsave((target_ulong)ptr, data32);      helper_fsave(ptr, data32);
   
     env = saved_env;      env = saved_env;
 }  }
   
 void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)  void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
 {  {
     CPUX86State *saved_env;      CPUX86State *saved_env;
   
     saved_env = env;      saved_env = env;
     env = s;      env = s;
       
     helper_frstor((target_ulong)ptr, data32);      helper_frstor(ptr, data32);
   
     env = saved_env;      env = saved_env;
 }  }
Line 866  void cpu_x86_frstor(CPUX86State *s, uint Line 801  void cpu_x86_frstor(CPUX86State *s, uint
    write caused the exception and otherwise 0'. 'old_set' is the     write caused the exception and otherwise 0'. 'old_set' is the
    signal set which should be restored */     signal set which should be restored */
 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,  static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
                                     int is_write, sigset_t *old_set,                                       int is_write, sigset_t *old_set,
                                     void *puc)                                      void *puc)
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
Line 875  static inline int handle_cpu_signal(unsi Line 810  static inline int handle_cpu_signal(unsi
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
                 pc, address, is_write, *(unsigned long *)old_set);                  pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 884  static inline int handle_cpu_signal(unsi Line 819  static inline int handle_cpu_signal(unsi
     }      }
   
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_x86_handle_mmu_fault(env, address, is_write,       ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
                                    ((env->hflags & HF_CPL_MASK) == 3), 0);  
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 899  static inline int handle_cpu_signal(unsi Line 833  static inline int handle_cpu_signal(unsi
     }      }
     if (ret == 1) {      if (ret == 1) {
 #if 0  #if 0
         printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",           printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
                env->eip, env->cr[2], env->error_code);                 env->eip, env->cr[2], env->error_code);
 #endif  #endif
         /* we restore the process signal mask as the sigreturn should          /* we restore the process signal mask as the sigreturn should
Line 926  static inline int handle_cpu_signal(unsi Line 860  static inline int handle_cpu_signal(unsi
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 934  static inline int handle_cpu_signal(unsi Line 868  static inline int handle_cpu_signal(unsi
         return 1;          return 1;
     }      }
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);      ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 962  static inline int handle_cpu_signal(unsi Line 896  static inline int handle_cpu_signal(unsi
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 970  static inline int handle_cpu_signal(unsi Line 904  static inline int handle_cpu_signal(unsi
         return 1;          return 1;
     }      }
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);      ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 994  static inline int handle_cpu_signal(unsi Line 928  static inline int handle_cpu_signal(unsi
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
     int ret;      int ret;
       
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 1007  static inline int handle_cpu_signal(unsi Line 941  static inline int handle_cpu_signal(unsi
     }      }
   
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);      ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 1022  static inline int handle_cpu_signal(unsi Line 956  static inline int handle_cpu_signal(unsi
     }      }
     if (ret == 1) {      if (ret == 1) {
 #if 0  #if 0
         printf("PF exception: NIP=0x%08x error=0x%x %p\n",           printf("PF exception: NIP=0x%08x error=0x%x %p\n",
                env->nip, env->error_code, tb);                 env->nip, env->error_code, tb);
 #endif  #endif
     /* we restore the process signal mask as the sigreturn should      /* we restore the process signal mask as the sigreturn should
Line 1048  static inline int handle_cpu_signal(unsi Line 982  static inline int handle_cpu_signal(unsi
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 1056  static inline int handle_cpu_signal(unsi Line 990  static inline int handle_cpu_signal(unsi
         return 1;          return 1;
     }      }
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);      ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 1083  static inline int handle_cpu_signal(unsi Line 1017  static inline int handle_cpu_signal(unsi
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
     int ret;      int ret;
       
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 1096  static inline int handle_cpu_signal(unsi Line 1030  static inline int handle_cpu_signal(unsi
     }      }
   
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);      ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 1111  static inline int handle_cpu_signal(unsi Line 1045  static inline int handle_cpu_signal(unsi
     }      }
     if (ret == 1) {      if (ret == 1) {
 #if 0  #if 0
         printf("PF exception: NIP=0x%08x error=0x%x %p\n",           printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
                env->nip, env->error_code, tb);                 env->PC, env->error_code, tb);
 #endif  #endif
     /* we restore the process signal mask as the sigreturn should      /* we restore the process signal mask as the sigreturn should
        do it (XXX: use sigsetjmp) */         do it (XXX: use sigsetjmp) */
Line 1133  static inline int handle_cpu_signal(unsi Line 1067  static inline int handle_cpu_signal(unsi
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
     int ret;      int ret;
       
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
Line 1146  static inline int handle_cpu_signal(unsi Line 1080  static inline int handle_cpu_signal(unsi
     }      }
   
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
     ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);      ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)      if (ret < 0)
         return 0; /* not an MMU fault */          return 0; /* not an MMU fault */
     if (ret == 0)      if (ret == 0)
Line 1160  static inline int handle_cpu_signal(unsi Line 1094  static inline int handle_cpu_signal(unsi
         cpu_restore_state(tb, env, pc, puc);          cpu_restore_state(tb, env, pc, puc);
     }      }
 #if 0  #if 0
         printf("PF exception: NIP=0x%08x error=0x%x %p\n",           printf("PF exception: NIP=0x%08x error=0x%x %p\n",
                env->nip, env->error_code, tb);                 env->nip, env->error_code, tb);
 #endif  #endif
     /* we restore the process signal mask as the sigreturn should      /* we restore the process signal mask as the sigreturn should
Line 1170  static inline int handle_cpu_signal(unsi Line 1104  static inline int handle_cpu_signal(unsi
     /* never comes here */      /* never comes here */
     return 1;      return 1;
 }  }
 #else  
 #error unsupported target CPU  
 #endif  
   
 #if defined(__i386__)  
   
 #if defined(__APPLE__)  #elif defined (TARGET_ALPHA)
 # include <sys/ucontext.h>  static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
                                       int is_write, sigset_t *old_set,
                                       void *puc)
   {
       TranslationBlock *tb;
       int ret;
   
 # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))      if (cpu_single_env)
 # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)          env = cpu_single_env; /* XXX: find a correct solution for multithread */
 # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)  #if defined(DEBUG_SIGNAL)
 #else      printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
 # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])             pc, address, is_write, *(unsigned long *)old_set);
 # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])  
 # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])  
 #endif  #endif
       /* XXX: locking issue */
       if (is_write && page_unprotect(h2g(address), pc, puc)) {
           return 1;
       }
   
 #if defined(USE_CODE_COPY)      /* see if it is an MMU fault */
 static void cpu_send_trap(unsigned long pc, int trap,       ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
                           struct ucontext *uc)      if (ret < 0)
           return 0; /* not an MMU fault */
       if (ret == 0)
           return 1; /* the MMU fault was handled without causing real CPU fault */
   
       /* now we have a real cpu fault */
       tb = tb_find_pc(pc);
       if (tb) {
           /* the PC is inside the translated code. It means that we have
              a virtual CPU fault */
           cpu_restore_state(tb, env, pc, puc);
       }
   #if 0
           printf("PF exception: NIP=0x%08x error=0x%x %p\n",
                  env->nip, env->error_code, tb);
   #endif
       /* we restore the process signal mask as the sigreturn should
          do it (XXX: use sigsetjmp) */
       sigprocmask(SIG_SETMASK, old_set, NULL);
       cpu_loop_exit();
       /* never comes here */
       return 1;
   }
   #elif defined (TARGET_CRIS)
   static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
                                       int is_write, sigset_t *old_set,
                                       void *puc)
 {  {
     TranslationBlock *tb;      TranslationBlock *tb;
       int ret;
   
     if (cpu_single_env)      if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */          env = cpu_single_env; /* XXX: find a correct solution for multithread */
   #if defined(DEBUG_SIGNAL)
       printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
              pc, address, is_write, *(unsigned long *)old_set);
   #endif
       /* XXX: locking issue */
       if (is_write && page_unprotect(h2g(address), pc, puc)) {
           return 1;
       }
   
       /* see if it is an MMU fault */
       ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
       if (ret < 0)
           return 0; /* not an MMU fault */
       if (ret == 0)
           return 1; /* the MMU fault was handled without causing real CPU fault */
   
     /* now we have a real cpu fault */      /* now we have a real cpu fault */
     tb = tb_find_pc(pc);      tb = tb_find_pc(pc);
     if (tb) {      if (tb) {
         /* the PC is inside the translated code. It means that we have          /* the PC is inside the translated code. It means that we have
            a virtual CPU fault */             a virtual CPU fault */
         cpu_restore_state(tb, env, pc, uc);          cpu_restore_state(tb, env, pc, puc);
     }      }
     sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);  #if 0
     raise_exception_err(trap, env->error_code);          printf("PF exception: NIP=0x%08x error=0x%x %p\n",
                  env->nip, env->error_code, tb);
   #endif
       /* we restore the process signal mask as the sigreturn should
          do it (XXX: use sigsetjmp) */
       sigprocmask(SIG_SETMASK, old_set, NULL);
       cpu_loop_exit();
       /* never comes here */
       return 1;
 }  }
   
   #else
   #error unsupported target CPU
 #endif  #endif
   
 int cpu_signal_handler(int host_signum, void *pinfo,   #if defined(__i386__)
   
   #if defined(__APPLE__)
   # include <sys/ucontext.h>
   
   # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
   # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
   # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
   #else
   # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
   # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
   # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
   #endif
   
   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
Line 1224  int cpu_signal_handler(int host_signum,  Line 1228  int cpu_signal_handler(int host_signum, 
 #endif  #endif
     pc = EIP_sig(uc);      pc = EIP_sig(uc);
     trapno = TRAP_sig(uc);      trapno = TRAP_sig(uc);
 #if defined(TARGET_I386) && defined(USE_CODE_COPY)      return handle_cpu_signal(pc, (unsigned long)info->si_addr,
     if (trapno == 0x00 || trapno == 0x05) {                               trapno == 0xe ?
         /* send division by zero or bound exception */                               (ERROR_sig(uc) >> 1) & 1 : 0,
         cpu_send_trap(pc, trapno, uc);                               &uc->uc_sigmask, puc);
         return 1;  
     } else  
 #endif  
         return handle_cpu_signal(pc, (unsigned long)info->si_addr,   
                                  trapno == 0xe ?   
                                  (ERROR_sig(uc) >> 1) & 1 : 0,  
                                  &uc->uc_sigmask, puc);  
 }  }
   
 #elif defined(__x86_64__)  #elif defined(__x86_64__)
Line 1247  int cpu_signal_handler(int host_signum,  Line 1244  int cpu_signal_handler(int host_signum, 
     unsigned long pc;      unsigned long pc;
   
     pc = uc->uc_mcontext.gregs[REG_RIP];      pc = uc->uc_mcontext.gregs[REG_RIP];
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?                                uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
                              (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,                               (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
                              &uc->uc_sigmask, puc);                               &uc->uc_sigmask, puc);
 }  }
Line 1304  typedef struct ucontext SIGCONTEXT; Line 1301  typedef struct ucontext SIGCONTEXT;
 # define TRAP_sig(context)                      EXCEPREG_sig(exception, context) /* number of powerpc exception taken */  # define TRAP_sig(context)                      EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
 #endif /* __APPLE__ */  #endif /* __APPLE__ */
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
Line 1322  int cpu_signal_handler(int host_signum,  Line 1319  int cpu_signal_handler(int host_signum, 
     if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))      if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
         is_write = 1;          is_write = 1;
 #endif  #endif
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write, &uc->uc_sigmask, puc);                               is_write, &uc->uc_sigmask, puc);
 }  }
   
 #elif defined(__alpha__)  #elif defined(__alpha__)
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                            void *puc)                             void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
Line 1353  int cpu_signal_handler(int host_signum,  Line 1350  int cpu_signal_handler(int host_signum, 
         is_write = 1;          is_write = 1;
     }      }
   
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write, &uc->uc_sigmask, puc);                               is_write, &uc->uc_sigmask, puc);
 }  }
 #elif defined(__sparc__)  #elif defined(__sparc__)
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
Line 1367  int cpu_signal_handler(int host_signum,  Line 1364  int cpu_signal_handler(int host_signum, 
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
     uint32_t insn;      uint32_t insn;
       
     /* XXX: is there a standard glibc define ? */      /* XXX: is there a standard glibc define ? */
     pc = regs[1];      pc = regs[1];
     /* XXX: need kernel patch to get write flag faster */      /* XXX: need kernel patch to get write flag faster */
Line 1386  int cpu_signal_handler(int host_signum,  Line 1383  int cpu_signal_handler(int host_signum, 
         break;          break;
       }        }
     }      }
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write, sigmask, NULL);                               is_write, sigmask, NULL);
 }  }
   
 #elif defined(__arm__)  #elif defined(__arm__)
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
       
     pc = uc->uc_mcontext.gregs[R15];      pc = uc->uc_mcontext.gregs[R15];
     /* XXX: compute is_write */      /* XXX: compute is_write */
     is_write = 0;      is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write,                               is_write,
                              &uc->uc_sigmask, puc);                               &uc->uc_sigmask, puc);
 }  }
   
 #elif defined(__mc68000)  #elif defined(__mc68000)
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
       
     pc = uc->uc_mcontext.gregs[16];      pc = uc->uc_mcontext.gregs[16];
     /* XXX: compute is_write */      /* XXX: compute is_write */
     is_write = 0;      is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write,                               is_write,
                              &uc->uc_sigmask, puc);                               &uc->uc_sigmask, puc);
 }  }
Line 1462  int cpu_signal_handler(int host_signum,  Line 1459  int cpu_signal_handler(int host_signum, 
   
 #elif defined(__s390__)  #elif defined(__s390__)
   
 int cpu_signal_handler(int host_signum, void *pinfo,   int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
       
     pc = uc->uc_mcontext.psw.addr;      pc = uc->uc_mcontext.psw.addr;
     /* XXX: compute is_write */      /* XXX: compute is_write */
     is_write = 0;      is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write,                               is_write, &uc->uc_sigmask, puc);
                              &uc->uc_sigmask, puc);  }
   
   #elif defined(__mips__)
   
   int cpu_signal_handler(int host_signum, void *pinfo,
                          void *puc)
   {
       siginfo_t *info = pinfo;
       struct ucontext *uc = puc;
       greg_t pc = uc->uc_mcontext.pc;
       int is_write;
   
       /* XXX: compute is_write */
       is_write = 0;
       return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                                is_write, &uc->uc_sigmask, puc);
 }  }
   
 #else  #else

Removed from v.1.1.1.5  
changed lines
  Added in v.1.1.1.6


unix.superglobalmegacorp.com