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) { | ... | ... |