Revision 43fb823b
b/target-i386/op.c | ||
---|---|---|
1952 | 1952 |
|
1953 | 1953 |
/* FPU operations */ |
1954 | 1954 |
|
1955 |
const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; |
|
1956 |
|
|
1955 | 1957 |
void OPPROTO op_fcom_ST0_FT0(void) |
1956 | 1958 |
{ |
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; |
|
1959 |
int ret; |
|
1960 |
|
|
1961 |
ret = floatx_compare(ST0, FT0, &env->fp_status); |
|
1962 |
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; |
|
1974 | 1963 |
FORCE_RET(); |
1975 | 1964 |
} |
1976 | 1965 |
|
1977 | 1966 |
void OPPROTO op_fucom_ST0_FT0(void) |
1978 | 1967 |
{ |
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; |
|
1968 |
int ret; |
|
1969 |
|
|
1970 |
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); |
|
1971 |
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; |
|
1996 | 1972 |
FORCE_RET(); |
1997 | 1973 |
} |
1998 | 1974 |
|
1975 |
const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; |
|
1976 |
|
|
1999 | 1977 |
void OPPROTO op_fcomi_ST0_FT0(void) |
2000 | 1978 |
{ |
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 |
} |
|
1979 |
int eflags; |
|
1980 |
int ret; |
|
1981 |
|
|
1982 |
ret = floatx_compare(ST0, FT0, &env->fp_status); |
|
2017 | 1983 |
eflags = cc_table[CC_OP].compute_all(); |
2018 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc;
|
|
1984 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
|
|
2019 | 1985 |
CC_SRC = eflags; |
2020 | 1986 |
FORCE_RET(); |
2021 | 1987 |
} |
2022 | 1988 |
|
2023 | 1989 |
void OPPROTO op_fucomi_ST0_FT0(void) |
2024 | 1990 |
{ |
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 |
} |
|
1991 |
int eflags; |
|
1992 |
int ret; |
|
1993 |
|
|
1994 |
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); |
|
2041 | 1995 |
eflags = cc_table[CC_OP].compute_all(); |
2042 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc;
|
|
1996 |
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
|
|
2043 | 1997 |
CC_SRC = eflags; |
2044 | 1998 |
FORCE_RET(); |
2045 | 1999 |
} |
b/target-i386/ops_sse.h | ||
---|---|---|
1079 | 1079 |
SSE_OP_CMP(cmpnle, FPU_CMPNLE) |
1080 | 1080 |
SSE_OP_CMP(cmpord, FPU_CMPORD) |
1081 | 1081 |
|
1082 |
const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; |
|
1083 |
|
|
1082 | 1084 |
void OPPROTO op_ucomiss(void) |
1083 | 1085 |
{ |
1084 |
int eflags;
|
|
1086 |
int ret;
|
|
1085 | 1087 |
float32 s0, s1; |
1086 | 1088 |
Reg *d, *s; |
1087 | 1089 |
d = (Reg *)((char *)env + PARAM1); |
... | ... | |
1089 | 1091 |
|
1090 | 1092 |
s0 = d->XMM_S(0); |
1091 | 1093 |
s1 = s->XMM_S(0); |
1092 |
switch(float32_compare_quiet(s0, s1, &env->sse_status)) { |
|
1093 |
case -1: |
|
1094 |
eflags = CC_C; |
|
1095 |
break; |
|
1096 |
case 0: |
|
1097 |
eflags = CC_Z; |
|
1098 |
break; |
|
1099 |
case 1: |
|
1100 |
eflags = 0; |
|
1101 |
break; |
|
1102 |
case 2: |
|
1103 |
default: |
|
1104 |
eflags = CC_Z | CC_P | CC_C; |
|
1105 |
break; |
|
1106 |
} |
|
1107 |
CC_SRC = eflags; |
|
1094 |
ret = float32_compare_quiet(s0, s1, &env->sse_status); |
|
1095 |
CC_SRC = comis_eflags[ret + 1]; |
|
1108 | 1096 |
FORCE_RET(); |
1109 | 1097 |
} |
1110 | 1098 |
|
1111 | 1099 |
void OPPROTO op_comiss(void) |
1112 | 1100 |
{ |
1113 |
int eflags;
|
|
1101 |
int ret;
|
|
1114 | 1102 |
float32 s0, s1; |
1115 | 1103 |
Reg *d, *s; |
1116 | 1104 |
d = (Reg *)((char *)env + PARAM1); |
... | ... | |
1118 | 1106 |
|
1119 | 1107 |
s0 = d->XMM_S(0); |
1120 | 1108 |
s1 = s->XMM_S(0); |
1121 |
switch(float32_compare(s0, s1, &env->sse_status)) { |
|
1122 |
case -1: |
|
1123 |
eflags = CC_C; |
|
1124 |
break; |
|
1125 |
case 0: |
|
1126 |
eflags = CC_Z; |
|
1127 |
break; |
|
1128 |
case 1: |
|
1129 |
eflags = 0; |
|
1130 |
break; |
|
1131 |
case 2: |
|
1132 |
default: |
|
1133 |
eflags = CC_Z | CC_P | CC_C; |
|
1134 |
break; |
|
1135 |
} |
|
1136 |
CC_SRC = eflags; |
|
1109 |
ret = float32_compare(s0, s1, &env->sse_status); |
|
1110 |
CC_SRC = comis_eflags[ret + 1]; |
|
1137 | 1111 |
FORCE_RET(); |
1138 | 1112 |
} |
1139 | 1113 |
|
1140 | 1114 |
void OPPROTO op_ucomisd(void) |
1141 | 1115 |
{ |
1142 |
int eflags;
|
|
1116 |
int ret;
|
|
1143 | 1117 |
float64 d0, d1; |
1144 | 1118 |
Reg *d, *s; |
1145 | 1119 |
d = (Reg *)((char *)env + PARAM1); |
... | ... | |
1147 | 1121 |
|
1148 | 1122 |
d0 = d->XMM_D(0); |
1149 | 1123 |
d1 = s->XMM_D(0); |
1150 |
switch(float64_compare_quiet(d0, d1, &env->sse_status)) { |
|
1151 |
case -1: |
|
1152 |
eflags = CC_C; |
|
1153 |
break; |
|
1154 |
case 0: |
|
1155 |
eflags = CC_Z; |
|
1156 |
break; |
|
1157 |
case 1: |
|
1158 |
eflags = 0; |
|
1159 |
break; |
|
1160 |
case 2: |
|
1161 |
default: |
|
1162 |
eflags = CC_Z | CC_P | CC_C; |
|
1163 |
break; |
|
1164 |
} |
|
1165 |
CC_SRC = eflags; |
|
1124 |
ret = float64_compare_quiet(d0, d1, &env->sse_status); |
|
1125 |
CC_SRC = comis_eflags[ret + 1]; |
|
1166 | 1126 |
FORCE_RET(); |
1167 | 1127 |
} |
1168 | 1128 |
|
1169 | 1129 |
void OPPROTO op_comisd(void) |
1170 | 1130 |
{ |
1171 |
int eflags;
|
|
1131 |
int ret;
|
|
1172 | 1132 |
float64 d0, d1; |
1173 | 1133 |
Reg *d, *s; |
1174 | 1134 |
d = (Reg *)((char *)env + PARAM1); |
... | ... | |
1176 | 1136 |
|
1177 | 1137 |
d0 = d->XMM_D(0); |
1178 | 1138 |
d1 = s->XMM_D(0); |
1179 |
switch(float64_compare(d0, d1, &env->sse_status)) { |
|
1180 |
case -1: |
|
1181 |
eflags = CC_C; |
|
1182 |
break; |
|
1183 |
case 0: |
|
1184 |
eflags = CC_Z; |
|
1185 |
break; |
|
1186 |
case 1: |
|
1187 |
eflags = 0; |
|
1188 |
break; |
|
1189 |
case 2: |
|
1190 |
default: |
|
1191 |
eflags = CC_Z | CC_P | CC_C; |
|
1192 |
break; |
|
1193 |
} |
|
1194 |
CC_SRC = eflags; |
|
1139 |
ret = float64_compare(d0, d1, &env->sse_status); |
|
1140 |
CC_SRC = comis_eflags[ret + 1]; |
|
1195 | 1141 |
FORCE_RET(); |
1196 | 1142 |
} |
1197 | 1143 |
|
Also available in: Unified diff