Commit 8f1f22f6abc7af1e5ecc8d83698514999e0284e4

Authored by blueswir1
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
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) {