Commit e3b60f1d9e1f73e75095e885af66473400bef8aa

Authored by ths
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))