/[qemu]/qemu/linux-user/main.c
ViewVC logotype

Diff of /qemu/linux-user/main.c

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

revision 1.60 by bellard, Tue Feb 15 22:54:53 2005 UTC revision 1.61 by bellard, Sat Feb 19 17:25:31 2005 UTC
# Line 396  void cpu_loop(CPUARMState *env) Line 396  void cpu_loop(CPUARMState *env)
396    
397  //#define DEBUG_WIN  //#define DEBUG_WIN
398    
399  /* WARNING: dealing with register windows _is_ complicated */  /* WARNING: dealing with register windows _is_ complicated. More info
400       can be found at http://www.sics.se/~psm/sparcstack.html */
401  static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)  static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
402  {  {
403      index = (index + cwp * 16) & (16 * NWINDOWS - 1);      index = (index + cwp * 16) & (16 * NWINDOWS - 1);
# Line 407  static inline int get_reg_index(CPUSPARC Line 408  static inline int get_reg_index(CPUSPARC
408      return index;      return index;
409  }  }
410    
411  static inline void save_window_offset(CPUSPARCState *env, int offset)  /* save the register window 'cwp1' */
412    static inline void save_window_offset(CPUSPARCState *env, int cwp1)
413  {  {
414      unsigned int new_wim, i, cwp1;      unsigned int i;
415      uint32_t *sp_ptr;      uint32_t *sp_ptr;
416            
     new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &  
         ((1LL << NWINDOWS) - 1);  
     /* save the window */  
     cwp1 = (env->cwp + offset) & (NWINDOWS - 1);  
417      sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]);      sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]);
418  #if defined(DEBUG_WIN)  #if defined(DEBUG_WIN)
419      printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",      printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
420             (int)sp_ptr, cwp1);             (int)sp_ptr, cwp1);
421  #endif  #endif
422      for(i = 0; i < 16; i++)      for(i = 0; i < 16; i++) {
423          stl_raw(sp_ptr + i, env->regbase[get_reg_index(env, cwp1, 8 + i)]);          put_user(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
424      env->wim = new_wim;          sp_ptr++;
425        }
426  }  }
427    
428  static void save_window(CPUSPARCState *env)  static void save_window(CPUSPARCState *env)
429  {  {
430      save_window_offset(env, 2);      unsigned int new_wim;
431        new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
432            ((1LL << NWINDOWS) - 1);
433        save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
434        env->wim = new_wim;
435  }  }
436    
437  static void restore_window(CPUSPARCState *env)  static void restore_window(CPUSPARCState *env)
438  {  {
439      unsigned int new_wim, i, cwp1;      unsigned int new_wim, i, cwp1;
440      uint32_t *sp_ptr;      uint32_t *sp_ptr, reg;
441            
442      new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &      new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
443          ((1LL << NWINDOWS) - 1);          ((1LL << NWINDOWS) - 1);
# Line 446  static void restore_window(CPUSPARCState Line 449  static void restore_window(CPUSPARCState
449      printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",      printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
450             (int)sp_ptr, cwp1);             (int)sp_ptr, cwp1);
451  #endif  #endif
452      for(i = 0; i < 16; i++)      for(i = 0; i < 16; i++) {
453          env->regbase[get_reg_index(env, cwp1, 8 + i)] = ldl_raw(sp_ptr + i);          get_user(reg, sp_ptr);
454            env->regbase[get_reg_index(env, cwp1, 8 + i)] = reg;
455            sp_ptr++;
456        }
457      env->wim = new_wim;      env->wim = new_wim;
458  }  }
459    
 #if 0  
460  static void flush_windows(CPUSPARCState *env)  static void flush_windows(CPUSPARCState *env)
461  {  {
462      int offset, cwp1;      int offset, cwp1;
463  #if defined(DEBUG_WIN)  
464      printf("flush_windows:\n");      offset = 1;
 #endif  
     offset = 2;  
465      for(;;) {      for(;;) {
466          /* if restore would invoke restore_window(), then we can stop */          /* if restore would invoke restore_window(), then we can stop */
467          cwp1 = (env->cwp + 1) & (NWINDOWS - 1);          cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
468          if (env->wim & (1 << cwp1))          if (env->wim & (1 << cwp1))
469              break;              break;
470  #if defined(DEBUG_WIN)          save_window_offset(env, cwp1);
         printf("offset=%d: ", offset);  
 #endif  
         save_window_offset(env, offset);  
471          offset++;          offset++;
472      }      }
473  }      /* set wim so that restore will reload the registers */
474        cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
475        env->wim = 1 << cwp1;
476    #if defined(DEBUG_WIN)
477        printf("flush_windows: nb=%d\n", offset - 1);
478  #endif  #endif
479    }
480    
481  void cpu_loop (CPUSPARCState *env)  void cpu_loop (CPUSPARCState *env)
482  {  {
# Line 500  void cpu_loop (CPUSPARCState *env) Line 505  void cpu_loop (CPUSPARCState *env)
505              env->npc = env->npc + 4;              env->npc = env->npc + 4;
506              break;              break;
507          case 0x83: /* flush windows */          case 0x83: /* flush windows */
508              //            flush_windows(env);              flush_windows(env);
509              /* next instruction */              /* next instruction */
510              env->pc = env->npc;              env->pc = env->npc;
511              env->npc = env->npc + 4;              env->npc = env->npc + 4;

Legend:
Removed from v.1.60  
changed lines
  Added in v.1.61

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