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 27c5f9864eSAndreas Färber void cpu_set_cwp(CPUSPARCState *env, int new_cwp) 28070af384SBlue Swirl { 29070af384SBlue Swirl /* put the modified wrap registers at their proper location */ 30070af384SBlue Swirl if (env->cwp == env->nwindows - 1) { 31*7ac87b14SPhilippe Mathieu-Daudé memcpy(env->regbase, env->regbase + env->nwindows * 16, 32*7ac87b14SPhilippe Mathieu-Daudé sizeof(env->gregs)); 33070af384SBlue Swirl } 34070af384SBlue Swirl env->cwp = new_cwp; 35070af384SBlue Swirl 36070af384SBlue Swirl /* put the wrap registers at their temporary location */ 37070af384SBlue Swirl if (new_cwp == env->nwindows - 1) { 38*7ac87b14SPhilippe Mathieu-Daudé memcpy(env->regbase + env->nwindows * 16, env->regbase, 39*7ac87b14SPhilippe Mathieu-Daudé sizeof(env->gregs)); 40070af384SBlue Swirl } 41070af384SBlue Swirl env->regwptr = env->regbase + (new_cwp * 16); 42070af384SBlue Swirl } 43070af384SBlue Swirl 44c5f9864eSAndreas Färber target_ulong cpu_get_psr(CPUSPARCState *env) 45070af384SBlue Swirl { 462a1905c7SRichard Henderson target_ulong icc = 0; 472a1905c7SRichard Henderson 482a1905c7SRichard Henderson icc |= ((int32_t)env->cc_N < 0) << PSR_NEG_SHIFT; 492a1905c7SRichard Henderson icc |= ((int32_t)env->cc_V < 0) << PSR_OVF_SHIFT; 502a1905c7SRichard Henderson icc |= ((int32_t)env->icc_Z == 0) << PSR_ZERO_SHIFT; 512a1905c7SRichard Henderson if (TARGET_LONG_BITS == 64) { 522a1905c7SRichard Henderson icc |= extract64(env->icc_C, 32, 1) << PSR_CARRY_SHIFT; 532a1905c7SRichard Henderson } else { 542a1905c7SRichard Henderson icc |= env->icc_C << PSR_CARRY_SHIFT; 552a1905c7SRichard Henderson } 562a1905c7SRichard Henderson 57070af384SBlue Swirl #if !defined(TARGET_SPARC64) 582a1905c7SRichard Henderson return env->version | icc | 59070af384SBlue Swirl (env->psref ? PSR_EF : 0) | 60070af384SBlue Swirl (env->psrpil << 8) | 61070af384SBlue Swirl (env->psrs ? PSR_S : 0) | 62070af384SBlue Swirl (env->psrps ? PSR_PS : 0) | 63070af384SBlue Swirl (env->psret ? PSR_ET : 0) | env->cwp; 64070af384SBlue Swirl #else 652a1905c7SRichard Henderson return icc; 66070af384SBlue Swirl #endif 67070af384SBlue Swirl } 68070af384SBlue Swirl 69b1fa27fcSRichard Henderson void cpu_put_psr_icc(CPUSPARCState *env, target_ulong val) 70070af384SBlue Swirl { 712a1905c7SRichard Henderson if (TARGET_LONG_BITS == 64) { 722a1905c7SRichard Henderson /* Do not clobber xcc.[NV] */ 732a1905c7SRichard Henderson env->cc_N = deposit64(env->cc_N, 0, 32, -(val & PSR_NEG)); 742a1905c7SRichard Henderson env->cc_V = deposit64(env->cc_V, 0, 32, -(val & PSR_OVF)); 752a1905c7SRichard Henderson env->icc_C = -(val & PSR_CARRY); 762a1905c7SRichard Henderson } else { 772a1905c7SRichard Henderson env->cc_N = -(val & PSR_NEG); 782a1905c7SRichard Henderson env->cc_V = -(val & PSR_OVF); 792a1905c7SRichard Henderson env->icc_C = (val >> PSR_CARRY_SHIFT) & 1; 802a1905c7SRichard Henderson } 812a1905c7SRichard Henderson env->icc_Z = ~val & PSR_ZERO; 82b1fa27fcSRichard Henderson } 83b1fa27fcSRichard Henderson 84b1fa27fcSRichard Henderson void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val) 85b1fa27fcSRichard Henderson { 86b1fa27fcSRichard Henderson cpu_put_psr_icc(env, val); 87070af384SBlue Swirl #if !defined(TARGET_SPARC64) 88070af384SBlue Swirl env->psref = (val & PSR_EF) ? 1 : 0; 89070af384SBlue Swirl env->psrpil = (val & PSR_PIL) >> 8; 90070af384SBlue Swirl env->psrs = (val & PSR_S) ? 1 : 0; 91070af384SBlue Swirl env->psrps = (val & PSR_PS) ? 1 : 0; 92070af384SBlue Swirl env->psret = (val & PSR_ET) ? 1 : 0; 93070af384SBlue Swirl #endif 944552a09dSPeter Maydell #if !defined(TARGET_SPARC64) 954552a09dSPeter Maydell cpu_set_cwp(env, val & PSR_CWP); 964552a09dSPeter Maydell #endif 974552a09dSPeter Maydell } 984552a09dSPeter Maydell 995ee59930SAlex Bennée /* Called with BQL held */ 1004552a09dSPeter Maydell void cpu_put_psr(CPUSPARCState *env, target_ulong val) 1014552a09dSPeter Maydell { 1024552a09dSPeter Maydell cpu_put_psr_raw(env, val); 1034552a09dSPeter Maydell #if ((!defined(TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY)) 1044552a09dSPeter Maydell cpu_check_irqs(env); 1054552a09dSPeter Maydell #endif 106070af384SBlue Swirl } 107070af384SBlue Swirl 108c5f9864eSAndreas Färber int cpu_cwp_inc(CPUSPARCState *env, int cwp) 109070af384SBlue Swirl { 110070af384SBlue Swirl if (unlikely(cwp >= env->nwindows)) { 111070af384SBlue Swirl cwp -= env->nwindows; 112070af384SBlue Swirl } 113070af384SBlue Swirl return cwp; 114070af384SBlue Swirl } 115070af384SBlue Swirl 116c5f9864eSAndreas Färber int cpu_cwp_dec(CPUSPARCState *env, int cwp) 117070af384SBlue Swirl { 118070af384SBlue Swirl if (unlikely(cwp < 0)) { 119070af384SBlue Swirl cwp += env->nwindows; 120070af384SBlue Swirl } 121070af384SBlue Swirl return cwp; 122070af384SBlue Swirl } 123070af384SBlue Swirl 124070af384SBlue Swirl #ifndef TARGET_SPARC64 125c5f9864eSAndreas Färber void helper_rett(CPUSPARCState *env) 126070af384SBlue Swirl { 127070af384SBlue Swirl unsigned int cwp; 128070af384SBlue Swirl 129070af384SBlue Swirl if (env->psret == 1) { 1302f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 131070af384SBlue Swirl } 132070af384SBlue Swirl 133070af384SBlue Swirl env->psret = 1; 134063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1) ; 135070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1362f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 137070af384SBlue Swirl } 138063c3675SBlue Swirl cpu_set_cwp(env, cwp); 139070af384SBlue Swirl env->psrs = env->psrps; 140070af384SBlue Swirl } 141070af384SBlue Swirl 142070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 143070af384SBlue Swirl handling ? */ 144c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 145070af384SBlue Swirl { 146070af384SBlue Swirl uint32_t cwp; 147070af384SBlue Swirl 148063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 149070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1502f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_OVF, GETPC()); 151070af384SBlue Swirl } 152063c3675SBlue Swirl cpu_set_cwp(env, cwp); 153070af384SBlue Swirl } 154070af384SBlue Swirl 155c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 156070af384SBlue Swirl { 157070af384SBlue Swirl uint32_t cwp; 158070af384SBlue Swirl 159063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 160070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1612f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 162070af384SBlue Swirl } 163063c3675SBlue Swirl cpu_set_cwp(env, cwp); 164070af384SBlue Swirl } 165070af384SBlue Swirl 166c5f9864eSAndreas Färber void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) 167070af384SBlue Swirl { 168070af384SBlue Swirl if ((new_psr & PSR_CWP) >= env->nwindows) { 1692f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 170070af384SBlue Swirl } else { 1715ee59930SAlex Bennée /* cpu_put_psr may trigger interrupts, hence BQL */ 172195801d7SStefan Hajnoczi bql_lock(); 173070af384SBlue Swirl cpu_put_psr(env, new_psr); 174195801d7SStefan Hajnoczi bql_unlock(); 175070af384SBlue Swirl } 176070af384SBlue Swirl } 177070af384SBlue Swirl 178c5f9864eSAndreas Färber target_ulong helper_rdpsr(CPUSPARCState *env) 179070af384SBlue Swirl { 180063c3675SBlue Swirl return cpu_get_psr(env); 181070af384SBlue Swirl } 182070af384SBlue Swirl 183070af384SBlue Swirl #else 184070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 185070af384SBlue Swirl handling ? */ 186c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 187070af384SBlue Swirl { 188070af384SBlue Swirl uint32_t cwp; 189070af384SBlue Swirl 190063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 191070af384SBlue Swirl if (env->cansave == 0) { 1922f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 1932f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 1942f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 1952f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 196070af384SBlue Swirl } else { 197070af384SBlue Swirl if (env->cleanwin - env->canrestore == 0) { 198070af384SBlue Swirl /* XXX Clean windows without trap */ 1992f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_CLRWIN, GETPC()); 200070af384SBlue Swirl } else { 201070af384SBlue Swirl env->cansave--; 202070af384SBlue Swirl env->canrestore++; 203063c3675SBlue Swirl cpu_set_cwp(env, cwp); 204070af384SBlue Swirl } 205070af384SBlue Swirl } 206070af384SBlue Swirl } 207070af384SBlue Swirl 208c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 209070af384SBlue Swirl { 210070af384SBlue Swirl uint32_t cwp; 211070af384SBlue Swirl 212063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 213070af384SBlue Swirl if (env->canrestore == 0) { 2142f9d35fcSRichard Henderson int tt = TT_FILL | (env->otherwin != 0 2152f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2162f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2172f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 218070af384SBlue Swirl } else { 219070af384SBlue Swirl env->cansave++; 220070af384SBlue Swirl env->canrestore--; 221063c3675SBlue Swirl cpu_set_cwp(env, cwp); 222070af384SBlue Swirl } 223070af384SBlue Swirl } 224070af384SBlue Swirl 225c5f9864eSAndreas Färber void helper_flushw(CPUSPARCState *env) 226070af384SBlue Swirl { 227070af384SBlue Swirl if (env->cansave != env->nwindows - 2) { 2282f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 2292f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2302f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2312f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 232070af384SBlue Swirl } 233070af384SBlue Swirl } 234070af384SBlue Swirl 235c5f9864eSAndreas Färber void helper_saved(CPUSPARCState *env) 236070af384SBlue Swirl { 237070af384SBlue Swirl env->cansave++; 238070af384SBlue Swirl if (env->otherwin == 0) { 239070af384SBlue Swirl env->canrestore--; 240070af384SBlue Swirl } else { 241070af384SBlue Swirl env->otherwin--; 242070af384SBlue Swirl } 243070af384SBlue Swirl } 244070af384SBlue Swirl 245c5f9864eSAndreas Färber void helper_restored(CPUSPARCState *env) 246070af384SBlue Swirl { 247070af384SBlue Swirl env->canrestore++; 248070af384SBlue Swirl if (env->cleanwin < env->nwindows - 1) { 249070af384SBlue Swirl env->cleanwin++; 250070af384SBlue Swirl } 251070af384SBlue Swirl if (env->otherwin == 0) { 252070af384SBlue Swirl env->cansave--; 253070af384SBlue Swirl } else { 254070af384SBlue Swirl env->otherwin--; 255070af384SBlue Swirl } 256070af384SBlue Swirl } 257070af384SBlue Swirl 258c5f9864eSAndreas Färber target_ulong cpu_get_ccr(CPUSPARCState *env) 259070af384SBlue Swirl { 2602a1905c7SRichard Henderson target_ulong ccr = 0; 261070af384SBlue Swirl 2622a1905c7SRichard Henderson ccr |= (env->icc_C >> 32) & 1; 2632a1905c7SRichard Henderson ccr |= ((int32_t)env->cc_V < 0) << 1; 2642a1905c7SRichard Henderson ccr |= ((int32_t)env->icc_Z == 0) << 2; 2652a1905c7SRichard Henderson ccr |= ((int32_t)env->cc_N < 0) << 3; 2662a1905c7SRichard Henderson 2672a1905c7SRichard Henderson ccr |= env->xcc_C << 4; 2682a1905c7SRichard Henderson ccr |= (env->cc_V < 0) << 5; 2692a1905c7SRichard Henderson ccr |= (env->xcc_Z == 0) << 6; 2702a1905c7SRichard Henderson ccr |= (env->cc_N < 0) << 7; 2712a1905c7SRichard Henderson 2722a1905c7SRichard Henderson return ccr; 273070af384SBlue Swirl } 274070af384SBlue Swirl 275c5f9864eSAndreas Färber void cpu_put_ccr(CPUSPARCState *env, target_ulong val) 276070af384SBlue Swirl { 2772a1905c7SRichard Henderson env->cc_N = deposit64(-(val & 0x08), 32, 32, -(val & 0x80)); 2782a1905c7SRichard Henderson env->cc_V = deposit64(-(val & 0x02), 32, 32, -(val & 0x20)); 2792a1905c7SRichard Henderson env->icc_C = (uint64_t)val << 32; 2802a1905c7SRichard Henderson env->xcc_C = (val >> 4) & 1; 2812a1905c7SRichard Henderson env->icc_Z = ~val & 0x04; 2822a1905c7SRichard Henderson env->xcc_Z = ~val & 0x40; 283070af384SBlue Swirl } 284070af384SBlue Swirl 285c5f9864eSAndreas Färber target_ulong cpu_get_cwp64(CPUSPARCState *env) 286070af384SBlue Swirl { 287070af384SBlue Swirl return env->nwindows - 1 - env->cwp; 288070af384SBlue Swirl } 289070af384SBlue Swirl 290c5f9864eSAndreas Färber void cpu_put_cwp64(CPUSPARCState *env, int cwp) 291070af384SBlue Swirl { 292070af384SBlue Swirl if (unlikely(cwp >= env->nwindows || cwp < 0)) { 293070af384SBlue Swirl cwp %= env->nwindows; 294070af384SBlue Swirl } 295063c3675SBlue Swirl cpu_set_cwp(env, env->nwindows - 1 - cwp); 296070af384SBlue Swirl } 297070af384SBlue Swirl 298c5f9864eSAndreas Färber target_ulong helper_rdccr(CPUSPARCState *env) 299070af384SBlue Swirl { 300063c3675SBlue Swirl return cpu_get_ccr(env); 301070af384SBlue Swirl } 302070af384SBlue Swirl 303c5f9864eSAndreas Färber void helper_wrccr(CPUSPARCState *env, target_ulong new_ccr) 304070af384SBlue Swirl { 305063c3675SBlue Swirl cpu_put_ccr(env, new_ccr); 306070af384SBlue Swirl } 307070af384SBlue Swirl 308070af384SBlue Swirl /* CWP handling is reversed in V9, but we still use the V8 register 309070af384SBlue Swirl order. */ 310c5f9864eSAndreas Färber target_ulong helper_rdcwp(CPUSPARCState *env) 311070af384SBlue Swirl { 312063c3675SBlue Swirl return cpu_get_cwp64(env); 313070af384SBlue Swirl } 314070af384SBlue Swirl 315c5f9864eSAndreas Färber void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp) 316070af384SBlue Swirl { 317063c3675SBlue Swirl cpu_put_cwp64(env, new_cwp); 318070af384SBlue Swirl } 319070af384SBlue Swirl 320c5f9864eSAndreas Färber static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) 321070af384SBlue Swirl { 322576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 323cbc3a6a4SArtyom Tarasenko return env->glregs + (env->gl & 7) * 8; 324cbc3a6a4SArtyom Tarasenko } 325cbc3a6a4SArtyom Tarasenko 326070af384SBlue Swirl switch (pstate) { 327070af384SBlue Swirl default: 328870be6adSBlue Swirl trace_win_helper_gregset_error(pstate); 3299cf5a9cfSChen Qun /* fall through to normal set of global registers */ 330070af384SBlue Swirl case 0: 331070af384SBlue Swirl return env->bgregs; 332070af384SBlue Swirl case PS_AG: 333070af384SBlue Swirl return env->agregs; 334070af384SBlue Swirl case PS_MG: 335070af384SBlue Swirl return env->mgregs; 336070af384SBlue Swirl case PS_IG: 337070af384SBlue Swirl return env->igregs; 338070af384SBlue Swirl } 339070af384SBlue Swirl } 340070af384SBlue Swirl 341cbc3a6a4SArtyom Tarasenko static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl) 342cbc3a6a4SArtyom Tarasenko { 343cbc3a6a4SArtyom Tarasenko return env->glregs + (gl & 7) * 8; 344cbc3a6a4SArtyom Tarasenko } 345cbc3a6a4SArtyom Tarasenko 346cbc3a6a4SArtyom Tarasenko /* Switch global register bank */ 347cbc3a6a4SArtyom Tarasenko void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl) 348cbc3a6a4SArtyom Tarasenko { 349cbc3a6a4SArtyom Tarasenko uint64_t *src, *dst; 350cbc3a6a4SArtyom Tarasenko src = get_gl_gregset(env, new_gl); 351cbc3a6a4SArtyom Tarasenko dst = get_gl_gregset(env, env->gl); 352cbc3a6a4SArtyom Tarasenko 353cbc3a6a4SArtyom Tarasenko if (src != dst) { 354*7ac87b14SPhilippe Mathieu-Daudé memcpy(dst, env->gregs, sizeof(env->gregs)); 355*7ac87b14SPhilippe Mathieu-Daudé memcpy(env->gregs, src, sizeof(env->gregs)); 356cbc3a6a4SArtyom Tarasenko } 357cbc3a6a4SArtyom Tarasenko } 358cbc3a6a4SArtyom Tarasenko 359cbc3a6a4SArtyom Tarasenko void helper_wrgl(CPUSPARCState *env, target_ulong new_gl) 360cbc3a6a4SArtyom Tarasenko { 361cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl & 7); 362cbc3a6a4SArtyom Tarasenko env->gl = new_gl & 7; 363cbc3a6a4SArtyom Tarasenko } 364cbc3a6a4SArtyom Tarasenko 365c5f9864eSAndreas Färber void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) 366070af384SBlue Swirl { 367070af384SBlue Swirl uint32_t pstate_regs, new_pstate_regs; 368070af384SBlue Swirl uint64_t *src, *dst; 369070af384SBlue Swirl 370576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 371cbc3a6a4SArtyom Tarasenko /* PS_AG, IG and MG are not implemented in this case */ 372cbc3a6a4SArtyom Tarasenko new_pstate &= ~(PS_AG | PS_IG | PS_MG); 373cbc3a6a4SArtyom Tarasenko env->pstate = new_pstate; 374cbc3a6a4SArtyom Tarasenko return; 375070af384SBlue Swirl } 376070af384SBlue Swirl 377070af384SBlue Swirl pstate_regs = env->pstate & 0xc01; 378070af384SBlue Swirl new_pstate_regs = new_pstate & 0xc01; 379070af384SBlue Swirl 380070af384SBlue Swirl if (new_pstate_regs != pstate_regs) { 381870be6adSBlue Swirl trace_win_helper_switch_pstate(pstate_regs, new_pstate_regs); 382870be6adSBlue Swirl 383070af384SBlue Swirl /* Switch global register bank */ 384063c3675SBlue Swirl src = get_gregset(env, new_pstate_regs); 385063c3675SBlue Swirl dst = get_gregset(env, pstate_regs); 386*7ac87b14SPhilippe Mathieu-Daudé memcpy(dst, env->gregs, sizeof(env->gregs)); 387*7ac87b14SPhilippe Mathieu-Daudé memcpy(env->gregs, src, sizeof(env->gregs)); 388070af384SBlue Swirl } else { 389870be6adSBlue Swirl trace_win_helper_no_switch_pstate(new_pstate_regs); 390070af384SBlue Swirl } 391070af384SBlue Swirl env->pstate = new_pstate; 392070af384SBlue Swirl } 393070af384SBlue Swirl 394c5f9864eSAndreas Färber void helper_wrpstate(CPUSPARCState *env, target_ulong new_state) 395070af384SBlue Swirl { 396063c3675SBlue Swirl cpu_change_pstate(env, new_state & 0xf3f); 397070af384SBlue Swirl 398070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 399070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 400195801d7SStefan Hajnoczi bql_lock(); 401070af384SBlue Swirl cpu_check_irqs(env); 402195801d7SStefan Hajnoczi bql_unlock(); 403070af384SBlue Swirl } 404070af384SBlue Swirl #endif 405070af384SBlue Swirl } 406070af384SBlue Swirl 407c5f9864eSAndreas Färber void helper_wrpil(CPUSPARCState *env, target_ulong new_pil) 408070af384SBlue Swirl { 409070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 410870be6adSBlue Swirl trace_win_helper_wrpil(env->psrpil, (uint32_t)new_pil); 411070af384SBlue Swirl 412070af384SBlue Swirl env->psrpil = new_pil; 413070af384SBlue Swirl 414070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 415195801d7SStefan Hajnoczi bql_lock(); 416070af384SBlue Swirl cpu_check_irqs(env); 417195801d7SStefan Hajnoczi bql_unlock(); 418070af384SBlue Swirl } 419070af384SBlue Swirl #endif 420070af384SBlue Swirl } 421070af384SBlue Swirl 422c5f9864eSAndreas Färber void helper_done(CPUSPARCState *env) 423070af384SBlue Swirl { 424070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 425070af384SBlue Swirl 426070af384SBlue Swirl env->pc = tsptr->tnpc; 427070af384SBlue Swirl env->npc = tsptr->tnpc + 4; 428063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 429070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 430063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 431063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4326e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 433cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4346e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 435cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 436cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4376e040755SArtyom Tarasenko } 438070af384SBlue Swirl env->tl--; 439070af384SBlue Swirl 440870be6adSBlue Swirl trace_win_helper_done(env->tl); 441070af384SBlue Swirl 442070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 443070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 444195801d7SStefan Hajnoczi bql_lock(); 445070af384SBlue Swirl cpu_check_irqs(env); 446195801d7SStefan Hajnoczi bql_unlock(); 447070af384SBlue Swirl } 448070af384SBlue Swirl #endif 449070af384SBlue Swirl } 450070af384SBlue Swirl 451c5f9864eSAndreas Färber void helper_retry(CPUSPARCState *env) 452070af384SBlue Swirl { 453070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 454070af384SBlue Swirl 455070af384SBlue Swirl env->pc = tsptr->tpc; 456070af384SBlue Swirl env->npc = tsptr->tnpc; 457063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 458070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 459063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 460063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4616e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 462cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4636e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 464cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 465cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4666e040755SArtyom Tarasenko } 467070af384SBlue Swirl env->tl--; 468070af384SBlue Swirl 469870be6adSBlue Swirl trace_win_helper_retry(env->tl); 470070af384SBlue Swirl 471070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 472070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 473195801d7SStefan Hajnoczi bql_lock(); 474070af384SBlue Swirl cpu_check_irqs(env); 475195801d7SStefan Hajnoczi bql_unlock(); 476070af384SBlue Swirl } 477070af384SBlue Swirl #endif 478070af384SBlue Swirl } 479070af384SBlue Swirl #endif 480