Revision 8422b113

b/target-i386/exec.h
325 325
#define floatx_abs floatx80_abs
326 326
#define floatx_chs floatx80_chs
327 327
#define floatx_round_to_int floatx80_round_to_int
328
#define floatx_compare floatx80_compare
329
#define floatx_compare_quiet floatx80_compare_quiet
328 330
#define sin sinl
329 331
#define cos cosl
330 332
#define sqrt sqrtl
......
340 342
#define floatx_abs float64_abs
341 343
#define floatx_chs float64_chs
342 344
#define floatx_round_to_int float64_round_to_int
345
#define floatx_compare float64_compare
346
#define floatx_compare_quiet float64_compare_quiet
343 347
#endif
344 348

  
345 349
extern CPU86_LDouble sin(CPU86_LDouble x);
......
547 551
void save_native_fp_state(CPUState *env);
548 552
float approx_rsqrt(float a);
549 553
float approx_rcp(float a);
550
double helper_sqrt(double a);
551
int fpu_isnan(double a);
552 554
void update_fp_status(void);
553 555

  
554 556
extern const uint8_t parity_table[256];
b/target-i386/helper.c
3223 3223

  
3224 3224
#endif
3225 3225

  
3226
/* XXX: do it */
3227
int fpu_isnan(double a)
3228
{
3229
    return 0;
3230
}
3231

  
3232 3226
float approx_rsqrt(float a)
3233 3227
{
3234 3228
    return 1.0 / sqrt(a);
b/target-i386/op.c
1952 1952

  
1953 1953
/* FPU operations */
1954 1954

  
1955
/* XXX: handle nans */
1956 1955
void OPPROTO op_fcom_ST0_FT0(void)
1957 1956
{
1958
    env->fpus &= (~0x4500);	/* (C3,C2,C0) <-- 000 */
1959
    if (ST0 < FT0)
1960
        env->fpus |= 0x100;	/* (C3,C2,C0) <-- 001 */
1961
    else if (ST0 == FT0)
1962
        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1957
    int cc;
1958
    switch(floatx_compare(ST0, FT0, &env->fp_status)) {
1959
    case -1:
1960
        cc = 0x0100;
1961
        break;
1962
    case 0:
1963
        cc = 0x4000;
1964
        break;
1965
    case 1:
1966
        cc = 0x0000;
1967
        break;
1968
    case 2:
1969
    default:
1970
        cc = 0x4500;
1971
        break;
1972
    }
1973
    env->fpus = (env->fpus & ~0x4500) | cc;
1963 1974
    FORCE_RET();
1964 1975
}
1965 1976

  
1966
/* XXX: handle nans */
1967 1977
void OPPROTO op_fucom_ST0_FT0(void)
1968 1978
{
1969
    env->fpus &= (~0x4500);	/* (C3,C2,C0) <-- 000 */
1970
    if (ST0 < FT0)
1971
        env->fpus |= 0x100;	/* (C3,C2,C0) <-- 001 */
1972
    else if (ST0 == FT0)
1973
        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1979
    int cc;
1980
    switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) {
1981
    case -1:
1982
        cc = 0x0100;
1983
        break;
1984
    case 0:
1985
        cc = 0x4000;
1986
        break;
1987
    case 1:
1988
        cc = 0x0000;
1989
        break;
1990
    case 2:
1991
    default:
1992
        cc = 0x4500;
1993
        break;
1994
    }
1995
    env->fpus = (env->fpus & ~0x4500) | cc;
1974 1996
    FORCE_RET();
1975 1997
}
1976 1998

  
1977
/* XXX: handle nans */
1978 1999
void OPPROTO op_fcomi_ST0_FT0(void)
1979 2000
{
1980
    int eflags;
2001
    int eflags, cc;
2002
    switch(floatx_compare(ST0, FT0, &env->fp_status)) {
2003
    case -1:
2004
        cc = CC_C;
2005
        break;
2006
    case 0:
2007
        cc = CC_Z;
2008
        break;
2009
    case 1:
2010
        cc = 0;
2011
        break;
2012
    case 2:
2013
    default:
2014
        cc = CC_Z | CC_P | CC_C;
2015
        break;
2016
    }
1981 2017
    eflags = cc_table[CC_OP].compute_all();
1982
    eflags &= ~(CC_Z | CC_P | CC_C);
1983
    if (ST0 < FT0)
1984
        eflags |= CC_C;
1985
    else if (ST0 == FT0)
1986
        eflags |= CC_Z;
2018
    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc;
1987 2019
    CC_SRC = eflags;
1988 2020
    FORCE_RET();
1989 2021
}
1990 2022

  
1991
/* XXX: handle nans */
1992 2023
void OPPROTO op_fucomi_ST0_FT0(void)
1993 2024
{
1994
    int eflags;
2025
    int eflags, cc;
2026
    switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) {
2027
    case -1:
2028
        cc = CC_C;
2029
        break;
2030
    case 0:
2031
        cc = CC_Z;
2032
        break;
2033
    case 1:
2034
        cc = 0;
2035
        break;
2036
    case 2:
2037
    default:
2038
        cc = CC_Z | CC_P | CC_C;
2039
        break;
2040
    }
1995 2041
    eflags = cc_table[CC_OP].compute_all();
1996
    eflags &= ~(CC_Z | CC_P | CC_C);
1997
    if (ST0 < FT0)
1998
        eflags |= CC_C;
1999
    else if (ST0 == FT0)
2000
        eflags |= CC_Z;
2042
    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc;
2001 2043
    CC_SRC = eflags;
2002 2044
    FORCE_RET();
2003 2045
}
b/target-i386/ops_sse.h
704 704
/* float to float conversions */
705 705
void OPPROTO op_cvtps2pd(void)
706 706
{
707
    float s0, s1;
707
    float32 s0, s1;
708 708
    Reg *d, *s;
709 709
    d = (Reg *)((char *)env + PARAM1);
710 710
    s = (Reg *)((char *)env + PARAM2);
......
1031 1031
    Reg *d, *s;\
1032 1032
    d = (Reg *)((char *)env + PARAM1);\
1033 1033
    s = (Reg *)((char *)env + PARAM2);\
1034
    d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\
1035
    d->XMM_L(1) = F(d->XMM_S(1), s->XMM_S(1));\
1036
    d->XMM_L(2) = F(d->XMM_S(2), s->XMM_S(2));\
1037
    d->XMM_L(3) = F(d->XMM_S(3), s->XMM_S(3));\
1034
    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
1035
    d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
1036
    d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2));\
1037
    d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3));\
1038 1038
}\
1039 1039
\
1040 1040
void OPPROTO op_ ## name ## ss (void)\
......
1042 1042
    Reg *d, *s;\
1043 1043
    d = (Reg *)((char *)env + PARAM1);\
1044 1044
    s = (Reg *)((char *)env + PARAM2);\
1045
    d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\
1045
    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
1046 1046
}\
1047 1047
void OPPROTO op_ ## name ## pd (void)\
1048 1048
{\
1049 1049
    Reg *d, *s;\
1050 1050
    d = (Reg *)((char *)env + PARAM1);\
1051 1051
    s = (Reg *)((char *)env + PARAM2);\
1052
    d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\
1053
    d->XMM_Q(1) = F(d->XMM_D(1), s->XMM_D(1));\
1052
    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
1053
    d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
1054 1054
}\
1055 1055
\
1056 1056
void OPPROTO op_ ## name ## sd (void)\
......
1058 1058
    Reg *d, *s;\
1059 1059
    d = (Reg *)((char *)env + PARAM1);\
1060 1060
    s = (Reg *)((char *)env + PARAM2);\
1061
    d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\
1061
    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
1062 1062
}
1063 1063

  
1064
#define FPU_CMPEQ(a, b) (a) == (b) ? -1 : 0
1065
#define FPU_CMPLT(a, b) (a) < (b) ? -1 : 0
1066
#define FPU_CMPLE(a, b) (a) <= (b) ? -1 : 0
1067
#define FPU_CMPUNORD(a, b) (fpu_isnan(a) || fpu_isnan(b)) ? - 1 : 0
1068
#define FPU_CMPNEQ(a, b) (a) == (b) ? 0 : -1
1069
#define FPU_CMPNLT(a, b) (a) < (b) ? 0 : -1
1070
#define FPU_CMPNLE(a, b) (a) <= (b) ? 0 : -1
1071
#define FPU_CMPORD(a, b) (!fpu_isnan(a) && !fpu_isnan(b)) ? - 1 : 0
1064
#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
1065
#define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
1066
#define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
1067
#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
1068
#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
1069
#define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
1070
#define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
1071
#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
1072 1072

  
1073 1073
SSE_OP_CMP(cmpeq, FPU_CMPEQ)
1074 1074
SSE_OP_CMP(cmplt, FPU_CMPLT)
......
1082 1082
void OPPROTO op_ucomiss(void)
1083 1083
{
1084 1084
    int eflags;
1085
    float s0, s1;
1085
    float32 s0, s1;
1086 1086
    Reg *d, *s;
1087 1087
    d = (Reg *)((char *)env + PARAM1);
1088 1088
    s = (Reg *)((char *)env + PARAM2);
1089 1089

  
1090 1090
    s0 = d->XMM_S(0);
1091 1091
    s1 = s->XMM_S(0);
1092
    if (s0 < s1)
1092
    switch(float32_compare_quiet(s0, s1, &env->sse_status)) {
1093
    case -1:
1093 1094
        eflags = CC_C;
1094
    else if (s0 == s1)
1095
        break;
1096
    case 0:
1095 1097
        eflags = CC_Z;
1096
    else
1098
        break;
1099
    case 1:
1097 1100
        eflags = 0;
1101
        break;
1102
    case 2:
1103
    default:
1104
        eflags = CC_Z | CC_P | CC_C;
1105
        break;
1106
    }
1098 1107
    CC_SRC = eflags;
1099 1108
    FORCE_RET();
1100 1109
}
......
1102 1111
void OPPROTO op_comiss(void)
1103 1112
{
1104 1113
    int eflags;
1105
    float s0, s1;
1114
    float32 s0, s1;
1106 1115
    Reg *d, *s;
1107 1116
    d = (Reg *)((char *)env + PARAM1);
1108 1117
    s = (Reg *)((char *)env + PARAM2);
1109 1118

  
1110 1119
    s0 = d->XMM_S(0);
1111 1120
    s1 = s->XMM_S(0);
1112
    if (s0 < s1)
1121
    switch(float32_compare(s0, s1, &env->sse_status)) {
1122
    case -1:
1113 1123
        eflags = CC_C;
1114
    else if (s0 == s1)
1124
        break;
1125
    case 0:
1115 1126
        eflags = CC_Z;
1116
    else
1127
        break;
1128
    case 1:
1117 1129
        eflags = 0;
1130
        break;
1131
    case 2:
1132
    default:
1133
        eflags = CC_Z | CC_P | CC_C;
1134
        break;
1135
    }
1118 1136
    CC_SRC = eflags;
1119 1137
    FORCE_RET();
1120 1138
}
......
1122 1140
void OPPROTO op_ucomisd(void)
1123 1141
{
1124 1142
    int eflags;
1125
    double d0, d1;
1143
    float64 d0, d1;
1126 1144
    Reg *d, *s;
1127 1145
    d = (Reg *)((char *)env + PARAM1);
1128 1146
    s = (Reg *)((char *)env + PARAM2);
1129 1147

  
1130 1148
    d0 = d->XMM_D(0);
1131 1149
    d1 = s->XMM_D(0);
1132
    if (d0 < d1)
1150
    switch(float64_compare_quiet(d0, d1, &env->sse_status)) {
1151
    case -1:
1133 1152
        eflags = CC_C;
1134
    else if (d0 == d1)
1153
        break;
1154
    case 0:
1135 1155
        eflags = CC_Z;
1136
    else
1156
        break;
1157
    case 1:
1137 1158
        eflags = 0;
1159
        break;
1160
    case 2:
1161
    default:
1162
        eflags = CC_Z | CC_P | CC_C;
1163
        break;
1164
    }
1138 1165
    CC_SRC = eflags;
1139 1166
    FORCE_RET();
1140 1167
}
......
1142 1169
void OPPROTO op_comisd(void)
1143 1170
{
1144 1171
    int eflags;
1145
    double d0, d1;
1172
    float64 d0, d1;
1146 1173
    Reg *d, *s;
1147 1174
    d = (Reg *)((char *)env + PARAM1);
1148 1175
    s = (Reg *)((char *)env + PARAM2);
1149 1176

  
1150 1177
    d0 = d->XMM_D(0);
1151 1178
    d1 = s->XMM_D(0);
1152
    if (d0 < d1)
1179
    switch(float64_compare(d0, d1, &env->sse_status)) {
1180
    case -1:
1153 1181
        eflags = CC_C;
1154
    else if (d0 == d1)
1182
        break;
1183
    case 0:
1155 1184
        eflags = CC_Z;
1156
    else
1185
        break;
1186
    case 1:
1157 1187
        eflags = 0;
1188
        break;
1189
    case 2:
1190
    default:
1191
        eflags = CC_Z | CC_P | CC_C;
1192
        break;
1193
    }
1158 1194
    CC_SRC = eflags;
1159 1195
    FORCE_RET();
1160 1196
}

Also available in: Unified diff