Commit e3b60f1d9e1f73e75095e885af66473400bef8aa
1 parent
403f14ef
Fix computation for ceil, floor and round instructions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3028 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
24 additions
and
6 deletions
target-mips/op_helper.c
| @@ -783,6 +783,7 @@ FLOAT_OP(roundl, d) | @@ -783,6 +783,7 @@ FLOAT_OP(roundl, d) | ||
| 783 | { | 783 | { |
| 784 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); | 784 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); |
| 785 | DT2 = float64_round_to_int(FDT0, &env->fp_status); | 785 | DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 786 | + DT2 = float64_to_int64(DT2, &env->fp_status); | ||
| 786 | RESTORE_ROUNDING_MODE; | 787 | RESTORE_ROUNDING_MODE; |
| 787 | update_fcr31(); | 788 | update_fcr31(); |
| 788 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 789 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -791,7 +792,8 @@ FLOAT_OP(roundl, d) | @@ -791,7 +792,8 @@ FLOAT_OP(roundl, d) | ||
| 791 | FLOAT_OP(roundl, s) | 792 | FLOAT_OP(roundl, s) |
| 792 | { | 793 | { |
| 793 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); | 794 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); |
| 794 | - DT2 = float32_round_to_int(FST0, &env->fp_status); | 795 | + WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 796 | + DT2 = float32_to_int64(WT2, &env->fp_status); | ||
| 795 | RESTORE_ROUNDING_MODE; | 797 | RESTORE_ROUNDING_MODE; |
| 796 | update_fcr31(); | 798 | update_fcr31(); |
| 797 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 799 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -800,7 +802,10 @@ FLOAT_OP(roundl, s) | @@ -800,7 +802,10 @@ FLOAT_OP(roundl, s) | ||
| 800 | FLOAT_OP(roundw, d) | 802 | FLOAT_OP(roundw, d) |
| 801 | { | 803 | { |
| 802 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); | 804 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); |
| 803 | - WT2 = float64_round_to_int(FDT0, &env->fp_status); | 805 | + DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 806 | +// ??? | ||
| 807 | + env->fp_status.float_exception_flags &= ~float_flag_inexact; | ||
| 808 | + WT2 = float64_to_int32(DT2, &env->fp_status); | ||
| 804 | RESTORE_ROUNDING_MODE; | 809 | RESTORE_ROUNDING_MODE; |
| 805 | update_fcr31(); | 810 | update_fcr31(); |
| 806 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 811 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -810,6 +815,7 @@ FLOAT_OP(roundw, s) | @@ -810,6 +815,7 @@ FLOAT_OP(roundw, s) | ||
| 810 | { | 815 | { |
| 811 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); | 816 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); |
| 812 | WT2 = float32_round_to_int(FST0, &env->fp_status); | 817 | WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 818 | + WT2 = float32_to_int32(WT2, &env->fp_status); | ||
| 813 | RESTORE_ROUNDING_MODE; | 819 | RESTORE_ROUNDING_MODE; |
| 814 | update_fcr31(); | 820 | update_fcr31(); |
| 815 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 821 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -849,6 +855,7 @@ FLOAT_OP(ceill, d) | @@ -849,6 +855,7 @@ FLOAT_OP(ceill, d) | ||
| 849 | { | 855 | { |
| 850 | set_float_rounding_mode(float_round_up, &env->fp_status); | 856 | set_float_rounding_mode(float_round_up, &env->fp_status); |
| 851 | DT2 = float64_round_to_int(FDT0, &env->fp_status); | 857 | DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 858 | + DT2 = float64_to_int64(DT2, &env->fp_status); | ||
| 852 | RESTORE_ROUNDING_MODE; | 859 | RESTORE_ROUNDING_MODE; |
| 853 | update_fcr31(); | 860 | update_fcr31(); |
| 854 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 861 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -857,7 +864,8 @@ FLOAT_OP(ceill, d) | @@ -857,7 +864,8 @@ FLOAT_OP(ceill, d) | ||
| 857 | FLOAT_OP(ceill, s) | 864 | FLOAT_OP(ceill, s) |
| 858 | { | 865 | { |
| 859 | set_float_rounding_mode(float_round_up, &env->fp_status); | 866 | set_float_rounding_mode(float_round_up, &env->fp_status); |
| 860 | - DT2 = float32_round_to_int(FST0, &env->fp_status); | 867 | + WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 868 | + DT2 = float32_to_int64(WT2, &env->fp_status); | ||
| 861 | RESTORE_ROUNDING_MODE; | 869 | RESTORE_ROUNDING_MODE; |
| 862 | update_fcr31(); | 870 | update_fcr31(); |
| 863 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 871 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -866,7 +874,10 @@ FLOAT_OP(ceill, s) | @@ -866,7 +874,10 @@ FLOAT_OP(ceill, s) | ||
| 866 | FLOAT_OP(ceilw, d) | 874 | FLOAT_OP(ceilw, d) |
| 867 | { | 875 | { |
| 868 | set_float_rounding_mode(float_round_up, &env->fp_status); | 876 | set_float_rounding_mode(float_round_up, &env->fp_status); |
| 869 | - WT2 = float64_round_to_int(FDT0, &env->fp_status); | 877 | + DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 878 | +// ??? | ||
| 879 | + env->fp_status.float_exception_flags &= ~float_flag_inexact; | ||
| 880 | + WT2 = float64_to_int32(DT2, &env->fp_status); | ||
| 870 | RESTORE_ROUNDING_MODE; | 881 | RESTORE_ROUNDING_MODE; |
| 871 | update_fcr31(); | 882 | update_fcr31(); |
| 872 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 883 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -876,6 +887,7 @@ FLOAT_OP(ceilw, s) | @@ -876,6 +887,7 @@ FLOAT_OP(ceilw, s) | ||
| 876 | { | 887 | { |
| 877 | set_float_rounding_mode(float_round_up, &env->fp_status); | 888 | set_float_rounding_mode(float_round_up, &env->fp_status); |
| 878 | WT2 = float32_round_to_int(FST0, &env->fp_status); | 889 | WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 890 | + WT2 = float32_to_int32(WT2, &env->fp_status); | ||
| 879 | RESTORE_ROUNDING_MODE; | 891 | RESTORE_ROUNDING_MODE; |
| 880 | update_fcr31(); | 892 | update_fcr31(); |
| 881 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 893 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -886,6 +898,7 @@ FLOAT_OP(floorl, d) | @@ -886,6 +898,7 @@ FLOAT_OP(floorl, d) | ||
| 886 | { | 898 | { |
| 887 | set_float_rounding_mode(float_round_down, &env->fp_status); | 899 | set_float_rounding_mode(float_round_down, &env->fp_status); |
| 888 | DT2 = float64_round_to_int(FDT0, &env->fp_status); | 900 | DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 901 | + DT2 = float64_to_int64(DT2, &env->fp_status); | ||
| 889 | RESTORE_ROUNDING_MODE; | 902 | RESTORE_ROUNDING_MODE; |
| 890 | update_fcr31(); | 903 | update_fcr31(); |
| 891 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 904 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -894,7 +907,8 @@ FLOAT_OP(floorl, d) | @@ -894,7 +907,8 @@ FLOAT_OP(floorl, d) | ||
| 894 | FLOAT_OP(floorl, s) | 907 | FLOAT_OP(floorl, s) |
| 895 | { | 908 | { |
| 896 | set_float_rounding_mode(float_round_down, &env->fp_status); | 909 | set_float_rounding_mode(float_round_down, &env->fp_status); |
| 897 | - DT2 = float32_round_to_int(FST0, &env->fp_status); | 910 | + WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 911 | + DT2 = float32_to_int64(WT2, &env->fp_status); | ||
| 898 | RESTORE_ROUNDING_MODE; | 912 | RESTORE_ROUNDING_MODE; |
| 899 | update_fcr31(); | 913 | update_fcr31(); |
| 900 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 914 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -903,7 +917,10 @@ FLOAT_OP(floorl, s) | @@ -903,7 +917,10 @@ FLOAT_OP(floorl, s) | ||
| 903 | FLOAT_OP(floorw, d) | 917 | FLOAT_OP(floorw, d) |
| 904 | { | 918 | { |
| 905 | set_float_rounding_mode(float_round_down, &env->fp_status); | 919 | set_float_rounding_mode(float_round_down, &env->fp_status); |
| 906 | - WT2 = float64_round_to_int(FDT0, &env->fp_status); | 920 | + DT2 = float64_round_to_int(FDT0, &env->fp_status); |
| 921 | +// ??? | ||
| 922 | + env->fp_status.float_exception_flags &= ~float_flag_inexact; | ||
| 923 | + WT2 = float64_to_int32(DT2, &env->fp_status); | ||
| 907 | RESTORE_ROUNDING_MODE; | 924 | RESTORE_ROUNDING_MODE; |
| 908 | update_fcr31(); | 925 | update_fcr31(); |
| 909 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 926 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |
| @@ -913,6 +930,7 @@ FLOAT_OP(floorw, s) | @@ -913,6 +930,7 @@ FLOAT_OP(floorw, s) | ||
| 913 | { | 930 | { |
| 914 | set_float_rounding_mode(float_round_down, &env->fp_status); | 931 | set_float_rounding_mode(float_round_down, &env->fp_status); |
| 915 | WT2 = float32_round_to_int(FST0, &env->fp_status); | 932 | WT2 = float32_round_to_int(FST0, &env->fp_status); |
| 933 | + WT2 = float32_to_int32(WT2, &env->fp_status); | ||
| 916 | RESTORE_ROUNDING_MODE; | 934 | RESTORE_ROUNDING_MODE; |
| 917 | update_fcr31(); | 935 | update_fcr31(); |
| 918 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) | 936 | if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID)) |