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

version 1.1.1.4, 2018/04/24 16:42:36 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
 #if !(defined(TARGET_SPARC) || defined(TARGET_SH4))  #if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
 #define reg_T2  #define reg_T2
 #endif  #endif
   
Line 194  static inline TranslationBlock *tb_find_ Line 194  static inline TranslationBlock *tb_find_
     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;
   #elif defined(TARGET_M68K)
       flags = env->fpcr & M68K_FPCR_PREC;
       cs_base = 0;
       pc = env->pc;
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
     flags = env->sr & (SR_MD | SR_RB);      flags = env->sr & (SR_MD | SR_RB);
     cs_base = 0;         /* XXXXX */      cs_base = 0;         /* XXXXX */
Line 222  static inline TranslationBlock *tb_find_ Line 226  static inline TranslationBlock *tb_find_
   
 int cpu_exec(CPUState *env1)  int cpu_exec(CPUState *env1)
 {  {
     int saved_T0, saved_T1;  #define DECLARE_HOST_REGS 1
 #if defined(reg_T2)  #include "hostregs_helper.h"
     int saved_T2;  #if defined(TARGET_SPARC)
 #endif  
     CPUState *saved_env;  
 #if defined(TARGET_I386)  
 #ifdef reg_EAX  
     int saved_EAX;  
 #endif  
 #ifdef reg_ECX  
     int saved_ECX;  
 #endif  
 #ifdef reg_EDX  
     int saved_EDX;  
 #endif  
 #ifdef reg_EBX  
     int saved_EBX;  
 #endif  
 #ifdef reg_ESP  
     int saved_ESP;  
 #endif  
 #ifdef reg_EBP  
     int saved_EBP;  
 #endif  
 #ifdef reg_ESI  
     int saved_ESI;  
 #endif  
 #ifdef reg_EDI  
     int saved_EDI;  
 #endif  
 #elif defined(TARGET_SPARC)  
 #if defined(reg_REGWPTR)  #if defined(reg_REGWPTR)
     uint32_t *saved_regwptr;      uint32_t *saved_regwptr;
 #endif  #endif
 #endif  #endif
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  #if defined(__sparc__) && !defined(HOST_SOLARIS)
     int saved_i7, tmp_T0;      int saved_i7;
       target_ulong tmp_T0;
 #endif  #endif
     int ret, interrupt_request;      int ret, interrupt_request;
     void (*gen_func)(void);      void (*gen_func)(void);
Line 320  int cpu_exec(CPUState *env1) Line 297  int cpu_exec(CPUState *env1)
     cpu_single_env = env1;       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;  
     saved_T1 = T1;  
 #if defined(reg_T2)  
     saved_T2 = T2;  
 #endif  
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  #if defined(__sparc__) && !defined(HOST_SOLARIS)
     /* 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 370  int cpu_exec(CPUState *env1) Line 318  int cpu_exec(CPUState *env1)
     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)  #elif defined(TARGET_SH4)
     /* XXXXX */      /* XXXXX */
Line 390  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 458  int cpu_exec(CPUState *env1) Line 410  int cpu_exec(CPUState *env1)
                 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 519  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)  #if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;                          tmp_T0 = 0;
 #else  #else
Line 548  int cpu_exec(CPUState *env1) Line 507  int cpu_exec(CPUState *env1)
                         //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) {                      } else if (interrupt_request & CPU_INTERRUPT_HALT) {
                         env1->halted = 1;                          env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         return EXCP_HALTED;                          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
Line 622  int cpu_exec(CPUState *env1) Line 583  int cpu_exec(CPUState *env1)
                     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)  #elif defined(TARGET_SH4)
Line 803  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)
     /* XXX: Save/restore host fpu exception state?.  */      /* XXX: Save/restore host fpu exception state?.  */
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
Line 836  int cpu_exec(CPUState *env1) Line 777  int cpu_exec(CPUState *env1)
     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)  #elif defined(TARGET_SH4)
     /* XXXXX */      /* XXXXX */
 #else  #else
 #error unsupported target CPU  #error unsupported target CPU
 #endif  #endif
   
       /* restore global registers */
 #if defined(__sparc__) && !defined(HOST_SOLARIS)  #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)  
     T2 = saved_T2;  
 #endif  
     env = saved_env;  
     /* 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 1093  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 1193  static inline int handle_cpu_signal(unsi Line 1176  static inline int handle_cpu_signal(unsi
   
 #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 1213  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 1226  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 1237  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 1307  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 1330  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 1359  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 1392  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 1404  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 1431  int cpu_signal_handler(int host_signum,  Line 1433  int cpu_signal_handler(int host_signum, 
 # define __ISR_VALID    1  # define __ISR_VALID    1
 #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 1459  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.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com