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

version 1.1.1.1, 2018/04/24 16:37:52 version 1.1.1.2, 2018/04/24 16:38:19
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);
 }  }
   
   
   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)
   {
       TranslationBlock *tb;
       target_ulong cs_base, pc;
       unsigned int flags;
   
       /* 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)
       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);
       if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
           flags |= (1 << 6);
       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 | MIPS_HFLAG_BMASK);
       cs_base = 0;
       pc = env->PC;
   #else
   #error unsupported CPU
   #endif
       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 */  /* main execution loop */
   
 int cpu_exec(CPUState *env1)  int cpu_exec(CPUState *env1)
Line 115  int cpu_exec(CPUState *env1) Line 250  int cpu_exec(CPUState *env1)
 #ifdef __sparc__  #ifdef __sparc__
     int saved_i7, tmp_T0;      int saved_i7, 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;      saved_env = env;
Line 168  int cpu_exec(CPUState *env1) Line 355  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;
Line 225  int cpu_exec(CPUState *env1) Line 403  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);
 #endif  #endif
                 }                  }
                 env->exception_index = -1;                  env->exception_index = -1;
Line 290  int cpu_exec(CPUState *env1) Line 470  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)) {  #ifdef __sparc__
                             /* 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;
                         }  #ifdef __sparc__
                               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 316  int cpu_exec(CPUState *env1) Line 506  int cpu_exec(CPUState *env1)
                         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;
   #ifdef __sparc__
                           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 524  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;
   #ifdef __sparc__
                               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) {
                           env1->halted = 1;
                           return EXCP_HALTED;
                       }
   #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);
                       }
 #endif  #endif
                     if (interrupt_request & CPU_INTERRUPT_EXITTB) {                      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 */
Line 352  int cpu_exec(CPUState *env1) Line 566  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 597  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;
Line 399  int cpu_exec(CPUState *env1) Line 611  int cpu_exec(CPUState *env1)
 #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 526  int cpu_exec(CPUState *env1) Line 622  int cpu_exec(CPUState *env1)
 #ifdef __sparc__  #ifdef __sparc__
                 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 &&
                           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 699  int cpu_exec(CPUState *env1) Line 798  int cpu_exec(CPUState *env1)
     EDI = saved_EDI;      EDI = saved_EDI;
 #endif  #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)
Line 719  int cpu_exec(CPUState *env1) Line 817  int cpu_exec(CPUState *env1)
     T2 = saved_T2;      T2 = saved_T2;
 #endif  #endif
     env = saved_env;      env = saved_env;
       /* fail safe : never use cpu_single_env outside cpu_exec() */
       cpu_single_env = NULL; 
     return ret;      return ret;
 }  }
   
Line 827  static inline int handle_cpu_signal(unsi Line 927  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 979  static inline int handle_cpu_signal(unsi Line 1079  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_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)

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


unix.superglobalmegacorp.com