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 { 56*2a1905c7SRichard Henderson target_ulong icc = 0; 57*2a1905c7SRichard Henderson 58070af384SBlue Swirl helper_compute_psr(env); 59070af384SBlue Swirl 60*2a1905c7SRichard Henderson icc |= ((int32_t)env->cc_N < 0) << PSR_NEG_SHIFT; 61*2a1905c7SRichard Henderson icc |= ((int32_t)env->cc_V < 0) << PSR_OVF_SHIFT; 62*2a1905c7SRichard Henderson icc |= ((int32_t)env->icc_Z == 0) << PSR_ZERO_SHIFT; 63*2a1905c7SRichard Henderson if (TARGET_LONG_BITS == 64) { 64*2a1905c7SRichard Henderson icc |= extract64(env->icc_C, 32, 1) << PSR_CARRY_SHIFT; 65*2a1905c7SRichard Henderson } else { 66*2a1905c7SRichard Henderson icc |= env->icc_C << PSR_CARRY_SHIFT; 67*2a1905c7SRichard Henderson } 68*2a1905c7SRichard Henderson 69070af384SBlue Swirl #if !defined(TARGET_SPARC64) 70*2a1905c7SRichard Henderson return env->version | icc | 71070af384SBlue Swirl (env->psref ? PSR_EF : 0) | 72070af384SBlue Swirl (env->psrpil << 8) | 73070af384SBlue Swirl (env->psrs ? PSR_S : 0) | 74070af384SBlue Swirl (env->psrps ? PSR_PS : 0) | 75070af384SBlue Swirl (env->psret ? PSR_ET : 0) | env->cwp; 76070af384SBlue Swirl #else 77*2a1905c7SRichard Henderson return icc; 78070af384SBlue Swirl #endif 79070af384SBlue Swirl } 80070af384SBlue Swirl 81b1fa27fcSRichard Henderson void cpu_put_psr_icc(CPUSPARCState *env, target_ulong val) 82070af384SBlue Swirl { 83*2a1905c7SRichard Henderson if (TARGET_LONG_BITS == 64) { 84*2a1905c7SRichard Henderson /* Do not clobber xcc.[NV] */ 85*2a1905c7SRichard Henderson env->cc_N = deposit64(env->cc_N, 0, 32, -(val & PSR_NEG)); 86*2a1905c7SRichard Henderson env->cc_V = deposit64(env->cc_V, 0, 32, -(val & PSR_OVF)); 87*2a1905c7SRichard Henderson env->icc_C = -(val & PSR_CARRY); 88*2a1905c7SRichard Henderson } else { 89*2a1905c7SRichard Henderson env->cc_N = -(val & PSR_NEG); 90*2a1905c7SRichard Henderson env->cc_V = -(val & PSR_OVF); 91*2a1905c7SRichard Henderson env->icc_C = (val >> PSR_CARRY_SHIFT) & 1; 92*2a1905c7SRichard Henderson } 93*2a1905c7SRichard Henderson env->icc_Z = ~val & PSR_ZERO; 94b1fa27fcSRichard Henderson } 95b1fa27fcSRichard Henderson 96b1fa27fcSRichard Henderson void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val) 97b1fa27fcSRichard Henderson { 98b1fa27fcSRichard Henderson cpu_put_psr_icc(env, val); 99070af384SBlue Swirl #if !defined(TARGET_SPARC64) 100070af384SBlue Swirl env->psref = (val & PSR_EF) ? 1 : 0; 101070af384SBlue Swirl env->psrpil = (val & PSR_PIL) >> 8; 102070af384SBlue Swirl env->psrs = (val & PSR_S) ? 1 : 0; 103070af384SBlue Swirl env->psrps = (val & PSR_PS) ? 1 : 0; 104070af384SBlue Swirl env->psret = (val & PSR_ET) ? 1 : 0; 105070af384SBlue Swirl #endif 106070af384SBlue Swirl env->cc_op = CC_OP_FLAGS; 1074552a09dSPeter Maydell #if !defined(TARGET_SPARC64) 1084552a09dSPeter Maydell cpu_set_cwp(env, val & PSR_CWP); 1094552a09dSPeter Maydell #endif 1104552a09dSPeter Maydell } 1114552a09dSPeter Maydell 1125ee59930SAlex Bennée /* Called with BQL held */ 1134552a09dSPeter Maydell void cpu_put_psr(CPUSPARCState *env, target_ulong val) 1144552a09dSPeter Maydell { 1154552a09dSPeter Maydell cpu_put_psr_raw(env, val); 1164552a09dSPeter Maydell #if ((!defined(TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY)) 1174552a09dSPeter Maydell cpu_check_irqs(env); 1184552a09dSPeter Maydell #endif 119070af384SBlue Swirl } 120070af384SBlue Swirl 121c5f9864eSAndreas Färber int cpu_cwp_inc(CPUSPARCState *env, int cwp) 122070af384SBlue Swirl { 123070af384SBlue Swirl if (unlikely(cwp >= env->nwindows)) { 124070af384SBlue Swirl cwp -= env->nwindows; 125070af384SBlue Swirl } 126070af384SBlue Swirl return cwp; 127070af384SBlue Swirl } 128070af384SBlue Swirl 129c5f9864eSAndreas Färber int cpu_cwp_dec(CPUSPARCState *env, int cwp) 130070af384SBlue Swirl { 131070af384SBlue Swirl if (unlikely(cwp < 0)) { 132070af384SBlue Swirl cwp += env->nwindows; 133070af384SBlue Swirl } 134070af384SBlue Swirl return cwp; 135070af384SBlue Swirl } 136070af384SBlue Swirl 137070af384SBlue Swirl #ifndef TARGET_SPARC64 138c5f9864eSAndreas Färber void helper_rett(CPUSPARCState *env) 139070af384SBlue Swirl { 140070af384SBlue Swirl unsigned int cwp; 141070af384SBlue Swirl 142070af384SBlue Swirl if (env->psret == 1) { 1432f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 144070af384SBlue Swirl } 145070af384SBlue Swirl 146070af384SBlue Swirl env->psret = 1; 147063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1) ; 148070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1492f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 150070af384SBlue Swirl } 151063c3675SBlue Swirl cpu_set_cwp(env, cwp); 152070af384SBlue Swirl env->psrs = env->psrps; 153070af384SBlue Swirl } 154070af384SBlue Swirl 155070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 156070af384SBlue Swirl handling ? */ 157c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 158070af384SBlue Swirl { 159070af384SBlue Swirl uint32_t cwp; 160070af384SBlue Swirl 161063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 162070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1632f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_OVF, GETPC()); 164070af384SBlue Swirl } 165063c3675SBlue Swirl cpu_set_cwp(env, cwp); 166070af384SBlue Swirl } 167070af384SBlue Swirl 168c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 169070af384SBlue Swirl { 170070af384SBlue Swirl uint32_t cwp; 171070af384SBlue Swirl 172063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 173070af384SBlue Swirl if (env->wim & (1 << cwp)) { 1742f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); 175070af384SBlue Swirl } 176063c3675SBlue Swirl cpu_set_cwp(env, cwp); 177070af384SBlue Swirl } 178070af384SBlue Swirl 179c5f9864eSAndreas Färber void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) 180070af384SBlue Swirl { 181070af384SBlue Swirl if ((new_psr & PSR_CWP) >= env->nwindows) { 1822f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); 183070af384SBlue Swirl } else { 1845ee59930SAlex Bennée /* cpu_put_psr may trigger interrupts, hence BQL */ 1855ee59930SAlex Bennée qemu_mutex_lock_iothread(); 186070af384SBlue Swirl cpu_put_psr(env, new_psr); 1875ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 188070af384SBlue Swirl } 189070af384SBlue Swirl } 190070af384SBlue Swirl 191c5f9864eSAndreas Färber target_ulong helper_rdpsr(CPUSPARCState *env) 192070af384SBlue Swirl { 193063c3675SBlue Swirl return cpu_get_psr(env); 194070af384SBlue Swirl } 195070af384SBlue Swirl 196070af384SBlue Swirl #else 197070af384SBlue Swirl /* XXX: use another pointer for %iN registers to avoid slow wrapping 198070af384SBlue Swirl handling ? */ 199c5f9864eSAndreas Färber void helper_save(CPUSPARCState *env) 200070af384SBlue Swirl { 201070af384SBlue Swirl uint32_t cwp; 202070af384SBlue Swirl 203063c3675SBlue Swirl cwp = cpu_cwp_dec(env, env->cwp - 1); 204070af384SBlue Swirl if (env->cansave == 0) { 2052f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 2062f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2072f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2082f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 209070af384SBlue Swirl } else { 210070af384SBlue Swirl if (env->cleanwin - env->canrestore == 0) { 211070af384SBlue Swirl /* XXX Clean windows without trap */ 2122f9d35fcSRichard Henderson cpu_raise_exception_ra(env, TT_CLRWIN, GETPC()); 213070af384SBlue Swirl } else { 214070af384SBlue Swirl env->cansave--; 215070af384SBlue Swirl env->canrestore++; 216063c3675SBlue Swirl cpu_set_cwp(env, cwp); 217070af384SBlue Swirl } 218070af384SBlue Swirl } 219070af384SBlue Swirl } 220070af384SBlue Swirl 221c5f9864eSAndreas Färber void helper_restore(CPUSPARCState *env) 222070af384SBlue Swirl { 223070af384SBlue Swirl uint32_t cwp; 224070af384SBlue Swirl 225063c3675SBlue Swirl cwp = cpu_cwp_inc(env, env->cwp + 1); 226070af384SBlue Swirl if (env->canrestore == 0) { 2272f9d35fcSRichard Henderson int tt = TT_FILL | (env->otherwin != 0 2282f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2292f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2302f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 231070af384SBlue Swirl } else { 232070af384SBlue Swirl env->cansave++; 233070af384SBlue Swirl env->canrestore--; 234063c3675SBlue Swirl cpu_set_cwp(env, cwp); 235070af384SBlue Swirl } 236070af384SBlue Swirl } 237070af384SBlue Swirl 238c5f9864eSAndreas Färber void helper_flushw(CPUSPARCState *env) 239070af384SBlue Swirl { 240070af384SBlue Swirl if (env->cansave != env->nwindows - 2) { 2412f9d35fcSRichard Henderson int tt = TT_SPILL | (env->otherwin != 0 2422f9d35fcSRichard Henderson ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) 2432f9d35fcSRichard Henderson : ((env->wstate & 0x7) << 2)); 2442f9d35fcSRichard Henderson cpu_raise_exception_ra(env, tt, GETPC()); 245070af384SBlue Swirl } 246070af384SBlue Swirl } 247070af384SBlue Swirl 248c5f9864eSAndreas Färber void helper_saved(CPUSPARCState *env) 249070af384SBlue Swirl { 250070af384SBlue Swirl env->cansave++; 251070af384SBlue Swirl if (env->otherwin == 0) { 252070af384SBlue Swirl env->canrestore--; 253070af384SBlue Swirl } else { 254070af384SBlue Swirl env->otherwin--; 255070af384SBlue Swirl } 256070af384SBlue Swirl } 257070af384SBlue Swirl 258c5f9864eSAndreas Färber void helper_restored(CPUSPARCState *env) 259070af384SBlue Swirl { 260070af384SBlue Swirl env->canrestore++; 261070af384SBlue Swirl if (env->cleanwin < env->nwindows - 1) { 262070af384SBlue Swirl env->cleanwin++; 263070af384SBlue Swirl } 264070af384SBlue Swirl if (env->otherwin == 0) { 265070af384SBlue Swirl env->cansave--; 266070af384SBlue Swirl } else { 267070af384SBlue Swirl env->otherwin--; 268070af384SBlue Swirl } 269070af384SBlue Swirl } 270070af384SBlue Swirl 271c5f9864eSAndreas Färber target_ulong cpu_get_ccr(CPUSPARCState *env) 272070af384SBlue Swirl { 273*2a1905c7SRichard Henderson target_ulong ccr = 0; 274070af384SBlue Swirl 275*2a1905c7SRichard Henderson helper_compute_psr(env); 276070af384SBlue Swirl 277*2a1905c7SRichard Henderson ccr |= (env->icc_C >> 32) & 1; 278*2a1905c7SRichard Henderson ccr |= ((int32_t)env->cc_V < 0) << 1; 279*2a1905c7SRichard Henderson ccr |= ((int32_t)env->icc_Z == 0) << 2; 280*2a1905c7SRichard Henderson ccr |= ((int32_t)env->cc_N < 0) << 3; 281*2a1905c7SRichard Henderson 282*2a1905c7SRichard Henderson ccr |= env->xcc_C << 4; 283*2a1905c7SRichard Henderson ccr |= (env->cc_V < 0) << 5; 284*2a1905c7SRichard Henderson ccr |= (env->xcc_Z == 0) << 6; 285*2a1905c7SRichard Henderson ccr |= (env->cc_N < 0) << 7; 286*2a1905c7SRichard Henderson 287*2a1905c7SRichard Henderson return ccr; 288070af384SBlue Swirl } 289070af384SBlue Swirl 290c5f9864eSAndreas Färber void cpu_put_ccr(CPUSPARCState *env, target_ulong val) 291070af384SBlue Swirl { 292*2a1905c7SRichard Henderson env->cc_N = deposit64(-(val & 0x08), 32, 32, -(val & 0x80)); 293*2a1905c7SRichard Henderson env->cc_V = deposit64(-(val & 0x02), 32, 32, -(val & 0x20)); 294*2a1905c7SRichard Henderson env->icc_C = (uint64_t)val << 32; 295*2a1905c7SRichard Henderson env->xcc_C = (val >> 4) & 1; 296*2a1905c7SRichard Henderson env->icc_Z = ~val & 0x04; 297*2a1905c7SRichard Henderson env->xcc_Z = ~val & 0x40; 298*2a1905c7SRichard Henderson 299070af384SBlue Swirl CC_OP = CC_OP_FLAGS; 300070af384SBlue Swirl } 301070af384SBlue Swirl 302c5f9864eSAndreas Färber target_ulong cpu_get_cwp64(CPUSPARCState *env) 303070af384SBlue Swirl { 304070af384SBlue Swirl return env->nwindows - 1 - env->cwp; 305070af384SBlue Swirl } 306070af384SBlue Swirl 307c5f9864eSAndreas Färber void cpu_put_cwp64(CPUSPARCState *env, int cwp) 308070af384SBlue Swirl { 309070af384SBlue Swirl if (unlikely(cwp >= env->nwindows || cwp < 0)) { 310070af384SBlue Swirl cwp %= env->nwindows; 311070af384SBlue Swirl } 312063c3675SBlue Swirl cpu_set_cwp(env, env->nwindows - 1 - cwp); 313070af384SBlue Swirl } 314070af384SBlue Swirl 315c5f9864eSAndreas Färber target_ulong helper_rdccr(CPUSPARCState *env) 316070af384SBlue Swirl { 317063c3675SBlue Swirl return cpu_get_ccr(env); 318070af384SBlue Swirl } 319070af384SBlue Swirl 320c5f9864eSAndreas Färber void helper_wrccr(CPUSPARCState *env, target_ulong new_ccr) 321070af384SBlue Swirl { 322063c3675SBlue Swirl cpu_put_ccr(env, new_ccr); 323070af384SBlue Swirl } 324070af384SBlue Swirl 325070af384SBlue Swirl /* CWP handling is reversed in V9, but we still use the V8 register 326070af384SBlue Swirl order. */ 327c5f9864eSAndreas Färber target_ulong helper_rdcwp(CPUSPARCState *env) 328070af384SBlue Swirl { 329063c3675SBlue Swirl return cpu_get_cwp64(env); 330070af384SBlue Swirl } 331070af384SBlue Swirl 332c5f9864eSAndreas Färber void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp) 333070af384SBlue Swirl { 334063c3675SBlue Swirl cpu_put_cwp64(env, new_cwp); 335070af384SBlue Swirl } 336070af384SBlue Swirl 337c5f9864eSAndreas Färber static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) 338070af384SBlue Swirl { 339576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 340cbc3a6a4SArtyom Tarasenko return env->glregs + (env->gl & 7) * 8; 341cbc3a6a4SArtyom Tarasenko } 342cbc3a6a4SArtyom Tarasenko 343070af384SBlue Swirl switch (pstate) { 344070af384SBlue Swirl default: 345870be6adSBlue Swirl trace_win_helper_gregset_error(pstate); 3469cf5a9cfSChen Qun /* fall through to normal set of global registers */ 347070af384SBlue Swirl case 0: 348070af384SBlue Swirl return env->bgregs; 349070af384SBlue Swirl case PS_AG: 350070af384SBlue Swirl return env->agregs; 351070af384SBlue Swirl case PS_MG: 352070af384SBlue Swirl return env->mgregs; 353070af384SBlue Swirl case PS_IG: 354070af384SBlue Swirl return env->igregs; 355070af384SBlue Swirl } 356070af384SBlue Swirl } 357070af384SBlue Swirl 358cbc3a6a4SArtyom Tarasenko static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl) 359cbc3a6a4SArtyom Tarasenko { 360cbc3a6a4SArtyom Tarasenko return env->glregs + (gl & 7) * 8; 361cbc3a6a4SArtyom Tarasenko } 362cbc3a6a4SArtyom Tarasenko 363cbc3a6a4SArtyom Tarasenko /* Switch global register bank */ 364cbc3a6a4SArtyom Tarasenko void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl) 365cbc3a6a4SArtyom Tarasenko { 366cbc3a6a4SArtyom Tarasenko uint64_t *src, *dst; 367cbc3a6a4SArtyom Tarasenko src = get_gl_gregset(env, new_gl); 368cbc3a6a4SArtyom Tarasenko dst = get_gl_gregset(env, env->gl); 369cbc3a6a4SArtyom Tarasenko 370cbc3a6a4SArtyom Tarasenko if (src != dst) { 371cbc3a6a4SArtyom Tarasenko memcpy32(dst, env->gregs); 372cbc3a6a4SArtyom Tarasenko memcpy32(env->gregs, src); 373cbc3a6a4SArtyom Tarasenko } 374cbc3a6a4SArtyom Tarasenko } 375cbc3a6a4SArtyom Tarasenko 376cbc3a6a4SArtyom Tarasenko void helper_wrgl(CPUSPARCState *env, target_ulong new_gl) 377cbc3a6a4SArtyom Tarasenko { 378cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl & 7); 379cbc3a6a4SArtyom Tarasenko env->gl = new_gl & 7; 380cbc3a6a4SArtyom Tarasenko } 381cbc3a6a4SArtyom Tarasenko 382c5f9864eSAndreas Färber void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) 383070af384SBlue Swirl { 384070af384SBlue Swirl uint32_t pstate_regs, new_pstate_regs; 385070af384SBlue Swirl uint64_t *src, *dst; 386070af384SBlue Swirl 387576e1c4cSIgor Mammedov if (env->def.features & CPU_FEATURE_GL) { 388cbc3a6a4SArtyom Tarasenko /* PS_AG, IG and MG are not implemented in this case */ 389cbc3a6a4SArtyom Tarasenko new_pstate &= ~(PS_AG | PS_IG | PS_MG); 390cbc3a6a4SArtyom Tarasenko env->pstate = new_pstate; 391cbc3a6a4SArtyom Tarasenko return; 392070af384SBlue Swirl } 393070af384SBlue Swirl 394070af384SBlue Swirl pstate_regs = env->pstate & 0xc01; 395070af384SBlue Swirl new_pstate_regs = new_pstate & 0xc01; 396070af384SBlue Swirl 397070af384SBlue Swirl if (new_pstate_regs != pstate_regs) { 398870be6adSBlue Swirl trace_win_helper_switch_pstate(pstate_regs, new_pstate_regs); 399870be6adSBlue Swirl 400070af384SBlue Swirl /* Switch global register bank */ 401063c3675SBlue Swirl src = get_gregset(env, new_pstate_regs); 402063c3675SBlue Swirl dst = get_gregset(env, pstate_regs); 403070af384SBlue Swirl memcpy32(dst, env->gregs); 404070af384SBlue Swirl memcpy32(env->gregs, src); 405070af384SBlue Swirl } else { 406870be6adSBlue Swirl trace_win_helper_no_switch_pstate(new_pstate_regs); 407070af384SBlue Swirl } 408070af384SBlue Swirl env->pstate = new_pstate; 409070af384SBlue Swirl } 410070af384SBlue Swirl 411c5f9864eSAndreas Färber void helper_wrpstate(CPUSPARCState *env, target_ulong new_state) 412070af384SBlue Swirl { 413063c3675SBlue Swirl cpu_change_pstate(env, new_state & 0xf3f); 414070af384SBlue Swirl 415070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 416070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4175ee59930SAlex Bennée qemu_mutex_lock_iothread(); 418070af384SBlue Swirl cpu_check_irqs(env); 4195ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 420070af384SBlue Swirl } 421070af384SBlue Swirl #endif 422070af384SBlue Swirl } 423070af384SBlue Swirl 424c5f9864eSAndreas Färber void helper_wrpil(CPUSPARCState *env, target_ulong new_pil) 425070af384SBlue Swirl { 426070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 427870be6adSBlue Swirl trace_win_helper_wrpil(env->psrpil, (uint32_t)new_pil); 428070af384SBlue Swirl 429070af384SBlue Swirl env->psrpil = new_pil; 430070af384SBlue Swirl 431070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4325ee59930SAlex Bennée qemu_mutex_lock_iothread(); 433070af384SBlue Swirl cpu_check_irqs(env); 4345ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 435070af384SBlue Swirl } 436070af384SBlue Swirl #endif 437070af384SBlue Swirl } 438070af384SBlue Swirl 439c5f9864eSAndreas Färber void helper_done(CPUSPARCState *env) 440070af384SBlue Swirl { 441070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 442070af384SBlue Swirl 443070af384SBlue Swirl env->pc = tsptr->tnpc; 444070af384SBlue Swirl env->npc = tsptr->tnpc + 4; 445063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 446070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 447063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 448063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4496e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 450cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4516e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 452cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 453cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4546e040755SArtyom Tarasenko } 455070af384SBlue Swirl env->tl--; 456070af384SBlue Swirl 457870be6adSBlue Swirl trace_win_helper_done(env->tl); 458070af384SBlue Swirl 459070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 460070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4615ee59930SAlex Bennée qemu_mutex_lock_iothread(); 462070af384SBlue Swirl cpu_check_irqs(env); 4635ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 464070af384SBlue Swirl } 465070af384SBlue Swirl #endif 466070af384SBlue Swirl } 467070af384SBlue Swirl 468c5f9864eSAndreas Färber void helper_retry(CPUSPARCState *env) 469070af384SBlue Swirl { 470070af384SBlue Swirl trap_state *tsptr = cpu_tsptr(env); 471070af384SBlue Swirl 472070af384SBlue Swirl env->pc = tsptr->tpc; 473070af384SBlue Swirl env->npc = tsptr->tnpc; 474063c3675SBlue Swirl cpu_put_ccr(env, tsptr->tstate >> 32); 475070af384SBlue Swirl env->asi = (tsptr->tstate >> 24) & 0xff; 476063c3675SBlue Swirl cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); 477063c3675SBlue Swirl cpu_put_cwp64(env, tsptr->tstate & 0xff); 4786e040755SArtyom Tarasenko if (cpu_has_hypervisor(env)) { 479cbc3a6a4SArtyom Tarasenko uint32_t new_gl = (tsptr->tstate >> 40) & 7; 4806e040755SArtyom Tarasenko env->hpstate = env->htstate[env->tl]; 481cbc3a6a4SArtyom Tarasenko cpu_gl_switch_gregs(env, new_gl); 482cbc3a6a4SArtyom Tarasenko env->gl = new_gl; 4836e040755SArtyom Tarasenko } 484070af384SBlue Swirl env->tl--; 485070af384SBlue Swirl 486870be6adSBlue Swirl trace_win_helper_retry(env->tl); 487070af384SBlue Swirl 488070af384SBlue Swirl #if !defined(CONFIG_USER_ONLY) 489070af384SBlue Swirl if (cpu_interrupts_enabled(env)) { 4905ee59930SAlex Bennée qemu_mutex_lock_iothread(); 491070af384SBlue Swirl cpu_check_irqs(env); 4925ee59930SAlex Bennée qemu_mutex_unlock_iothread(); 493070af384SBlue Swirl } 494070af384SBlue Swirl #endif 495070af384SBlue Swirl } 496070af384SBlue Swirl #endif 497