Commit eda52953026a5b6d28b063af13101f1edb580dcf

Authored by blueswir1
1 parent a3772d4d

Fix Sparc64 window handling problems detected by Vince Weaver

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5091 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 18 additions and 3 deletions
linux-user/main.c
@@ -808,11 +808,16 @@ static void save_window(CPUSPARCState *env) @@ -808,11 +808,16 @@ static void save_window(CPUSPARCState *env)
808 808
809 static void restore_window(CPUSPARCState *env) 809 static void restore_window(CPUSPARCState *env)
810 { 810 {
811 - unsigned int new_wim, i, cwp1; 811 +#ifndef TARGET_SPARC64
  812 + unsigned int new_wim;
  813 +#endif
  814 + unsigned int i, cwp1;
812 abi_ulong sp_ptr; 815 abi_ulong sp_ptr;
813 816
  817 +#ifndef TARGET_SPARC64
814 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) & 818 new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
815 ((1LL << env->nwindows) - 1); 819 ((1LL << env->nwindows) - 1);
  820 +#endif
816 821
817 /* restore the invalid window */ 822 /* restore the invalid window */
818 cwp1 = cpu_cwp_inc(env, env->cwp + 1); 823 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
@@ -826,12 +831,13 @@ static void restore_window(CPUSPARCState *env) @@ -826,12 +831,13 @@ static void restore_window(CPUSPARCState *env)
826 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr); 831 get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
827 sp_ptr += sizeof(abi_ulong); 832 sp_ptr += sizeof(abi_ulong);
828 } 833 }
829 - env->wim = new_wim;  
830 #ifdef TARGET_SPARC64 834 #ifdef TARGET_SPARC64
831 env->canrestore++; 835 env->canrestore++;
832 if (env->cleanwin < env->nwindows - 1) 836 if (env->cleanwin < env->nwindows - 1)
833 env->cleanwin++; 837 env->cleanwin++;
834 env->cansave--; 838 env->cansave--;
  839 +#else
  840 + env->wim = new_wim;
835 #endif 841 #endif
836 } 842 }
837 843
@@ -843,14 +849,23 @@ static void flush_windows(CPUSPARCState *env) @@ -843,14 +849,23 @@ static void flush_windows(CPUSPARCState *env)
843 for(;;) { 849 for(;;) {
844 /* if restore would invoke restore_window(), then we can stop */ 850 /* if restore would invoke restore_window(), then we can stop */
845 cwp1 = cpu_cwp_inc(env, env->cwp + offset); 851 cwp1 = cpu_cwp_inc(env, env->cwp + offset);
  852 +#ifndef TARGET_SPARC64
846 if (env->wim & (1 << cwp1)) 853 if (env->wim & (1 << cwp1))
847 break; 854 break;
  855 +#else
  856 + if (env->canrestore == 0)
  857 + break;
  858 + env->cansave++;
  859 + env->canrestore--;
  860 +#endif
848 save_window_offset(env, cwp1); 861 save_window_offset(env, cwp1);
849 offset++; 862 offset++;
850 } 863 }
851 - /* set wim so that restore will reload the registers */  
852 cwp1 = cpu_cwp_inc(env, env->cwp + 1); 864 cwp1 = cpu_cwp_inc(env, env->cwp + 1);
  865 +#ifndef TARGET_SPARC64
  866 + /* set wim so that restore will reload the registers */
853 env->wim = 1 << cwp1; 867 env->wim = 1 << cwp1;
  868 +#endif
854 #if defined(DEBUG_WIN) 869 #if defined(DEBUG_WIN)
855 printf("flush_windows: nb=%d\n", offset - 1); 870 printf("flush_windows: nb=%d\n", offset - 1);
856 #endif 871 #endif