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,10 +294,8 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); | ||
| 294 | env->psr = (_tmp & 0xf) << 20; \ | 294 | env->psr = (_tmp & 0xf) << 20; \ |
| 295 | } while (0) | 295 | } while (0) |
| 296 | #define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) | 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 | #endif | 300 | #endif |
| 303 | 301 |
target-sparc/op_helper.c
| @@ -845,12 +845,11 @@ static inline uint64_t *get_gregset(uint64_t pstate) | @@ -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 | uint64_t *src, *dst; | 851 | uint64_t *src, *dst; |
| 852 | 852 | ||
| 853 | - new_pstate = T0 & 0xf3f; | ||
| 854 | pstate_regs = env->pstate & 0xc01; | 853 | pstate_regs = env->pstate & 0xc01; |
| 855 | new_pstate_regs = new_pstate & 0xc01; | 854 | new_pstate_regs = new_pstate & 0xc01; |
| 856 | if (new_pstate_regs != pstate_regs) { | 855 | if (new_pstate_regs != pstate_regs) { |
| @@ -863,6 +862,11 @@ void do_wrpstate() | @@ -863,6 +862,11 @@ void do_wrpstate() | ||
| 863 | env->pstate = new_pstate; | 862 | env->pstate = new_pstate; |
| 864 | } | 863 | } |
| 865 | 864 | ||
| 865 | +void do_wrpstate(void) | ||
| 866 | +{ | ||
| 867 | + change_pstate(T0 & 0xf3f); | ||
| 868 | +} | ||
| 869 | + | ||
| 866 | void do_done(void) | 870 | void do_done(void) |
| 867 | { | 871 | { |
| 868 | env->tl--; | 872 | env->tl--; |
| @@ -870,7 +874,7 @@ void do_done(void) | @@ -870,7 +874,7 @@ void do_done(void) | ||
| 870 | env->npc = env->tnpc[env->tl] + 4; | 874 | env->npc = env->tnpc[env->tl] + 4; |
| 871 | PUT_CCR(env, env->tstate[env->tl] >> 32); | 875 | PUT_CCR(env, env->tstate[env->tl] >> 32); |
| 872 | env->asi = (env->tstate[env->tl] >> 24) & 0xff; | 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 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); | 878 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); |
| 875 | } | 879 | } |
| 876 | 880 | ||
| @@ -881,7 +885,7 @@ void do_retry(void) | @@ -881,7 +885,7 @@ void do_retry(void) | ||
| 881 | env->npc = env->tnpc[env->tl]; | 885 | env->npc = env->tnpc[env->tl]; |
| 882 | PUT_CCR(env, env->tstate[env->tl] >> 32); | 886 | PUT_CCR(env, env->tstate[env->tl] >> 32); |
| 883 | env->asi = (env->tstate[env->tl] >> 24) & 0xff; | 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 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); | 889 | PUT_CWP64(env, env->tstate[env->tl] & 0xff); |
| 886 | } | 890 | } |
| 887 | #endif | 891 | #endif |
| @@ -952,11 +956,18 @@ void do_interrupt(int intno) | @@ -952,11 +956,18 @@ void do_interrupt(int intno) | ||
| 952 | } | 956 | } |
| 953 | #endif | 957 | #endif |
| 954 | env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | | 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 | env->tpc[env->tl] = env->pc; | 960 | env->tpc[env->tl] = env->pc; |
| 957 | env->tnpc[env->tl] = env->npc; | 961 | env->tnpc[env->tl] = env->npc; |
| 958 | env->tt[env->tl] = intno; | 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 | env->tbr &= ~0x7fffULL; | 971 | env->tbr &= ~0x7fffULL; |
| 961 | env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); | 972 | env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); |
| 962 | if (env->tl < MAXTL - 1) { | 973 | if (env->tl < MAXTL - 1) { |