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

version 1.1.1.1, 2018/04/24 16:37:52 version 1.1.1.5, 2018/04/24 16:44:47
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)  #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K)
 /* XXX: unify with i386 target */  /* XXX: unify with i386 target */
 void cpu_loop_exit(void)  void cpu_loop_exit(void)
 {  {
     longjmp(env->jmp_env, 1);      longjmp(env->jmp_env, 1);
 }  }
 #endif  #endif
 #ifndef TARGET_SPARC  #if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
 #define reg_T2  #define reg_T2
 #endif  #endif
   
Line 73  void cpu_resume_from_signal(CPUState *en Line 73  void cpu_resume_from_signal(CPUState *en
     longjmp(env->jmp_env, 1);      longjmp(env->jmp_env, 1);
 }  }
   
 /* main execution loop */  
   
 int cpu_exec(CPUState *env1)  static TranslationBlock *tb_find_slow(target_ulong pc,
                                         target_ulong cs_base,
                                         unsigned int flags)
   {
       TranslationBlock *tb, **ptb1;
       int code_gen_size;
       unsigned int h;
       target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
       uint8_t *tc_ptr;
       
       spin_lock(&tb_lock);
   
       tb_invalidated_flag = 0;
       
       regs_to_env(); /* XXX: do it just before cpu_gen_code() */
       
       /* find translated block using physical mappings */
       phys_pc = get_phys_addr_code(env, pc);
       phys_page1 = phys_pc & TARGET_PAGE_MASK;
       phys_page2 = -1;
       h = tb_phys_hash_func(phys_pc);
       ptb1 = &tb_phys_hash[h];
       for(;;) {
           tb = *ptb1;
           if (!tb)
               goto not_found;
           if (tb->pc == pc && 
               tb->page_addr[0] == phys_page1 &&
               tb->cs_base == cs_base && 
               tb->flags == flags) {
               /* check next page if needed */
               if (tb->page_addr[1] != -1) {
                   virt_page2 = (pc & TARGET_PAGE_MASK) + 
                       TARGET_PAGE_SIZE;
                   phys_page2 = get_phys_addr_code(env, virt_page2);
                   if (tb->page_addr[1] == phys_page2)
                       goto found;
               } else {
                   goto found;
               }
           }
           ptb1 = &tb->phys_hash_next;
       }
    not_found:
       /* if no translated code available, then translate it now */
       tb = tb_alloc(pc);
       if (!tb) {
           /* flush must be done */
           tb_flush(env);
           /* cannot fail at this point */
           tb = tb_alloc(pc);
           /* don't forget to invalidate previous TB info */
           tb_invalidated_flag = 1;
       }
       tc_ptr = code_gen_ptr;
       tb->tc_ptr = tc_ptr;
       tb->cs_base = cs_base;
       tb->flags = flags;
       cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
       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 */
       virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
       phys_page2 = -1;
       if ((pc & TARGET_PAGE_MASK) != virt_page2) {
           phys_page2 = get_phys_addr_code(env, virt_page2);
       }
       tb_link_phys(tb, phys_pc, phys_page2);
       
    found:
       /* we add the TB in the virtual pc hash table */
       env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
       spin_unlock(&tb_lock);
       return tb;
   }
   
   static inline TranslationBlock *tb_find_fast(void)
 {  {
     int saved_T0, saved_T1;      TranslationBlock *tb;
 #if defined(reg_T2)      target_ulong cs_base, pc;
     int saved_T2;      unsigned int flags;
 #endif  
     CPUState *saved_env;      /* we record a subset of the CPU state. It will
          always be the same before a given translated block
          is executed. */
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
 #ifdef reg_EAX      flags = env->hflags;
     int saved_EAX;      flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
 #endif      cs_base = env->segs[R_CS].base;
 #ifdef reg_ECX      pc = cs_base + env->eip;
     int saved_ECX;  #elif defined(TARGET_ARM)
 #endif      flags = env->thumb | (env->vfp.vec_len << 1)
 #ifdef reg_EDX              | (env->vfp.vec_stride << 4);
     int saved_EDX;      if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
 #endif          flags |= (1 << 6);
 #ifdef reg_EBX      if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
     int saved_EBX;          flags |= (1 << 7);
 #endif      cs_base = 0;
 #ifdef reg_ESP      pc = env->regs[15];
     int saved_ESP;  #elif defined(TARGET_SPARC)
 #endif  #ifdef TARGET_SPARC64
 #ifdef reg_EBP      // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
     int saved_EBP;      flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
 #endif          | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
 #ifdef reg_ESI  #else
     int saved_ESI;      // FPU enable . MMU enabled . MMU no-fault . Supervisor
       flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
           | env->psrs;
 #endif  #endif
 #ifdef reg_EDI      cs_base = env->npc;
     int saved_EDI;      pc = env->pc;
   #elif defined(TARGET_PPC)
       flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |
           (msr_se << MSR_SE) | (msr_le << MSR_LE);
       cs_base = 0;
       pc = env->nip;
   #elif defined(TARGET_MIPS)
       flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
       cs_base = 0;
       pc = env->PC;
   #elif defined(TARGET_M68K)
       flags = env->fpcr & M68K_FPCR_PREC;
       cs_base = 0;
       pc = env->pc;
   #elif defined(TARGET_SH4)
       flags = env->sr & (SR_MD | SR_RB);
       cs_base = 0;         /* XXXXX */
       pc = env->pc;
   #else
   #error unsupported CPU
 #endif  #endif
 #elif defined(TARGET_SPARC)      tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
       if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                            tb->flags != flags, 0)) {
           tb = tb_find_slow(pc, cs_base, flags);
           /* Note: we do it here to avoid a gcc bug on Mac OS X when
              doing it in tb_find_slow */
           if (tb_invalidated_flag) {
               /* as some TB could have been invalidated because
                  of memory exceptions while generating the code, we
                  must recompute the hash index here */
               T0 = 0;
           }
       }
       return tb;
   }
   
   
   /* main execution loop */
   
   int cpu_exec(CPUState *env1)
   {
   #define DECLARE_HOST_REGS 1
   #include "hostregs_helper.h"
   #if defined(TARGET_SPARC)
 #if defined(reg_REGWPTR)  #if defined(reg_REGWPTR)
     uint32_t *saved_regwptr;      uint32_t *saved_regwptr;
 #endif  #endif
 #endif  #endif
 #ifdef __sparc__  #if defined(__sparc__) && !defined(HOST_SOLARIS)
     int saved_i7, tmp_T0;      int saved_i7;
       target_ulong tmp_T0;
 #endif  #endif
     int code_gen_size, ret, interrupt_request;      int ret, interrupt_request;
     void (*gen_func)(void);      void (*gen_func)(void);
     TranslationBlock *tb, **ptb;      TranslationBlock *tb;
     target_ulong cs_base, pc;  
     uint8_t *tc_ptr;      uint8_t *tc_ptr;
     unsigned int flags;  
   #if defined(TARGET_I386)
       /* handle exit of HALTED state */
       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; 
   
     /* first we save global registers */      /* first we save global registers */
     saved_env = env;  #define SAVE_HOST_REGS 1
   #include "hostregs_helper.h"
     env = env1;      env = env1;
     saved_T0 = T0;  #if defined(__sparc__) && !defined(HOST_SOLARIS)
     saved_T1 = T1;  
 #if defined(reg_T2)  
     saved_T2 = T2;  
 #endif  
 #ifdef __sparc__  
     /* we also save i7 because longjmp may not restore it */      /* we also save i7 because longjmp may not restore it */
     asm volatile ("mov %%i7, %0" : "=r" (saved_i7));      asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
 #endif  #endif
   
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
 #ifdef reg_EAX  
     saved_EAX = EAX;  
 #endif  
 #ifdef reg_ECX  
     saved_ECX = ECX;  
 #endif  
 #ifdef reg_EDX  
     saved_EDX = EDX;  
 #endif  
 #ifdef reg_EBX  
     saved_EBX = EBX;  
 #endif  
 #ifdef reg_ESP  
     saved_ESP = ESP;  
 #endif  
 #ifdef reg_EBP  
     saved_EBP = EBP;  
 #endif  
 #ifdef reg_ESI  
     saved_ESI = ESI;  
 #endif  
 #ifdef reg_EDI  
     saved_EDI = EDI;  
 #endif  
   
     env_to_regs();      env_to_regs();
     /* 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);
Line 168  int cpu_exec(CPUState *env1) Line 313  int cpu_exec(CPUState *env1)
     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_ARM)
     {  
         unsigned int psr;  
         psr = env->cpsr;  
         env->CF = (psr >> 29) & 1;  
         env->NZF = (psr & 0xc0000000) ^ 0x40000000;  
         env->VF = (psr << 3) & 0x80000000;  
         env->QF = (psr >> 27) & 1;  
         env->cpsr = psr & ~CACHED_CPSR_BITS;  
     }  
 #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_PPC)
   #elif defined(TARGET_M68K)
       env->cc_op = CC_OP_FLAGS;
       env->cc_dest = env->sr & 0xf;
       env->cc_x = (env->sr >> 4) & 1;
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
   #elif defined(TARGET_SH4)
       /* XXXXX */
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
 #endif  #endif
Line 200  int cpu_exec(CPUState *env1) Line 342  int cpu_exec(CPUState *env1)
                     break;                      break;
                 } else if (env->user_mode_only) {                  } else if (env->user_mode_only) {
                     /* if user mode only, we simulate a fake exception                      /* if user mode only, we simulate a fake exception
                        which will be hanlded 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, 
Line 225  int cpu_exec(CPUState *env1) Line 367  int cpu_exec(CPUState *env1)
                     do_interrupt(env);                      do_interrupt(env);
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
                     do_interrupt(env->exception_index);                      do_interrupt(env->exception_index);
   #elif defined(TARGET_ARM)
                       do_interrupt(env);
   #elif defined(TARGET_SH4)
                       do_interrupt(env);
 #endif  #endif
                 }                  }
                 env->exception_index = -1;                  env->exception_index = -1;
Line 257  int cpu_exec(CPUState *env1) Line 403  int cpu_exec(CPUState *env1)
   
             T0 = 0; /* force lookup of first TB */              T0 = 0; /* force lookup of first TB */
             for(;;) {              for(;;) {
 #ifdef __sparc__  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                 /* g1 can be modified by some libc? functions */                   /* g1 can be modified by some libc? functions */ 
                 tmp_T0 = T0;                  tmp_T0 = T0;
 #endif        #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)  #if defined(TARGET_I386)
                     /* if hardware interrupt pending, we execute it */                      if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                          !(env->hflags & HF_SMM_MASK)) {
                           env->interrupt_request &= ~CPU_INTERRUPT_SMI;
                           do_smm_enter();
   #if defined(__sparc__) && !defined(HOST_SOLARIS)
                           tmp_T0 = 0;
   #else
                           T0 = 0;
   #endif
                       } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->eflags & IF_MASK) &&                           (env->eflags & IF_MASK) && 
                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {                          !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                         int intno;                          int intno;
Line 277  int cpu_exec(CPUState *env1) Line 431  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 */
 #ifdef __sparc__  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;                          tmp_T0 = 0;
 #else  #else
                         T0 = 0;                          T0 = 0;
Line 290  int cpu_exec(CPUState *env1) Line 444  int cpu_exec(CPUState *env1)
                     }                      }
 #endif  #endif
                     if (msr_ee != 0) {                      if (msr_ee != 0) {
                     if ((interrupt_request & CPU_INTERRUPT_HARD)) {                          if ((interrupt_request & CPU_INTERRUPT_HARD)) {
                             /* Raise it */                              /* Raise it */
                             env->exception_index = EXCP_EXTERNAL;                              env->exception_index = EXCP_EXTERNAL;
                             env->error_code = 0;                              env->error_code = 0;
                             do_interrupt(env);                              do_interrupt(env);
                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;                              env->interrupt_request &= ~CPU_INTERRUPT_HARD;
                         } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                             /* Raise it */                              tmp_T0 = 0;
                             env->exception_index = EXCP_DECR;  #else
                             env->error_code = 0;                              T0 = 0;
                             do_interrupt(env);  #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;                              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) &&
Line 315  int cpu_exec(CPUState *env1) Line 479  int cpu_exec(CPUState *env1)
                         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);
                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                           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 329  int cpu_exec(CPUState *env1) Line 497  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)
                               tmp_T0 = 0;
   #else
                               T0 = 0;
   #endif
                         }                          }
                     } 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)
                       if (interrupt_request & CPU_INTERRUPT_FIQ
                           && !(env->uncached_cpsr & CPSR_F)) {
                           env->exception_index = EXCP_FIQ;
                           do_interrupt(env);
                       }
                       if (interrupt_request & CPU_INTERRUPT_HARD
                           && !(env->uncached_cpsr & CPSR_I)) {
                           env->exception_index = EXCP_IRQ;
                           do_interrupt(env);
                       }
   #elif defined(TARGET_SH4)
                       /* XXXXX */
 #endif  #endif
                     if (interrupt_request & CPU_INTERRUPT_EXITTB) {                     /* Don't use the cached interupt_request value,
                         do_interrupt may have updated the EXITTB flag. */
                       if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
                         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 */
 #ifdef __sparc__  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;                          tmp_T0 = 0;
 #else  #else
                         T0 = 0;                          T0 = 0;
Line 352  int cpu_exec(CPUState *env1) Line 545  int cpu_exec(CPUState *env1)
                     }                      }
                 }                  }
 #ifdef DEBUG_EXEC  #ifdef DEBUG_EXEC
                 if ((loglevel & CPU_LOG_EXEC)) {                  if ((loglevel & CPU_LOG_TB_CPU)) {
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
                     /* restore flags in standard format */                      /* restore flags in standard format */
 #ifdef reg_EAX  #ifdef reg_EAX
Line 383  int cpu_exec(CPUState *env1) Line 576  int cpu_exec(CPUState *env1)
                     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);
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
                     env->cpsr = compute_cpsr();  
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
                     env->cpsr &= ~CACHED_CPSR_BITS;  
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
                     REGWPTR = env->regbase + (env->cwp * 16);                      REGWPTR = env->regbase + (env->cwp * 16);
                     env->regwptr = REGWPTR;                      env->regwptr = REGWPTR;
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
   #elif defined(TARGET_M68K)
                       cpu_m68k_flush_flags(env, env->cc_op);
                       env->cc_op = CC_OP_FLAGS;
                       env->sr = (env->sr & 0xffe0)
                                 | env->cc_dest | (env->cc_x << 4);
                       cpu_dump_state(env, logfile, fprintf, 0);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
                     cpu_dump_state(env, logfile, fprintf, 0);                      cpu_dump_state(env, logfile, fprintf, 0);
   #elif defined(TARGET_SH4)
                       cpu_dump_state(env, logfile, fprintf, 0);
 #else  #else
 #error unsupported target CPU   #error unsupported target CPU 
 #endif  #endif
                 }                  }
 #endif  #endif
                 /* we record a subset of the CPU state. It will                  tb = tb_find_fast();
                    always be the same before a given translated block  
                    is executed. */  
 #if defined(TARGET_I386)  
                 flags = env->hflags;  
                 flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));  
                 cs_base = env->segs[R_CS].base;  
                 pc = cs_base + env->eip;  
 #elif defined(TARGET_ARM)  
                 flags = env->thumb | (env->vfp.vec_len << 1)  
                         | (env->vfp.vec_stride << 4);  
                 cs_base = 0;  
                 pc = env->regs[15];  
 #elif defined(TARGET_SPARC)  
 #ifdef TARGET_SPARC64  
                 flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);  
 #else  
                 flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);  
 #endif  
                 cs_base = env->npc;  
                 pc = env->pc;  
 #elif defined(TARGET_PPC)  
                 flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |  
                     (msr_se << MSR_SE) | (msr_le << MSR_LE);  
                 cs_base = 0;  
                 pc = env->nip;  
 #elif defined(TARGET_MIPS)  
                 flags = env->hflags & MIPS_HFLAGS_TMASK;  
                 cs_base = NULL;  
                 pc = env->PC;  
 #else  
 #error unsupported CPU  
 #endif  
                 tb = tb_find(&ptb, pc, cs_base,   
                              flags);  
                 if (!tb) {  
                     TranslationBlock **ptb1;  
                     unsigned int h;  
                     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;  
                       
                       
                     spin_lock(&tb_lock);  
   
                     tb_invalidated_flag = 0;  
                       
                     regs_to_env(); /* XXX: do it just before cpu_gen_code() */  
   
                     /* find translated block using physical mappings */  
                     phys_pc = get_phys_addr_code(env, pc);  
                     phys_page1 = phys_pc & TARGET_PAGE_MASK;  
                     phys_page2 = -1;  
                     h = tb_phys_hash_func(phys_pc);  
                     ptb1 = &tb_phys_hash[h];  
                     for(;;) {  
                         tb = *ptb1;  
                         if (!tb)  
                             goto not_found;  
                         if (tb->pc == pc &&   
                             tb->page_addr[0] == phys_page1 &&  
                             tb->cs_base == cs_base &&   
                             tb->flags == flags) {  
                             /* check next page if needed */  
                             if (tb->page_addr[1] != -1) {  
                                 virt_page2 = (pc & TARGET_PAGE_MASK) +   
                                     TARGET_PAGE_SIZE;  
                                 phys_page2 = get_phys_addr_code(env, virt_page2);  
                                 if (tb->page_addr[1] == phys_page2)  
                                     goto found;  
                             } else {  
                                 goto found;  
                             }  
                         }  
                         ptb1 = &tb->phys_hash_next;  
                     }  
                 not_found:  
                     /* if no translated code available, then translate it now */  
                     tb = tb_alloc(pc);  
                     if (!tb) {  
                         /* flush must be done */  
                         tb_flush(env);  
                         /* cannot fail at this point */  
                         tb = tb_alloc(pc);  
                         /* don't forget to invalidate previous TB info */  
                         ptb = &tb_hash[tb_hash_func(pc)];  
                         T0 = 0;  
                     }  
                     tc_ptr = code_gen_ptr;  
                     tb->tc_ptr = tc_ptr;  
                     tb->cs_base = cs_base;  
                     tb->flags = flags;  
                     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);  
                     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 */  
                     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;  
                     phys_page2 = -1;  
                     if ((pc & TARGET_PAGE_MASK) != virt_page2) {  
                         phys_page2 = get_phys_addr_code(env, virt_page2);  
                     }  
                     tb_link_phys(tb, phys_pc, phys_page2);  
   
                 found:  
                     if (tb_invalidated_flag) {  
                         /* as some TB could have been invalidated because  
                            of memory exceptions while generating the code, we  
                            must recompute the hash index here */  
                         ptb = &tb_hash[tb_hash_func(pc)];  
                         while (*ptb != NULL)  
                             ptb = &(*ptb)->hash_next;  
                         T0 = 0;  
                     }  
                     /* we add the TB in the virtual pc hash table */  
                     *ptb = tb;  
                     tb->hash_next = NULL;  
                     tb_link(tb);  
                     spin_unlock(&tb_lock);  
                 }  
 #ifdef DEBUG_EXEC  #ifdef DEBUG_EXEC
                 if ((loglevel & CPU_LOG_EXEC)) {                  if ((loglevel & CPU_LOG_EXEC)) {
                     fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",                      fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
Line 523  int cpu_exec(CPUState *env1) Line 606  int cpu_exec(CPUState *env1)
                             lookup_symbol(tb->pc));                              lookup_symbol(tb->pc));
                 }                  }
 #endif  #endif
 #ifdef __sparc__  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                 T0 = tmp_T0;                  T0 = tmp_T0;
 #endif        #endif      
                 /* see if we can patch the calling TB. */                  /* see if we can patch the calling TB. When the TB
                      spans two pages, we cannot safely do a direct
                      jump. */
                 {                  {
                     if (T0 != 0                      if (T0 != 0 &&
   #if USE_KQEMU
                           (env->kqemu_enabled != 2) &&
   #endif
                           tb->page_addr[1] == -1
 #if defined(TARGET_I386) && defined(USE_CODE_COPY)  #if defined(TARGET_I386) && defined(USE_CODE_COPY)
                     && (tb->cflags & CF_CODE_COPY) ==                       && (tb->cflags & CF_CODE_COPY) == 
                     (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)                      (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)
Line 553  int cpu_exec(CPUState *env1) Line 642  int cpu_exec(CPUState *env1)
                                      "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",
                                          "l0", "l1", "l2", "l3", "l4", "l5",
                                          "l6", "l7");
 #elif defined(__arm__)  #elif defined(__arm__)
                 asm volatile ("mov pc, %0\n\t"                  asm volatile ("mov pc, %0\n\t"
                               ".global exec_loop\n\t"                                ".global exec_loop\n\t"
Line 657  int cpu_exec(CPUState *env1) Line 748  int cpu_exec(CPUState *env1)
                     T0 = 0;                      T0 = 0;
                 }                  }
 #endif  #endif
   #if defined(USE_KQEMU)
   #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
                   if (kqemu_is_ok(env) &&
                       (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
                       cpu_loop_exit();
                   }
   #endif
             }              }
         } else {          } else {
             env_to_regs();              env_to_regs();
Line 672  int cpu_exec(CPUState *env1) Line 770  int cpu_exec(CPUState *env1)
 #endif  #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);
   
     /* restore global registers */  
 #ifdef reg_EAX  
     EAX = saved_EAX;  
 #endif  
 #ifdef reg_ECX  
     ECX = saved_ECX;  
 #endif  
 #ifdef reg_EDX  
     EDX = saved_EDX;  
 #endif  
 #ifdef reg_EBX  
     EBX = saved_EBX;  
 #endif  
 #ifdef reg_ESP  
     ESP = saved_ESP;  
 #endif  
 #ifdef reg_EBP  
     EBP = saved_EBP;  
 #endif  
 #ifdef reg_ESI  
     ESI = saved_ESI;  
 #endif  
 #ifdef reg_EDI  
     EDI = saved_EDI;  
 #endif  
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
     env->cpsr = compute_cpsr();  
     /* XXX: Save/restore host fpu exception state?.  */      /* XXX: Save/restore host fpu exception state?.  */
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
 #if defined(reg_REGWPTR)  #if defined(reg_REGWPTR)
     REGWPTR = saved_regwptr;      REGWPTR = saved_regwptr;
 #endif  #endif
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
   #elif defined(TARGET_M68K)
       cpu_m68k_flush_flags(env, env->cc_op);
       env->cc_op = CC_OP_FLAGS;
       env->sr = (env->sr & 0xffe0)
                 | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
   #elif defined(TARGET_SH4)
       /* XXXXX */
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
 #endif  #endif
 #ifdef __sparc__  
       /* restore global registers */
   #if defined(__sparc__) && !defined(HOST_SOLARIS)
     asm volatile ("mov %0, %%i7" : : "r" (saved_i7));      asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
 #endif  #endif
     T0 = saved_T0;  #include "hostregs_helper.h"
     T1 = saved_T1;  
 #if defined(reg_T2)      /* fail safe : never use cpu_single_env outside cpu_exec() */
     T2 = saved_T2;      cpu_single_env = NULL; 
 #endif  
     env = saved_env;  
     return ret;      return ret;
 }  }
   
Line 801  static inline int handle_cpu_signal(unsi Line 879  static inline int handle_cpu_signal(unsi
                 pc, address, is_write, *(unsigned long *)old_set);                  pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {      if (is_write && page_unprotect(h2g(address), pc, puc)) {
         return 1;          return 1;
     }      }
   
Line 827  static inline int handle_cpu_signal(unsi Line 905  static inline int handle_cpu_signal(unsi
         /* 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) */
         sigprocmask(SIG_SETMASK, old_set, NULL);          sigprocmask(SIG_SETMASK, old_set, NULL);
         raise_exception_err(EXCP0E_PAGE, env->error_code);          raise_exception_err(env->exception_index, env->error_code);
     } else {      } else {
         /* activate soft MMU for this block */          /* activate soft MMU for this block */
         env->hflags |= HF_SOFTMMU_MASK;          env->hflags |= HF_SOFTMMU_MASK;
Line 852  static inline int handle_cpu_signal(unsi Line 930  static inline int handle_cpu_signal(unsi
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {      if (is_write && page_unprotect(h2g(address), pc, puc)) {
         return 1;          return 1;
     }      }
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
Line 888  static inline int handle_cpu_signal(unsi Line 966  static inline int handle_cpu_signal(unsi
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {      if (is_write && page_unprotect(h2g(address), pc, puc)) {
         return 1;          return 1;
     }      }
     /* see if it is an MMU fault */      /* see if it is an MMU fault */
Line 924  static inline int handle_cpu_signal(unsi Line 1002  static inline int handle_cpu_signal(unsi
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {      if (is_write && page_unprotect(h2g(address), pc, puc)) {
         return 1;          return 1;
     }      }
   
Line 959  static inline int handle_cpu_signal(unsi Line 1037  static inline int handle_cpu_signal(unsi
     return 1;      return 1;
 }  }
   
   #elif defined(TARGET_M68K)
   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;
   
       if (cpu_single_env)
           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(address, pc, puc)) {
           return 1;
       }
       /* see if it is an MMU fault */
       ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 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 */
       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);
       }
       /* 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_MIPS)  #elif defined (TARGET_MIPS)
 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,
Line 974  static inline int handle_cpu_signal(unsi Line 1091  static inline int handle_cpu_signal(unsi
            pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
 #endif  #endif
     /* XXX: locking issue */      /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {      if (is_write && page_unprotect(h2g(address), pc, puc)) {
         return 1;          return 1;
     }      }
   
     /* 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_mips_handle_mmu_fault(env, address, is_write, 1, 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 1009  static inline int handle_cpu_signal(unsi Line 1126  static inline int handle_cpu_signal(unsi
     return 1;      return 1;
 }  }
   
   #elif defined (TARGET_SH4)
   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;
       
       if (cpu_single_env)
           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_sh4_handle_mmu_fault(env, address, is_write, 1, 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 */
       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;
   }
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
 #endif  #endif
   
 #if defined(__i386__)  #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
   
 #if defined(USE_CODE_COPY)  #if defined(USE_CODE_COPY)
 static void cpu_send_trap(unsigned long pc, int trap,   static void cpu_send_trap(unsigned long pc, int trap, 
                           struct ucontext *uc)                            struct ucontext *uc)
Line 1035  static void cpu_send_trap(unsigned long  Line 1208  static void cpu_send_trap(unsigned long 
 }  }
 #endif  #endif
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int trapno;      int trapno;
Line 1048  int cpu_signal_handler(int host_signum,  Line 1222  int cpu_signal_handler(int host_signum, 
 #define REG_ERR    ERR  #define REG_ERR    ERR
 #define REG_TRAPNO TRAPNO  #define REG_TRAPNO TRAPNO
 #endif  #endif
     pc = uc->uc_mcontext.gregs[REG_EIP];      pc = EIP_sig(uc);
     trapno = uc->uc_mcontext.gregs[REG_TRAPNO];      trapno = TRAP_sig(uc);
 #if defined(TARGET_I386) && defined(USE_CODE_COPY)  #if defined(TARGET_I386) && defined(USE_CODE_COPY)
     if (trapno == 0x00 || trapno == 0x05) {      if (trapno == 0x00 || trapno == 0x05) {
         /* send division by zero or bound exception */          /* send division by zero or bound exception */
Line 1059  int cpu_signal_handler(int host_signum,  Line 1233  int cpu_signal_handler(int host_signum, 
 #endif  #endif
         return handle_cpu_signal(pc, (unsigned long)info->si_addr,           return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
                                  trapno == 0xe ?                                    trapno == 0xe ? 
                                  (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,                                   (ERROR_sig(uc) >> 1) & 1 : 0,
                                  &uc->uc_sigmask, puc);                                   &uc->uc_sigmask, puc);
 }  }
   
 #elif defined(__x86_64__)  #elif defined(__x86_64__)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,  int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
   
Line 1129  typedef struct ucontext SIGCONTEXT; Line 1304  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, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
Line 1152  int cpu_signal_handler(int host_signum,  Line 1328  int cpu_signal_handler(int host_signum, 
   
 #elif defined(__alpha__)  #elif defined(__alpha__)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                            void *puc)                             void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     uint32_t *pc = uc->uc_mcontext.sc_pc;      uint32_t *pc = uc->uc_mcontext.sc_pc;
     uint32_t insn = *pc;      uint32_t insn = *pc;
Line 1181  int cpu_signal_handler(int host_signum,  Line 1358  int cpu_signal_handler(int host_signum, 
 }  }
 #elif defined(__sparc__)  #elif defined(__sparc__)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     uint32_t *regs = (uint32_t *)(info + 1);      uint32_t *regs = (uint32_t *)(info + 1);
     void *sigmask = (regs + 20);      void *sigmask = (regs + 20);
     unsigned long pc;      unsigned long pc;
Line 1214  int cpu_signal_handler(int host_signum,  Line 1392  int cpu_signal_handler(int host_signum, 
   
 #elif defined(__arm__)  #elif defined(__arm__)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
Line 1226  int cpu_signal_handler(int host_signum,  Line 1405  int cpu_signal_handler(int host_signum, 
     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);                               &uc->uc_sigmask, puc);
 }  }
   
 #elif defined(__mc68000)  #elif defined(__mc68000)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
Line 1251  int cpu_signal_handler(int host_signum,  Line 1431  int cpu_signal_handler(int host_signum, 
 #ifndef __ISR_VALID  #ifndef __ISR_VALID
   /* This ought to be in <bits/siginfo.h>... */    /* This ought to be in <bits/siginfo.h>... */
 # define __ISR_VALID    1  # define __ISR_VALID    1
 # define si_flags       _sifields._sigfault._si_pad0  
 #endif  #endif
   
 int cpu_signal_handler(int host_signum, struct siginfo *info, void *puc)  int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long ip;      unsigned long ip;
     int is_write = 0;      int is_write = 0;
Line 1267  int cpu_signal_handler(int host_signum,  Line 1447  int cpu_signal_handler(int host_signum, 
       case SIGSEGV:        case SIGSEGV:
       case SIGBUS:        case SIGBUS:
       case SIGTRAP:        case SIGTRAP:
           if (info->si_code && (info->si_flags & __ISR_VALID))            if (info->si_code && (info->si_segvflags & __ISR_VALID))
               /* ISR.W (write-access) is bit 33:  */                /* ISR.W (write-access) is bit 33:  */
               is_write = (info->si_isr >> 33) & 1;                is_write = (info->si_isr >> 33) & 1;
           break;            break;
Line 1282  int cpu_signal_handler(int host_signum,  Line 1462  int cpu_signal_handler(int host_signum, 
   
 #elif defined(__s390__)  #elif defined(__s390__)
   
 int cpu_signal_handler(int host_signum, struct siginfo *info,   int cpu_signal_handler(int host_signum, void *pinfo, 
                        void *puc)                         void *puc)
 {  {
       siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;

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


unix.superglobalmegacorp.com