make FPU load exception safe
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@305 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									4d40895f2c
								
							
						
					
					
						commit
						c39d5b78f6
					
				
							
								
								
									
										64
									
								
								op-i386.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								op-i386.c
									
									
									
									
									
								
							@ -1406,28 +1406,40 @@ void OPPROTO op_fildll_FT0_A0(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_flds_ST0_A0(void)
 | 
					void OPPROTO op_flds_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					#ifdef USE_FP_CONVERT
 | 
				
			||||||
    FP_CONVERT.i32 = ldl((void *)A0);
 | 
					    FP_CONVERT.i32 = ldl((void *)A0);
 | 
				
			||||||
    ST0 = FP_CONVERT.f;
 | 
					    env->fpregs[new_fpstt] = FP_CONVERT.f;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    ST0 = ldfl((void *)A0);
 | 
					    env->fpregs[new_fpstt] = ldfl((void *)A0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_fldl_ST0_A0(void)
 | 
					void OPPROTO op_fldl_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					#ifdef USE_FP_CONVERT
 | 
				
			||||||
    FP_CONVERT.i64 = ldq((void *)A0);
 | 
					    FP_CONVERT.i64 = ldq((void *)A0);
 | 
				
			||||||
    ST0 = FP_CONVERT.d;
 | 
					    env->fpregs[new_fpstt] = FP_CONVERT.d;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    ST0 = ldfq((void *)A0);
 | 
					    env->fpregs[new_fpstt] = ldfq((void *)A0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_X86LDOUBLE
 | 
					#ifdef USE_X86LDOUBLE
 | 
				
			||||||
void OPPROTO op_fldt_ST0_A0(void)
 | 
					void OPPROTO op_fldt_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ST0 = *(long double *)A0;
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
 | 
					    env->fpregs[new_fpstt] = *(long double *)A0;
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
void OPPROTO op_fldt_ST0_A0(void)
 | 
					void OPPROTO op_fldt_ST0_A0(void)
 | 
				
			||||||
@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_ST0_A0(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void helper_fild_ST0_A0(void)
 | 
					void helper_fild_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ST0 = (CPU86_LDouble)ldsw((void *)A0);
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_fildl_ST0_A0(void)
 | 
					void helper_fildl_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_fildll_ST0_A0(void)
 | 
					void helper_fildll_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_fild_ST0_A0(void)
 | 
					void OPPROTO op_fild_ST0_A0(void)
 | 
				
			||||||
@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_fild_ST0_A0(void)
 | 
					void OPPROTO op_fild_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					#ifdef USE_FP_CONVERT
 | 
				
			||||||
    FP_CONVERT.i32 = ldsw((void *)A0);
 | 
					    FP_CONVERT.i32 = ldsw((void *)A0);
 | 
				
			||||||
    ST0 = (CPU86_LDouble)FP_CONVERT.i32;
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    ST0 = (CPU86_LDouble)ldsw((void *)A0);
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_fildl_ST0_A0(void)
 | 
					void OPPROTO op_fildl_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					#ifdef USE_FP_CONVERT
 | 
				
			||||||
    FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
 | 
					    FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
 | 
				
			||||||
    ST0 = (CPU86_LDouble)FP_CONVERT.i32;
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_fildll_ST0_A0(void)
 | 
					void OPPROTO op_fildll_ST0_A0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int new_fpstt;
 | 
				
			||||||
 | 
					    new_fpstt = (env->fpstt - 1) & 7;
 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					#ifdef USE_FP_CONVERT
 | 
				
			||||||
    FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
 | 
					    FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
 | 
				
			||||||
    ST0 = (CPU86_LDouble)FP_CONVERT.i64;
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
 | 
					    env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    env->fpstt = new_fpstt;
 | 
				
			||||||
 | 
					    env->fptags[new_fpstt] = 0; /* validate stack entry */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
 | 
				
			|||||||
                
 | 
					                
 | 
				
			||||||
                switch(op & 7) {
 | 
					                switch(op & 7) {
 | 
				
			||||||
                case 0:
 | 
					                case 0:
 | 
				
			||||||
                    gen_op_fpush();
 | 
					 | 
				
			||||||
                    switch(op >> 4) {
 | 
					                    switch(op >> 4) {
 | 
				
			||||||
                    case 0:
 | 
					                    case 0:
 | 
				
			||||||
                        gen_op_flds_ST0_A0();
 | 
					                        gen_op_flds_ST0_A0();
 | 
				
			||||||
@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
 | 
				
			|||||||
                gen_op_fnstcw_A0();
 | 
					                gen_op_fnstcw_A0();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x1d: /* fldt mem */
 | 
					            case 0x1d: /* fldt mem */
 | 
				
			||||||
                gen_op_fpush();
 | 
					 | 
				
			||||||
                gen_op_fldt_ST0_A0();
 | 
					                gen_op_fldt_ST0_A0();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x1f: /* fstpt mem */
 | 
					            case 0x1f: /* fstpt mem */
 | 
				
			||||||
@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
 | 
				
			|||||||
                gen_op_fnstsw_A0();
 | 
					                gen_op_fnstsw_A0();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x3c: /* fbld */
 | 
					            case 0x3c: /* fbld */
 | 
				
			||||||
                gen_op_fpush();
 | 
					 | 
				
			||||||
                gen_op_fbld_ST0_A0();
 | 
					                gen_op_fbld_ST0_A0();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x3e: /* fbstp */
 | 
					            case 0x3e: /* fbstp */
 | 
				
			||||||
@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
 | 
				
			|||||||
                gen_op_fpop();
 | 
					                gen_op_fpop();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x3d: /* fildll */
 | 
					            case 0x3d: /* fildll */
 | 
				
			||||||
                gen_op_fpush();
 | 
					 | 
				
			||||||
                gen_op_fildll_ST0_A0();
 | 
					                gen_op_fildll_ST0_A0();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x3f: /* fistpll */
 | 
					            case 0x3f: /* fistpll */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user