Commit 8f1f22f6abc7af1e5ecc8d83698514999e0284e4
1 parent
1ad21e69
Fix retry and done ops, trap handling
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3055 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
20 additions
and
11 deletions
target-sparc/cpu.h
... | ... | @@ -294,10 +294,8 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); |
294 | 294 | env->psr = (_tmp & 0xf) << 20; \ |
295 | 295 | } while (0) |
296 | 296 | #define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) |
297 | -#define PUT_CWP64(env, val) do { \ | |
298 | - env->cwp = NWINDOWS - 1 - ((val) & 0xff); \ | |
299 | - cpu_set_cwp(env, env->cwp); \ | |
300 | - } while(0) | |
297 | +#define PUT_CWP64(env, val) \ | |
298 | + cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1))) | |
301 | 299 | |
302 | 300 | #endif |
303 | 301 | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -845,12 +845,11 @@ static inline uint64_t *get_gregset(uint64_t pstate) |
845 | 845 | } |
846 | 846 | } |
847 | 847 | |
848 | -void do_wrpstate() | |
848 | +static inline void change_pstate(uint64_t new_pstate) | |
849 | 849 | { |
850 | - uint64_t new_pstate, pstate_regs, new_pstate_regs; | |
850 | + uint64_t pstate_regs, new_pstate_regs; | |
851 | 851 | uint64_t *src, *dst; |
852 | 852 | |
853 | - new_pstate = T0 & 0xf3f; | |
854 | 853 | pstate_regs = env->pstate & 0xc01; |
855 | 854 | new_pstate_regs = new_pstate & 0xc01; |
856 | 855 | if (new_pstate_regs != pstate_regs) { |
... | ... | @@ -863,6 +862,11 @@ void do_wrpstate() |
863 | 862 | env->pstate = new_pstate; |
864 | 863 | } |
865 | 864 | |
865 | +void do_wrpstate(void) | |
866 | +{ | |
867 | + change_pstate(T0 & 0xf3f); | |
868 | +} | |
869 | + | |
866 | 870 | void do_done(void) |
867 | 871 | { |
868 | 872 | env->tl--; |
... | ... | @@ -870,7 +874,7 @@ void do_done(void) |
870 | 874 | env->npc = env->tnpc[env->tl] + 4; |
871 | 875 | PUT_CCR(env, env->tstate[env->tl] >> 32); |
872 | 876 | env->asi = (env->tstate[env->tl] >> 24) & 0xff; |
873 | - env->pstate = (env->tstate[env->tl] >> 8) & 0xfff; | |
877 | + change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); | |
874 | 878 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); |
875 | 879 | } |
876 | 880 | |
... | ... | @@ -881,7 +885,7 @@ void do_retry(void) |
881 | 885 | env->npc = env->tnpc[env->tl]; |
882 | 886 | PUT_CCR(env, env->tstate[env->tl] >> 32); |
883 | 887 | env->asi = (env->tstate[env->tl] >> 24) & 0xff; |
884 | - env->pstate = (env->tstate[env->tl] >> 8) & 0xfff; | |
888 | + change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); | |
885 | 889 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); |
886 | 890 | } |
887 | 891 | #endif |
... | ... | @@ -952,11 +956,18 @@ void do_interrupt(int intno) |
952 | 956 | } |
953 | 957 | #endif |
954 | 958 | env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | |
955 | - ((env->pstate & 0xfff) << 8) | GET_CWP64(env); | |
959 | + ((env->pstate & 0xf3f) << 8) | GET_CWP64(env); | |
956 | 960 | env->tpc[env->tl] = env->pc; |
957 | 961 | env->tnpc[env->tl] = env->npc; |
958 | 962 | env->tt[env->tl] = intno; |
959 | - env->pstate = PS_PEF | PS_PRIV | PS_AG; | |
963 | + change_pstate(PS_PEF | PS_PRIV | PS_AG); | |
964 | + | |
965 | + if (intno == TT_CLRWIN) | |
966 | + set_cwp((env->cwp - 1) & (NWINDOWS - 1)); | |
967 | + else if ((intno & 0x1c0) == TT_SPILL) | |
968 | + set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1)); | |
969 | + else if ((intno & 0x1c0) == TT_FILL) | |
970 | + set_cwp((env->cwp + 1) & (NWINDOWS - 1)); | |
960 | 971 | env->tbr &= ~0x7fffULL; |
961 | 972 | env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); |
962 | 973 | if (env->tl < MAXTL - 1) { | ... | ... |