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
@ -808,11 +808,16 @@ static void save_window(CPUSPARCState *env)
|
|||||||
|
|
||||||
static void restore_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;
|
abi_ulong sp_ptr;
|
||||||
|
|
||||||
|
#ifndef TARGET_SPARC64
|
||||||
new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
|
new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
|
||||||
((1LL << env->nwindows) - 1);
|
((1LL << env->nwindows) - 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* restore the invalid window */
|
/* restore the invalid window */
|
||||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
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);
|
get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
|
||||||
sp_ptr += sizeof(abi_ulong);
|
sp_ptr += sizeof(abi_ulong);
|
||||||
}
|
}
|
||||||
env->wim = new_wim;
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
env->canrestore++;
|
env->canrestore++;
|
||||||
if (env->cleanwin < env->nwindows - 1)
|
if (env->cleanwin < env->nwindows - 1)
|
||||||
env->cleanwin++;
|
env->cleanwin++;
|
||||||
env->cansave--;
|
env->cansave--;
|
||||||
|
#else
|
||||||
|
env->wim = new_wim;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,14 +849,23 @@ static void flush_windows(CPUSPARCState *env)
|
|||||||
for(;;) {
|
for(;;) {
|
||||||
/* if restore would invoke restore_window(), then we can stop */
|
/* if restore would invoke restore_window(), then we can stop */
|
||||||
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
||||||
|
#ifndef TARGET_SPARC64
|
||||||
if (env->wim & (1 << cwp1))
|
if (env->wim & (1 << cwp1))
|
||||||
break;
|
break;
|
||||||
|
#else
|
||||||
|
if (env->canrestore == 0)
|
||||||
|
break;
|
||||||
|
env->cansave++;
|
||||||
|
env->canrestore--;
|
||||||
|
#endif
|
||||||
save_window_offset(env, cwp1);
|
save_window_offset(env, cwp1);
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
/* set wim so that restore will reload the registers */
|
|
||||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||||
|
#ifndef TARGET_SPARC64
|
||||||
|
/* set wim so that restore will reload the registers */
|
||||||
env->wim = 1 << cwp1;
|
env->wim = 1 << cwp1;
|
||||||
|
#endif
|
||||||
#if defined(DEBUG_WIN)
|
#if defined(DEBUG_WIN)
|
||||||
printf("flush_windows: nb=%d\n", offset - 1);
|
printf("flush_windows: nb=%d\n", offset - 1);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user