xref: /qemu/target/sparc/win_helper.c (revision 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf)
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