1070af384SBlue Swirl /* 2070af384SBlue Swirl * Helpers for CWP and PSTATE handling 3070af384SBlue Swirl * 4070af384SBlue Swirl * Copyright (c) 2003-2005 Fabrice Bellard 5070af384SBlue Swirl * 6070af384SBlue Swirl * This library is free software; you can redistribute it and/or 7070af384SBlue Swirl * modify it under the terms of the GNU Lesser General Public 8070af384SBlue Swirl * License as published by the Free Software Foundation; either 95650b549SChetan Pant * version 2.1 of the License, or (at your option) any later version. 10070af384SBlue Swirl * 11070af384SBlue Swirl * This library is distributed in the hope that it will be useful, 12070af384SBlue Swirl * but WITHOUT ANY WARRANTY; without even the implied warranty of 13070af384SBlue Swirl * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14070af384SBlue Swirl * Lesser General Public License for more details. 15070af384SBlue Swirl * 16070af384SBlue Swirl * You should have received a copy of the GNU Lesser General Public 17070af384SBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18070af384SBlue Swirl */ 19070af384SBlue Swirl 20db5ebe5fSPeter Maydell #include "qemu/osdep.h" 215ee59930SAlex Bennée #include "qemu/main-loop.h" 22070af384SBlue Swirl #include "cpu.h" 232f9d35fcSRichard Henderson #include "exec/exec-all.h" 242ef6175aSRichard Henderson #include "exec/helper-proto.h" 25870be6adSBlue Swirl #include "trace.h" 26070af384SBlue Swirl 27070af384SBlue Swirl static inline void memcpy32(target_ulong *dst, const target_ulong *src) 28070af384SBlue Swirl { 29070af384SBlue Swirl dst[0] = src[0]; 30070af384SBlue Swirl dst[1] = src[1]; 31070af384SBlue Swirl dst[2] = src[2]; 32070af384SBlue Swirl dst[3] = src[3]; 33070af384SBlue Swirl dst[4] = src[4]; 34070af384SBlue Swirl dst[5] = src[5]; 35070af384SBlue Swirl dst[6] = src[6]; 36070af384SBlue Swirl dst[7] = src[7]; 37070af384SBlue Swirl } 38070af384SBlue Swirl 39c5f9864eSAndreas Färber void cpu_set_cwp(CPUSPARCState *env, int new_cwp) 40070af384SBlue Swirl { 41070af384SBlue Swirl /* put the modified wrap registers at their proper location */ 42070af384SBlue Swirl if (env->cwp == env->nwindows - 1) { 43070af384SBlue Swirl memcpy32(env->regbase, env->regbase + env->nwindows * 16); 44070af384SBlue Swirl } 45070af384SBlue Swirl env->cwp = new_cwp; 46070af384SBlue Swirl 47070af384SBlue Swirl /* put the wrap registers at their temporary location */ 48070af384SBlue Swirl if (new_cwp == env->nwindows - 1) { 49070af384SBlue Swirl memcpy32(env->regbase + env->nwindows * 16, env->regbase); 50070af384SBlue Swirl } 51070af384SBlue Swirl env->regwptr = env->regbase + (new_cwp * 16); 52070af384SBlue Swirl } 53070af384SBlue Swirl 54c5f9864eSAndreas Färber target_ulong cpu_get_psr(CPUSPARCState *env) 55070af384SBlue Swirl { 56070af384SBlue Swirl helper_compute_psr(env); 57070af384SBlue Swirl 58070af384SBlue Swirl #if !defined(TARGET_SPARC64) 59070af384SBlue Swirl return env->version | (env->psr & PSR_ICC) | 60070af384SBlue Swirl (env->psref ? PSR_EF : 0) | 61070af384SBlue Swirl (env->psrpil << 8) | 62070af384SBlue Swirl (env->psrs ? PSR_S : 0) | 63070af384SBlue Swirl (env->psrps ? PSR_PS : 0) | 64070af384SBlue Swirl (env->psret ? PSR_ET : 0) | env->cwp; 65070af384SBlue Swirl #else 66070af384SBlue Swirl return env->psr & PSR_ICC; 67070af384SBlue Swirl #endif 68070af384SBlue Swirl } 69070af384SBlue Swirl 70*b1fa27fcSRichard Henderson void cpu_put_psr_icc(CPUSPARCState *env, target_ulong val) 71070af384SBlue Swirl { 72070af384SBlue Swirl env->psr = val & PSR_ICC; 73*b1fa27fcSRichard Henderson } 74*b1fa27fcSRichard Henderson 75*b1fa27fcSRichard Henderson void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val) 76*b1fa27fcSRichard Henderson { 77*b1fa27fcSRichard Henderson cpu_put_psr_icc(env, val); 78070af384SBlue Swirl #if !defined(TARGET_SPARC64) 79070af384SBlue Swirl env->psref = (val & PSR_EF) ? 1 : 0; 80070af384SBlue Swirl env->psrpil = (val & PSR_PIL) >> 8; 81070af384SBlue Swirl env->psrs = (val & PSR_S) ? 1 : 0; 82070af384SBlue Swirl env->psrps = (val & PSR_PS) ? 1 : 0; 83070af384SBlue Swirl env->psret = (val & PSR_ET) ? 1 : 0; 84070af384SBlue Swirl #endif 85070af384SBlue Swirl env->cc_op = CC_OP_FLAGS; 864552a09dSPeter Maydell #if !defined(TARGET_SPARC64) 874552a09dSPeter Maydell cpu_set_cwp(env, val & PSR_CWP); 884552a09dSPeter Maydell #endif 894552a09dSPeter Maydell } 904552a09dSPeter Maydell 915ee59930SAlex Bennée /* Called with BQL held */ 924552a09dSPeter Maydell void cpu_put_psr(CPUSPARCState *env, target_ulong val) 934552a09dSPeter Maydell { 944552a09dSPeter Maydell cpu_put_psr_raw(env, val); 954552a09dSPeter Maydell #if ((!defined(TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY)) 964552a09dSPeter Maydell cpu_check_irqs(env); 974552a09dSPeter Maydell #endif 98070af384SBlue Swirl } 99070af384SBlue Swirl 100c5f9864eSAndreas Färber int cpu_cwp_inc(CPUSPARCState *env, int cwp) 101070af384SBlue Swirl { 102070af384SBlue Swirl if (unlikely(cwp >= env->nwindows)) { 103070af384SBlue Swirl cwp -= env->nwindows; 104070af384SBlue Swirl } 105070af384SBlue Swirl return cwp; 106070af384SBlue Swirl } 107070af384SBlue Swirl 108c5f9864eSAndreas Färber int cpu_cwp_dec(CPUSPARCState *env, int cwp) 109070af384SBlue Swirl { 110070af384SBlue Swirl if (unlikely(cwp < 0)) { 111070af384SBlue Swirl cwp += env->nwindows; 112070af384SBlue Swirl } 113070af384SBlue Swirl return cwp; 114070af384SBlue Swirl } 115070af384SBlue Swirl 116070af384SBlue Swirl #ifndef TARGET_SPARC64 117c5f9864eSAndreas Färber void helper_rett(CPUSPARCState *env) 118070af384SBlue Swirl { 119070af384SBlue Swirl unsigned int cwp; 120070af384SBlue Swirl 121070af384SBlue Swirl if (env->psret == 1) { 1222f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 123070af384SBlue Swirl } 124070af384SBlue Swirl 125070af384SBlue Swirl env->psret = 1; 126063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1) ; 127070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1282f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 129070af384SBlue Swirl } 130063c3675SBlue Swirl cpu_set_cwp(env, cwp); 131070af384SBlue Swirl env->psrs = env->psrps; 132070af384SBlue Swirl } 133070af384SBlue Swirl 134070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 135070af384SBlue Swirl handling ? */ 136c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 137070af384SBlue Swirl { 138070af384SBlue Swirl uint32_t cwp; 139070af384SBlue Swirl 140063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 141070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1422f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_OVF, GETPC()); 143070af384SBlue Swirl } 144063c3675SBlue Swirl cpu_set_cwp(env, cwp); 145070af384SBlue Swirl } 146070af384SBlue Swirl 147c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 148070af384SBlue Swirl { 149070af384SBlue Swirl uint32_t cwp; 150070af384SBlue Swirl 151063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 152070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1532f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 154070af384SBlue Swirl } 155063c3675SBlue Swirl cpu_set_cwp(env, cwp); 156070af384SBlue Swirl } 157070af384SBlue Swirl 158c5f9864eSAndreas Färber void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) 159070af384SBlue Swirl { 160070af384SBlue Swirl if ((new_psr & PSR_CWP) >= env->nwindows) { 1612f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 162070af384SBlue Swirl } else { 1635ee59930SAlex Bennée /* cpu_put_psr may trigger interrupts, hence BQL */ 1645ee59930SAlex Bennée qemu_mutex_lock_iothread(); 165070af384SBlue Swirl cpu_put_psr(env, new_psr); 1665ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 167070af384SBlue Swirl } 168070af384SBlue Swirl } 169070af384SBlue Swirl 170c5f9864eSAndreas Färber target_ulong helper_rdpsr(CPUSPARCState *env) 171070af384SBlue Swirl { 172063c3675SBlue Swirl return cpu_get_psr(env); 173070af384SBlue Swirl } 174070af384SBlue Swirl 175070af384SBlue Swirl #else 176070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 177070af384SBlue Swirl handling ? */ 178c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 179070af384SBlue Swirl { 180070af384SBlue Swirl uint32_t cwp; 181070af384SBlue Swirl 182063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 183070af384SBlue Swirl if (env->cansave == 0) { 1842f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 1852f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 1862f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 1872f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 188070af384SBlue Swirl } else { 189070af384SBlue Swirl if (env->cleanwin - env->canrestore == 0) { 190070af384SBlue Swirl /* XXX Clean windows without trap */ 1912f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_CLRWIN, GETPC()); 192070af384SBlue Swirl } else { 193070af384SBlue Swirl env->cansave--; 194070af384SBlue Swirl env->canrestore++; 195063c3675SBlue Swirl cpu_set_cwp(env, cwp); 196070af384SBlue Swirl } 197070af384SBlue Swirl } 198070af384SBlue Swirl } 199070af384SBlue Swirl 200c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 201070af384SBlue Swirl { 202070af384SBlue Swirl uint32_t cwp; 203070af384SBlue Swirl 204063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 205070af384SBlue Swirl if (env->canrestore == 0) { 2062f9d35fcSRichard Henderson int tt = TT_FILL | (env->otherwin != 0 2072f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2082f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2092f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 210070af384SBlue Swirl } else { 211070af384SBlue Swirl env->cansave++; 212070af384SBlue Swirl env->canrestore--; 213063c3675SBlue Swirl cpu_set_cwp(env, cwp); 214070af384SBlue Swirl } 215070af384SBlue Swirl } 216070af384SBlue Swirl 217c5f9864eSAndreas Färber void helper_flushw(CPUSPARCState *env) 218070af384SBlue Swirl { 219070af384SBlue Swirl if (env->cansave != env->nwindows - 2) { 2202f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 2212f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2222f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2232f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 224070af384SBlue Swirl } 225070af384SBlue Swirl } 226070af384SBlue Swirl 227c5f9864eSAndreas Färber void helper_saved(CPUSPARCState *env) 228070af384SBlue Swirl { 229070af384SBlue Swirl env->cansave++; 230070af384SBlue Swirl if (env->otherwin == 0) { 231070af384SBlue Swirl env->canrestore--; 232070af384SBlue Swirl } else { 233070af384SBlue Swirl env->otherwin--; 234070af384SBlue Swirl } 235070af384SBlue Swirl } 236070af384SBlue Swirl 237c5f9864eSAndreas Färber void helper_restored(CPUSPARCState *env) 238070af384SBlue Swirl { 239070af384SBlue Swirl env->canrestore++; 240070af384SBlue Swirl if (env->cleanwin < env->nwindows - 1) { 241070af384SBlue Swirl env->cleanwin++; 242070af384SBlue Swirl } 243070af384SBlue Swirl if (env->otherwin == 0) { 244070af384SBlue Swirl env->cansave--; 245070af384SBlue Swirl } else { 246070af384SBlue Swirl env->otherwin--; 247070af384SBlue Swirl } 248070af384SBlue Swirl } 249070af384SBlue Swirl 250c5f9864eSAndreas Färber target_ulong cpu_get_ccr(CPUSPARCState *env) 251070af384SBlue Swirl { 252070af384SBlue Swirl target_ulong psr; 253070af384SBlue Swirl 254063c3675SBlue Swirl psr = cpu_get_psr(env); 255070af384SBlue Swirl 256070af384SBlue Swirl return ((env->xcc >> 20) << 4) | ((psr & PSR_ICC) >> 20); 257070af384SBlue Swirl } 258070af384SBlue Swirl 259c5f9864eSAndreas Färber void cpu_put_ccr(CPUSPARCState *env, target_ulong val) 260070af384SBlue Swirl { 261070af384SBlue Swirl env->xcc = (val >> 4) << 20; 262070af384SBlue Swirl env->psr = (val & 0xf) << 20; 263070af384SBlue Swirl CC_OP = CC_OP_FLAGS; 264070af384SBlue Swirl } 265070af384SBlue Swirl 266c5f9864eSAndreas Färber target_ulong cpu_get_cwp64(CPUSPARCState *env) 267070af384SBlue Swirl { 268070af384SBlue Swirl return env->nwindows - 1 - env->cwp; 269070af384SBlue Swirl } 270070af384SBlue Swirl 271c5f9864eSAndreas Färber void cpu_put_cwp64(CPUSPARCState *env, int cwp) 272070af384SBlue Swirl { 273070af384SBlue Swirl if (unlikely(cwp >= env->nwindows || cwp < 0)) { 274070af384SBlue Swirl cwp %= env->nwindows; 275070af384SBlue Swirl } 276063c3675SBlue Swirl cpu_set_cwp(env, env->nwindows - 1 - cwp); 277070af384SBlue Swirl } 278070af384SBlue Swirl 279c5f9864eSAndreas Färber target_ulong helper_rdccr(CPUSPARCState *env) 280070af384SBlue Swirl { 281063c3675SBlue Swirl return cpu_get_ccr(env); 282070af384SBlue Swirl } 283070af384SBlue Swirl 284c5f9864eSAndreas Färber void helper_wrccr(CPUSPARCState *env, target_ulong new_ccr) 285070af384SBlue Swirl { 286063c3675SBlue Swirl cpu_put_ccr(env, new_ccr); 287070af384SBlue Swirl } 288070af384SBlue Swirl 289070af384SBlue Swirl /* CWP handling is reversed in V9, but we still use the V8 register 290070af384SBlue Swirl order. */ 291c5f9864eSAndreas Färber target_ulong helper_rdcwp(CPUSPARCState *env) 292070af384SBlue Swirl { 293063c3675SBlue Swirl return cpu_get_cwp64(env); 294070af384SBlue Swirl } 295070af384SBlue Swirl 296c5f9864eSAndreas Färber void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp) 297070af384SBlue Swirl { 298063c3675SBlue Swirl cpu_put_cwp64(env, new_cwp); 299070af384SBlue Swirl } 300070af384SBlue Swirl 301c5f9864eSAndreas Färber static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) 302070af384SBlue Swirl { 303576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 304cbc3a6a4SArtyom Tarasenko return env->glregs + (env->gl & 7) * 8; 305cbc3a6a4SArtyom Tarasenko } 306cbc3a6a4SArtyom Tarasenko 307070af384SBlue Swirl switch (pstate) { 308070af384SBlue Swirl default: 309870be6adSBlue Swirl trace_win_helper_gregset_error(pstate); 3109cf5a9cfSChen Qun /* fall through to normal set of global registers */ 311070af384SBlue Swirl case 0: 312070af384SBlue Swirl return env->bgregs; 313070af384SBlue Swirl case PS_AG: 314070af384SBlue Swirl return env->agregs; 315070af384SBlue Swirl case PS_MG: 316070af384SBlue Swirl return env->mgregs; 317070af384SBlue Swirl case PS_IG: 318070af384SBlue Swirl return env->igregs; 319070af384SBlue Swirl } 320070af384SBlue Swirl } 321070af384SBlue Swirl 322cbc3a6a4SArtyom Tarasenko static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl) 323cbc3a6a4SArtyom Tarasenko { 324cbc3a6a4SArtyom Tarasenko return env->glregs + (gl & 7) * 8; 325cbc3a6a4SArtyom Tarasenko } 326cbc3a6a4SArtyom Tarasenko 327cbc3a6a4SArtyom Tarasenko /* Switch global register bank */ 328cbc3a6a4SArtyom Tarasenko void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl) 329cbc3a6a4SArtyom Tarasenko { 330cbc3a6a4SArtyom Tarasenko uint64_t *src, *dst; 331cbc3a6a4SArtyom Tarasenko src = get_gl_gregset(env, new_gl); 332cbc3a6a4SArtyom Tarasenko dst = get_gl_gregset(env, env->gl); 333cbc3a6a4SArtyom Tarasenko 334cbc3a6a4SArtyom Tarasenko if (src != dst) { 335cbc3a6a4SArtyom Tarasenko memcpy32(dst, env->gregs); 336cbc3a6a4SArtyom Tarasenko memcpy32(env->gregs, src); 337cbc3a6a4SArtyom Tarasenko } 338cbc3a6a4SArtyom Tarasenko } 339cbc3a6a4SArtyom Tarasenko 340cbc3a6a4SArtyom Tarasenko void helper_wrgl(CPUSPARCState *env, target_ulong new_gl) 341cbc3a6a4SArtyom Tarasenko { 342cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl & 7); 343cbc3a6a4SArtyom Tarasenko env->gl = new_gl & 7; 344cbc3a6a4SArtyom Tarasenko } 345cbc3a6a4SArtyom Tarasenko 346c5f9864eSAndreas Färber void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) 347070af384SBlue Swirl { 348070af384SBlue Swirl uint32_t pstate_regs, new_pstate_regs; 349070af384SBlue Swirl uint64_t *src, *dst; 350070af384SBlue Swirl 351576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 352cbc3a6a4SArtyom Tarasenko /* PS_AG, IG and MG are not implemented in this case */ 353cbc3a6a4SArtyom Tarasenko new_pstate &= ~(PS_AG | PS_IG | PS_MG); 354cbc3a6a4SArtyom Tarasenko env->pstate = new_pstate; 355cbc3a6a4SArtyom Tarasenko return; 356070af384SBlue Swirl } 357070af384SBlue Swirl 358070af384SBlue Swirl pstate_regs = env->pstate & 0xc01; 359070af384SBlue Swirl new_pstate_regs = new_pstate & 0xc01; 360070af384SBlue Swirl 361070af384SBlue Swirl if (new_pstate_regs != pstate_regs) { 362870be6adSBlue Swirl trace_win_helper_switch_pstate(pstate_regs, new_pstate_regs); 363870be6adSBlue Swirl 364070af384SBlue Swirl /* Switch global register bank */ 365063c3675SBlue Swirl src = get_gregset(env, new_pstate_regs); 366063c3675SBlue Swirl dst = get_gregset(env, pstate_regs); 367070af384SBlue Swirl memcpy32(dst, env->gregs); 368070af384SBlue Swirl memcpy32(env->gregs, src); 369070af384SBlue Swirl } else { 370870be6adSBlue Swirl trace_win_helper_no_switch_pstate(new_pstate_regs); 371070af384SBlue Swirl } 372070af384SBlue Swirl env->pstate = new_pstate; 373070af384SBlue Swirl } 374070af384SBlue Swirl 375c5f9864eSAndreas Färber void helper_wrpstate(CPUSPARCState *env, target_ulong new_state) 376070af384SBlue Swirl { 377063c3675SBlue Swirl cpu_change_pstate(env, new_state & 0xf3f); 378070af384SBlue Swirl 379070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 380070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 3815ee59930SAlex Bennée qemu_mutex_lock_iothread(); 382070af384SBlue Swirl cpu_check_irqs(env); 3835ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 384070af384SBlue Swirl } 385070af384SBlue Swirl #endif 386070af384SBlue Swirl } 387070af384SBlue Swirl 388c5f9864eSAndreas Färber void helper_wrpil(CPUSPARCState *env, target_ulong new_pil) 389070af384SBlue Swirl { 390070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 391870be6adSBlue Swirl trace_win_helper_wrpil(env->psrpil, (uint32_t)new_pil); 392070af384SBlue Swirl 393070af384SBlue Swirl env->psrpil = new_pil; 394070af384SBlue Swirl 395070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 3965ee59930SAlex Bennée qemu_mutex_lock_iothread(); 397070af384SBlue Swirl cpu_check_irqs(env); 3985ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 399070af384SBlue Swirl } 400070af384SBlue Swirl #endif 401070af384SBlue Swirl } 402070af384SBlue Swirl 403c5f9864eSAndreas Färber void helper_done(CPUSPARCState *env) 404070af384SBlue Swirl { 405070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 406070af384SBlue Swirl 407070af384SBlue Swirl env->pc = tsptr->tnpc; 408070af384SBlue Swirl env->npc = tsptr->tnpc + 4; 409063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 410070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 411063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 412063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4136e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 414cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4156e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 416cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 417cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4186e040755SArtyom Tarasenko } 419070af384SBlue Swirl env->tl--; 420070af384SBlue Swirl 421870be6adSBlue Swirl trace_win_helper_done(env->tl); 422070af384SBlue Swirl 423070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 424070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4255ee59930SAlex Bennée qemu_mutex_lock_iothread(); 426070af384SBlue Swirl cpu_check_irqs(env); 4275ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 428070af384SBlue Swirl } 429070af384SBlue Swirl #endif 430070af384SBlue Swirl } 431070af384SBlue Swirl 432c5f9864eSAndreas Färber void helper_retry(CPUSPARCState *env) 433070af384SBlue Swirl { 434070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 435070af384SBlue Swirl 436070af384SBlue Swirl env->pc = tsptr->tpc; 437070af384SBlue Swirl env->npc = tsptr->tnpc; 438063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 439070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 440063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 441063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4426e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 443cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4446e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 445cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 446cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4476e040755SArtyom Tarasenko } 448070af384SBlue Swirl env->tl--; 449070af384SBlue Swirl 450870be6adSBlue Swirl trace_win_helper_retry(env->tl); 451070af384SBlue Swirl 452070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 453070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4545ee59930SAlex Bennée qemu_mutex_lock_iothread(); 455070af384SBlue Swirl cpu_check_irqs(env); 4565ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 457070af384SBlue Swirl } 458070af384SBlue Swirl #endif 459070af384SBlue Swirl } 460070af384SBlue Swirl #endif 461