Revision 8dfdb87c

b/target-mips/op_helper.c
597 597

  
598 598
/* Complex FPU operations which may need stack space. */
599 599

  
600
#define FLOAT_SIGN32 (1 << 31)
601
#define FLOAT_SIGN64 (1ULL << 63)
602
#define FLOAT_ONE32 (0x3f8 << 20)
603
#define FLOAT_ONE64 (0x3ffULL << 52)
604
#define FLOAT_TWO32 (1 << 30)
605
#define FLOAT_TWO64 (1ULL << 62)
606

  
600 607
/* convert MIPS rounding mode in FCR31 to IEEE library */
601 608
unsigned int ieee_rm[] = {
602 609
    float_round_nearest_even,
......
912 919
        WT2 = 0x7fffffff;
913 920
}
914 921

  
915
/* unary operations, MIPS specific, s and d */
916
#define FLOAT_UNOP(name)  \
917
FLOAT_OP(name, d)         \
918
{                         \
919
    set_float_exception_flags(0, &env->fp_status);            \
920
/* XXX: not implemented */ \
921
/*    FDT2 = float64_ ## name (FDT0, &env->fp_status);*/          \
922
do_raise_exception(EXCP_RI); \
923
    update_fcr31();       \
924
}                         \
925
FLOAT_OP(name, s)         \
926
{                         \
927
    set_float_exception_flags(0, &env->fp_status);            \
928
/* XXX: not implemented */ \
929
/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
930
do_raise_exception(EXCP_RI); \
931
    update_fcr31();       \
922
/* MIPS specific unary operations */
923
FLOAT_OP(recip, d)
924
{
925
    set_float_exception_flags(0, &env->fp_status);
926
    FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
927
    update_fcr31();
928
}
929
FLOAT_OP(recip, s)
930
{
931
    set_float_exception_flags(0, &env->fp_status);
932
    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
933
    update_fcr31();
932 934
}
933
FLOAT_UNOP(rsqrt)
934
FLOAT_UNOP(recip)
935
#undef FLOAT_UNOP
936 935

  
937
/* unary operations, MIPS specific, s, d and ps */
938
#define FLOAT_UNOP(name)  \
939
FLOAT_OP(name, d)         \
940
{                         \
941
    set_float_exception_flags(0, &env->fp_status);            \
942
/* XXX: not implemented */ \
943
/*    FDT2 = float64_ ## name (FDT0, &env->fp_status);*/          \
944
do_raise_exception(EXCP_RI); \
945
    update_fcr31();       \
946
}                         \
947
FLOAT_OP(name, s)         \
948
{                         \
949
    set_float_exception_flags(0, &env->fp_status);            \
950
/* XXX: not implemented */ \
951
/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
952
do_raise_exception(EXCP_RI); \
953
    update_fcr31();       \
954
}                         \
955
FLOAT_OP(name, ps)        \
956
{                         \
957
    set_float_exception_flags(0, &env->fp_status);            \
958
/* XXX: not implemented */ \
959
/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
960
/*    FSTH2 = float32_ ## name (FSTH0, &env->fp_status);*/        \
961
do_raise_exception(EXCP_RI); \
962
    update_fcr31();       \
936
FLOAT_OP(rsqrt, d)
937
{
938
    set_float_exception_flags(0, &env->fp_status);
939
    FDT2 = float64_sqrt(FDT0, &env->fp_status);
940
    FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
941
    update_fcr31();
942
}
943
FLOAT_OP(rsqrt, s)
944
{
945
    set_float_exception_flags(0, &env->fp_status);
946
    FST2 = float32_sqrt(FST0, &env->fp_status);
947
    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
948
    update_fcr31();
949
}
950

  
951
FLOAT_OP(recip1, d)
952
{
953
    set_float_exception_flags(0, &env->fp_status);
954
    FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
955
    update_fcr31();
956
}
957
FLOAT_OP(recip1, s)
958
{
959
    set_float_exception_flags(0, &env->fp_status);
960
    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
961
    update_fcr31();
962
}
963
FLOAT_OP(recip1, ps)
964
{
965
    set_float_exception_flags(0, &env->fp_status);
966
    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
967
    FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fp_status);
968
    update_fcr31();
969
}
970

  
971
FLOAT_OP(rsqrt1, d)
972
{
973
    set_float_exception_flags(0, &env->fp_status);
974
    FDT2 = float64_sqrt(FDT0, &env->fp_status);
975
    FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
976
    update_fcr31();
977
}
978
FLOAT_OP(rsqrt1, s)
979
{
980
    set_float_exception_flags(0, &env->fp_status);
981
    FST2 = float32_sqrt(FST0, &env->fp_status);
982
    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
983
    update_fcr31();
984
}
985
FLOAT_OP(rsqrt1, ps)
986
{
987
    set_float_exception_flags(0, &env->fp_status);
988
    FST2 = float32_sqrt(FST0, &env->fp_status);
989
    FSTH2 = float32_sqrt(FSTH0, &env->fp_status);
990
    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
991
    FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fp_status);
992
    update_fcr31();
963 993
}
964
FLOAT_UNOP(rsqrt1)
965
FLOAT_UNOP(recip1)
966
#undef FLOAT_UNOP
967 994

  
968 995
/* binary operations */
969 996
#define FLOAT_BINOP(name) \
......
976 1003
        FDT2 = 0x7ff7ffffffffffffULL;                         \
977 1004
    else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {       \
978 1005
        if ((env->fcr31 & 0x3) == 0)                          \
979
            FDT2 &= 0x8000000000000000ULL;                    \
1006
            FDT2 &= FLOAT_SIGN64;                             \
980 1007
    }                     \
981 1008
}                         \
982 1009
FLOAT_OP(name, s)         \
......
988 1015
        FST2 = 0x7fbfffff;                                    \
989 1016
    else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {       \
990 1017
        if ((env->fcr31 & 0x3) == 0)                          \
991
            FST2 &= 0x80000000ULL;                            \
1018
            FST2 &= FLOAT_SIGN32;                             \
992 1019
    }                     \
993 1020
}                         \
994 1021
FLOAT_OP(name, ps)        \
......
1002 1029
        FSTH2 = 0x7fbfffff;                                   \
1003 1030
    } else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {     \
1004 1031
        if ((env->fcr31 & 0x3) == 0) {                        \
1005
            FST2 &= 0x80000000ULL;                            \
1006
            FSTH2 &= 0x80000000ULL;                           \
1032
            FST2 &= FLOAT_SIGN32;                             \
1033
            FSTH2 &= FLOAT_SIGN32;                            \
1007 1034
        }                 \
1008 1035
    }                     \
1009 1036
}
......
1013 1040
FLOAT_BINOP(div)
1014 1041
#undef FLOAT_BINOP
1015 1042

  
1016
/* binary operations, MIPS specific */
1017
#define FLOAT_BINOP(name) \
1018
FLOAT_OP(name, d)         \
1019
{                         \
1020
    set_float_exception_flags(0, &env->fp_status);            \
1021
/* XXX: not implemented */ \
1022
/*    FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);*/    \
1023
do_raise_exception(EXCP_RI); \
1024
    update_fcr31();       \
1025
}                         \
1026
FLOAT_OP(name, s)         \
1027
{                         \
1028
    set_float_exception_flags(0, &env->fp_status);            \
1029
/* XXX: not implemented */ \
1030
/*    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/    \
1031
do_raise_exception(EXCP_RI); \
1032
    update_fcr31();       \
1033
}                         \
1034
FLOAT_OP(name, ps)        \
1035
{                         \
1036
    set_float_exception_flags(0, &env->fp_status);            \
1037
/* XXX: not implemented */ \
1038
/*    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/    \
1039
/*    FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status);*/ \
1040
do_raise_exception(EXCP_RI); \
1041
    update_fcr31();       \
1043
/* MIPS specific binary operations */
1044
FLOAT_OP(recip2, d)
1045
{
1046
    set_float_exception_flags(0, &env->fp_status);
1047
    FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1048
    FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status) ^ FLOAT_SIGN64;
1049
    update_fcr31();
1050
}
1051
FLOAT_OP(recip2, s)
1052
{
1053
    set_float_exception_flags(0, &env->fp_status);
1054
    FST2 = float32_mul(FST0, FST2, &env->fp_status);
1055
    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
1056
    update_fcr31();
1057
}
1058
FLOAT_OP(recip2, ps)
1059
{
1060
    set_float_exception_flags(0, &env->fp_status);
1061
    FST2 = float32_mul(FST0, FST2, &env->fp_status);
1062
    FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1063
    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
1064
    FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
1065
    update_fcr31();
1066
}
1067

  
1068
FLOAT_OP(rsqrt2, d)
1069
{
1070
    set_float_exception_flags(0, &env->fp_status);
1071
    FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
1072
    FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status);
1073
    FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fp_status) ^ FLOAT_SIGN64;
1074
    update_fcr31();
1075
}
1076
FLOAT_OP(rsqrt2, s)
1077
{
1078
    set_float_exception_flags(0, &env->fp_status);
1079
    FST2 = float32_mul(FST0, FST2, &env->fp_status);
1080
    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1081
    FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
1082
    update_fcr31();
1083
}
1084
FLOAT_OP(rsqrt2, ps)
1085
{
1086
    set_float_exception_flags(0, &env->fp_status);
1087
    FST2 = float32_mul(FST0, FST2, &env->fp_status);
1088
    FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
1089
    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
1090
    FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status);
1091
    FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
1092
    FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
1093
    update_fcr31();
1042 1094
}
1043
FLOAT_BINOP(rsqrt2)
1044
FLOAT_BINOP(recip2)
1045
#undef FLOAT_BINOP
1046 1095

  
1047 1096
FLOAT_OP(addr, ps)
1048 1097
{
......
1060 1109
    update_fcr31();
1061 1110
}
1062 1111

  
1112
/* compare operations */
1063 1113
#define FOP_COND_D(op, cond)                   \
1064 1114
void do_cmp_d_ ## op (long cc)                 \
1065 1115
{                                              \
......
1073 1123
void do_cmpabs_d_ ## op (long cc)              \
1074 1124
{                                              \
1075 1125
    int c;                                     \
1076
    FDT0 &= ~(1ULL << 63);                     \
1077
    FDT1 &= ~(1ULL << 63);                     \
1126
    FDT0 &= ~FLOAT_SIGN64;                     \
1127
    FDT1 &= ~FLOAT_SIGN64;                     \
1078 1128
    c = cond;                                  \
1079 1129
    update_fcr31();                            \
1080 1130
    if (c)                                     \
......
1131 1181
void do_cmpabs_s_ ## op (long cc)              \
1132 1182
{                                              \
1133 1183
    int c;                                     \
1134
    FST0 &= ~(1 << 31);                        \
1135
    FST1 &= ~(1 << 31);                        \
1184
    FST0 &= ~FLOAT_SIGN32;                     \
1185
    FST1 &= ~FLOAT_SIGN32;                     \
1136 1186
    c = cond;                                  \
1137 1187
    update_fcr31();                            \
1138 1188
    if (c)                                     \
......
1194 1244
void do_cmpabs_ps_ ## op (long cc)             \
1195 1245
{                                              \
1196 1246
    int cl, ch;                                \
1197
    FST0 &= ~(1 << 31);                        \
1198
    FSTH0 &= ~(1 << 31);                       \
1199
    FST1 &= ~(1 << 31);                        \
1200
    FSTH1 &= ~(1 << 31);                       \
1247
    FST0 &= ~FLOAT_SIGN32;                     \
1248
    FSTH0 &= ~FLOAT_SIGN32;                    \
1249
    FST1 &= ~FLOAT_SIGN32;                     \
1250
    FSTH1 &= ~FLOAT_SIGN32;                    \
1201 1251
    cl = condl;                                \
1202 1252
    ch = condh;                                \
1203 1253
    update_fcr31();                            \
b/target-mips/translate.c
4551 4551
    case FOP(31, 16):
4552 4552
        check_cp1_64bitmode(ctx);
4553 4553
        GEN_LOAD_FREG_FTN(WT0, fs);
4554
        GEN_LOAD_FREG_FTN(WT2, fd);
4554
        GEN_LOAD_FREG_FTN(WT2, ft);
4555 4555
        gen_op_float_rsqrt2_s();
4556 4556
        GEN_STORE_FTN_FREG(fd, WT2);
4557 4557
        opn = "rsqrt2.s";
......
5036 5036
        check_cp1_64bitmode(ctx);
5037 5037
        GEN_LOAD_FREG_FTN(WT0, fs);
5038 5038
        GEN_LOAD_FREG_FTN(WTH0, fs);
5039
        GEN_LOAD_FREG_FTN(WT2, fd);
5040
        GEN_LOAD_FREG_FTN(WTH2, fd);
5039
        GEN_LOAD_FREG_FTN(WT2, ft);
5040
        GEN_LOAD_FREG_FTN(WTH2, ft);
5041 5041
        gen_op_float_rsqrt2_ps();
5042 5042
        GEN_STORE_FTN_FREG(fd, WT2);
5043 5043
        GEN_STORE_FTN_FREG(fd, WTH2);

Also available in: Unified diff