Commit eda52953026a5b6d28b063af13101f1edb580dcf
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 |