[PATCH] [MIPS] Clear softfpu exception state for round, trunc, ceil and floor
MIPS FPU instructions should start with a clean softfpu status. This is done for the arithmetic operations and cvt instructions, but not for round, trunc, ceil and floor. Signed-off-by: Chris Dearman <chris@mips.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
		
							parent
							
								
									cc2212c2f8
								
							
						
					
					
						commit
						efd410373a
					
				@ -2282,6 +2282,7 @@ uint64_t helper_float_roundl_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
					    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2295,6 +2296,7 @@ uint64_t helper_float_roundl_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
					    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2308,6 +2310,7 @@ uint32_t helper_float_roundw_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
					    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2321,6 +2324,7 @@ uint32_t helper_float_roundw_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
					    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2334,6 +2338,7 @@ uint64_t helper_float_truncl_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
 | 
					    dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    update_fcr31();
 | 
					    update_fcr31();
 | 
				
			||||||
    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
					    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
				
			||||||
@ -2345,6 +2350,7 @@ uint64_t helper_float_truncl_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
 | 
					    dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    update_fcr31();
 | 
					    update_fcr31();
 | 
				
			||||||
    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
					    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
				
			||||||
@ -2356,6 +2362,7 @@ uint32_t helper_float_truncw_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
 | 
					    wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    update_fcr31();
 | 
					    update_fcr31();
 | 
				
			||||||
    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
					    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
				
			||||||
@ -2367,6 +2374,7 @@ uint32_t helper_float_truncw_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
 | 
					    wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    update_fcr31();
 | 
					    update_fcr31();
 | 
				
			||||||
    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
					    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
 | 
				
			||||||
@ -2378,6 +2386,7 @@ uint64_t helper_float_ceill_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
					    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2391,6 +2400,7 @@ uint64_t helper_float_ceill_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
					    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2404,6 +2414,7 @@ uint32_t helper_float_ceilw_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
					    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2417,6 +2428,7 @@ uint32_t helper_float_ceilw_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
					    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2430,6 +2442,7 @@ uint64_t helper_float_floorl_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
					    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2443,6 +2456,7 @@ uint64_t helper_float_floorl_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t dt2;
 | 
					    uint64_t dt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
				
			||||||
    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
					    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2456,6 +2470,7 @@ uint32_t helper_float_floorw_d(uint64_t fdt0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
					    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
@ -2469,6 +2484,7 @@ uint32_t helper_float_floorw_s(uint32_t fst0)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t wt2;
 | 
					    uint32_t wt2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_float_exception_flags(0, &env->active_fpu.fp_status);
 | 
				
			||||||
    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
					    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
 | 
				
			||||||
    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
					    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
 | 
				
			||||||
    RESTORE_ROUNDING_MODE;
 | 
					    RESTORE_ROUNDING_MODE;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user