diff options
| author | Artyom Tarasenko <atar4qemu@gmail.com> | 2016-06-07 18:34:49 +0200 |
|---|---|---|
| committer | Artyom Tarasenko <atar4qemu@gmail.com> | 2017-01-18 22:03:44 +0100 |
| commit | cbc3a6a4cc675516328a2b0d3602355d68b6302d (patch) | |
| tree | 837af98184dabc03c037428d2cfd8f0bf6248df6 /target/sparc/win_helper.c | |
| parent | 6e040755f12eba34d2fa3d56b18de32d63fea631 (diff) | |
| download | focaccia-qemu-cbc3a6a4cc675516328a2b0d3602355d68b6302d.tar.gz focaccia-qemu-cbc3a6a4cc675516328a2b0d3602355d68b6302d.zip | |
target-sparc: implement UA2005 GL register
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Diffstat (limited to 'target/sparc/win_helper.c')
| -rw-r--r-- | target/sparc/win_helper.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 45ee4e643e..71b3dd37e8 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -290,6 +290,10 @@ void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp) static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) { + if (env->def->features & CPU_FEATURE_GL) { + return env->glregs + (env->gl & 7) * 8; + } + switch (pstate) { default: trace_win_helper_gregset_error(pstate); @@ -305,14 +309,40 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) } } +static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl) +{ + return env->glregs + (gl & 7) * 8; +} + +/* Switch global register bank */ +void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl) +{ + uint64_t *src, *dst; + src = get_gl_gregset(env, new_gl); + dst = get_gl_gregset(env, env->gl); + + if (src != dst) { + memcpy32(dst, env->gregs); + memcpy32(env->gregs, src); + } +} + +void helper_wrgl(CPUSPARCState *env, target_ulong new_gl) +{ + cpu_gl_switch_gregs(env, new_gl & 7); + env->gl = new_gl & 7; +} + void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) { uint32_t pstate_regs, new_pstate_regs; uint64_t *src, *dst; if (env->def->features & CPU_FEATURE_GL) { - /* PS_AG is not implemented in this case */ - new_pstate &= ~PS_AG; + /* PS_AG, IG and MG are not implemented in this case */ + new_pstate &= ~(PS_AG | PS_IG | PS_MG); + env->pstate = new_pstate; + return; } pstate_regs = env->pstate & 0xc01; @@ -367,7 +397,10 @@ void helper_done(CPUSPARCState *env) cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); cpu_put_cwp64(env, tsptr->tstate & 0xff); if (cpu_has_hypervisor(env)) { + uint32_t new_gl = (tsptr->tstate >> 40) & 7; env->hpstate = env->htstate[env->tl]; + cpu_gl_switch_gregs(env, new_gl); + env->gl = new_gl; } env->tl--; @@ -391,7 +424,10 @@ void helper_retry(CPUSPARCState *env) cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); cpu_put_cwp64(env, tsptr->tstate & 0xff); if (cpu_has_hypervisor(env)) { + uint32_t new_gl = (tsptr->tstate >> 40) & 7; env->hpstate = env->htstate[env->tl]; + cpu_gl_switch_gregs(env, new_gl); + env->gl = new_gl; } env->tl--; |