mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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
This commit is contained in:
parent
a3772d4d44
commit
eda5295302
1 changed files with 18 additions and 3 deletions
|
@ -808,11 +808,16 @@ static void save_window(CPUSPARCState *env)
|
|||
|
||||
static void restore_window(CPUSPARCState *env)
|
||||
{
|
||||
unsigned int new_wim, i, cwp1;
|
||||
#ifndef TARGET_SPARC64
|
||||
unsigned int new_wim;
|
||||
#endif
|
||||
unsigned int i, cwp1;
|
||||
abi_ulong sp_ptr;
|
||||
|
||||
#ifndef TARGET_SPARC64
|
||||
new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
|
||||
((1LL << env->nwindows) - 1);
|
||||
#endif
|
||||
|
||||
/* restore the invalid window */
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||
|
@ -826,12 +831,13 @@ static void restore_window(CPUSPARCState *env)
|
|||
get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
|
||||
sp_ptr += sizeof(abi_ulong);
|
||||
}
|
||||
env->wim = new_wim;
|
||||
#ifdef TARGET_SPARC64
|
||||
env->canrestore++;
|
||||
if (env->cleanwin < env->nwindows - 1)
|
||||
env->cleanwin++;
|
||||
env->cansave--;
|
||||
#else
|
||||
env->wim = new_wim;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -843,14 +849,23 @@ static void flush_windows(CPUSPARCState *env)
|
|||
for(;;) {
|
||||
/* if restore would invoke restore_window(), then we can stop */
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
||||
#ifndef TARGET_SPARC64
|
||||
if (env->wim & (1 << cwp1))
|
||||
break;
|
||||
#else
|
||||
if (env->canrestore == 0)
|
||||
break;
|
||||
env->cansave++;
|
||||
env->canrestore--;
|
||||
#endif
|
||||
save_window_offset(env, cwp1);
|
||||
offset++;
|
||||
}
|
||||
/* set wim so that restore will reload the registers */
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||
#ifndef TARGET_SPARC64
|
||||
/* set wim so that restore will reload the registers */
|
||||
env->wim = 1 << cwp1;
|
||||
#endif
|
||||
#if defined(DEBUG_WIN)
|
||||
printf("flush_windows: nb=%d\n", offset - 1);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue