/[qemu]/qemu/exec-i386.c
ViewVC logotype

Diff of /qemu/exec-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.27 by bellard, Mon Jun 2 20:38:09 2003 UTC revision 1.28 by bellard, Mon Jun 9 15:28:00 2003 UTC
# Line 25  Line 25 
25    
26  /* main execution loop */  /* main execution loop */
27    
 /* thread support */  
   
 spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;  
   
 void cpu_lock(void)  
 {  
     spin_lock(&global_cpu_lock);  
 }  
   
 void cpu_unlock(void)  
 {  
     spin_unlock(&global_cpu_lock);  
 }  
   
 void cpu_loop_exit(void)  
 {  
     /* NOTE: the register at this point must be saved by hand because  
        longjmp restore them */  
 #ifdef __sparc__  
         /* We have to stay in the same register window as our caller,  
          * thus this trick.  
          */  
         __asm__ __volatile__("restore\n\t"  
                              "mov\t%o0, %i0");  
 #endif  
 #ifdef reg_EAX  
     env->regs[R_EAX] = EAX;  
 #endif  
 #ifdef reg_ECX  
     env->regs[R_ECX] = ECX;  
 #endif  
 #ifdef reg_EDX  
     env->regs[R_EDX] = EDX;  
 #endif  
 #ifdef reg_EBX  
     env->regs[R_EBX] = EBX;  
 #endif  
 #ifdef reg_ESP  
     env->regs[R_ESP] = ESP;  
 #endif  
 #ifdef reg_EBP  
     env->regs[R_EBP] = EBP;  
 #endif  
 #ifdef reg_ESI  
     env->regs[R_ESI] = ESI;  
 #endif  
 #ifdef reg_EDI  
     env->regs[R_EDI] = EDI;  
 #endif  
     longjmp(env->jmp_env, 1);  
 }  
   
28  int cpu_x86_exec(CPUX86State *env1)  int cpu_x86_exec(CPUX86State *env1)
29  {  {
30      int saved_T0, saved_T1, saved_A0;      int saved_T0, saved_T1, saved_A0;
# Line 105  int cpu_x86_exec(CPUX86State *env1) Line 53  int cpu_x86_exec(CPUX86State *env1)
53  #ifdef reg_EDI  #ifdef reg_EDI
54      int saved_EDI;      int saved_EDI;
55  #endif  #endif
56    #ifdef __sparc__
57        int saved_i7, tmp_T0;
58    #endif
59      int code_gen_size, ret;      int code_gen_size, ret;
60      void (*gen_func)(void);      void (*gen_func)(void);
61      TranslationBlock *tb, **ptb;      TranslationBlock *tb, **ptb;
62      uint8_t *tc_ptr, *cs_base, *pc;      uint8_t *tc_ptr, *cs_base, *pc;
63      unsigned int flags;      unsigned int flags;
64        
65      /* first we save global registers */      /* first we save global registers */
66      saved_T0 = T0;      saved_T0 = T0;
67      saved_T1 = T1;      saved_T1 = T1;
# Line 149  int cpu_x86_exec(CPUX86State *env1) Line 100  int cpu_x86_exec(CPUX86State *env1)
100      saved_EDI = EDI;      saved_EDI = EDI;
101      EDI = env->regs[R_EDI];      EDI = env->regs[R_EDI];
102  #endif  #endif
103    #ifdef __sparc__
104        /* we also save i7 because longjmp may not restore it */
105        asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
106    #endif
107            
108      /* put eflags in CPU temporary format */      /* put eflags in CPU temporary format */
109      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 161  int cpu_x86_exec(CPUX86State *env1) Line 116  int cpu_x86_exec(CPUX86State *env1)
116      if (setjmp(env->jmp_env) == 0) {      if (setjmp(env->jmp_env) == 0) {
117          T0 = 0; /* force lookup of first TB */          T0 = 0; /* force lookup of first TB */
118          for(;;) {          for(;;) {
119    #ifdef __sparc__
120              /* g1 can be modified by some libc? functions */
121                tmp_T0 = T0;
122    #endif      
123              if (env->interrupt_request) {              if (env->interrupt_request) {
124                  env->exception_index = EXCP_INTERRUPT;                  env->exception_index = EXCP_INTERRUPT;
125                  cpu_loop_exit();                  cpu_loop_exit();
# Line 240  int cpu_x86_exec(CPUX86State *env1) Line 199  int cpu_x86_exec(CPUX86State *env1)
199                          lookup_symbol((void *)tb->pc));                          lookup_symbol((void *)tb->pc));
200              }              }
201  #endif  #endif
202    #ifdef __sparc__
203                T0 = tmp_T0;
204    #endif      
205              /* see if we can patch the calling TB */              /* see if we can patch the calling TB */
206              if (T0 != 0 && !(env->eflags & TF_MASK)) {              if (T0 != 0 && !(env->eflags & TF_MASK)) {
207                  spin_lock(&tb_lock);                  spin_lock(&tb_lock);
208                  tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);                  tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);
209                  spin_unlock(&tb_lock);                  spin_unlock(&tb_lock);
210              }              }
   
211              tc_ptr = tb->tc_ptr;              tc_ptr = tb->tc_ptr;
212    
213              /* execute the generated code */              /* execute the generated code */
214              gen_func = (void *)tc_ptr;              gen_func = (void *)tc_ptr;
215  #ifdef __sparc__  #if defined(__sparc__)
216              __asm__ __volatile__("call  %0\n\t"              __asm__ __volatile__("call  %0\n\t"
217                                   " mov  %%o7,%%i0"                                   "mov   %%o7,%%i0"
218                                   : /* no outputs */                                   : /* no outputs */
219                                   : "r" (gen_func)                                   : "r" (gen_func)
220                                   : "i0", "i1", "i2", "i3", "i4", "i5");                                   : "i0", "i1", "i2", "i3", "i4", "i5");
221    #elif defined(__arm__)
222                asm volatile ("mov pc, %0\n\t"
223                              ".global exec_loop\n\t"
224                              "exec_loop:\n\t"
225                              : /* no outputs */
226                              : "r" (gen_func)
227                              : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
228  #else  #else
229              gen_func();              gen_func();
230  #endif  #endif
# Line 292  int cpu_x86_exec(CPUX86State *env1) Line 260  int cpu_x86_exec(CPUX86State *env1)
260  #ifdef reg_EDI  #ifdef reg_EDI
261      EDI = saved_EDI;      EDI = saved_EDI;
262  #endif  #endif
263    #ifdef __sparc__
264        asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
265    #endif
266      T0 = saved_T0;      T0 = saved_T0;
267      T1 = saved_T1;      T1 = saved_T1;
268      A0 = saved_A0;      A0 = saved_A0;
# Line 457  int cpu_x86_signal_handler(int host_sign Line 428  int cpu_x86_signal_handler(int host_sign
428      uint32_t insn = *pc;      uint32_t insn = *pc;
429      int is_write = 0;      int is_write = 0;
430    
431        /* XXX: need kernel patch to get write flag faster */
432      switch (insn >> 26) {      switch (insn >> 26) {
433      case 0x0d: // stw      case 0x0d: // stw
434      case 0x0e: // stb      case 0x0e: // stb
# Line 475  int cpu_x86_signal_handler(int host_sign Line 447  int cpu_x86_signal_handler(int host_sign
447      return handle_cpu_signal(pc, (unsigned long)info->si_addr,      return handle_cpu_signal(pc, (unsigned long)info->si_addr,
448                               is_write, &uc->uc_sigmask);                               is_write, &uc->uc_sigmask);
449  }  }
450    #elif defined(__sparc__)
451    
452    int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
453                               void *puc)
454    {
455        uint32_t *regs = (uint32_t *)(info + 1);
456        void *sigmask = (regs + 20);
457        unsigned long pc;
458        int is_write;
459        uint32_t insn;
460        
461        /* XXX: is there a standard glibc define ? */
462        pc = regs[1];
463        /* XXX: need kernel patch to get write flag faster */
464        is_write = 0;
465        insn = *(uint32_t *)pc;
466        if ((insn >> 30) == 3) {
467          switch((insn >> 19) & 0x3f) {
468          case 0x05: // stb
469          case 0x06: // sth
470          case 0x04: // st
471          case 0x07: // std
472          case 0x24: // stf
473          case 0x27: // stdf
474          case 0x25: // stfsr
475            is_write = 1;
476            break;
477          }
478        }
479        return handle_cpu_signal(pc, (unsigned long)info->si_addr,
480                                 is_write, sigmask);
481    }
482    
483    #elif defined(__arm__)
484    
485    int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
486                               void *puc)
487    {
488        struct ucontext *uc = puc;
489        unsigned long pc;
490        int is_write;
491        
492        pc = uc->uc_mcontext.gregs[R15];
493        /* XXX: compute is_write */
494        is_write = 0;
495        return handle_cpu_signal(pc, (unsigned long)info->si_addr,
496                                 is_write,
497                                 &uc->uc_sigmask);
498    }
499    
500  #else  #else
501    
502  #error CPU specific signal handler needed  #error CPU specific signal handler needed

Legend:
Removed from v.1.27  
changed lines
  Added in v.1.28

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26