Commit 1c97856dcc4557f75eb9a86ec5300f9450a1e1a0
1 parent
f4887919
target-ppc: convert SPE FP ops to TCG
Including a few bug fixes: - Don't clear high part for instruction with 32-bit destination - Fix efscmp* and etstcmp* return value Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5783 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
681 additions
and
1007 deletions
target-ppc/helper.h
... | ... | @@ -60,10 +60,77 @@ DEF_HELPER_3(fnmsub, i64, i64, i64, i64) |
60 | 60 | DEF_HELPER_1(fabs, i64, i64) |
61 | 61 | DEF_HELPER_1(fnabs, i64, i64) |
62 | 62 | DEF_HELPER_1(fneg, i64, i64) |
63 | -DEF_HELPER_1(fsqrt, i64, i64); | |
64 | -DEF_HELPER_1(fre, i64, i64); | |
65 | -DEF_HELPER_1(fres, i64, i64); | |
66 | -DEF_HELPER_1(frsqrte, i64, i64); | |
63 | +DEF_HELPER_1(fsqrt, i64, i64) | |
64 | +DEF_HELPER_1(fre, i64, i64) | |
65 | +DEF_HELPER_1(fres, i64, i64) | |
66 | +DEF_HELPER_1(frsqrte, i64, i64) | |
67 | 67 | DEF_HELPER_3(fsel, i64, i64, i64, i64) |
68 | 68 | |
69 | +DEF_HELPER_1(efscfsi, i32, i32) | |
70 | +DEF_HELPER_1(efscfui, i32, i32) | |
71 | +DEF_HELPER_1(efscfuf, i32, i32) | |
72 | +DEF_HELPER_1(efscfsf, i32, i32) | |
73 | +DEF_HELPER_1(efsctsi, i32, i32) | |
74 | +DEF_HELPER_1(efsctui, i32, i32) | |
75 | +DEF_HELPER_1(efsctsiz, i32, i32) | |
76 | +DEF_HELPER_1(efsctuiz, i32, i32) | |
77 | +DEF_HELPER_1(efsctsf, i32, i32) | |
78 | +DEF_HELPER_1(efsctuf, i32, i32) | |
79 | +DEF_HELPER_1(evfscfsi, i64, i64) | |
80 | +DEF_HELPER_1(evfscfui, i64, i64) | |
81 | +DEF_HELPER_1(evfscfuf, i64, i64) | |
82 | +DEF_HELPER_1(evfscfsf, i64, i64) | |
83 | +DEF_HELPER_1(evfsctsi, i64, i64) | |
84 | +DEF_HELPER_1(evfsctui, i64, i64) | |
85 | +DEF_HELPER_1(evfsctsiz, i64, i64) | |
86 | +DEF_HELPER_1(evfsctuiz, i64, i64) | |
87 | +DEF_HELPER_1(evfsctsf, i64, i64) | |
88 | +DEF_HELPER_1(evfsctuf, i64, i64) | |
89 | +DEF_HELPER_2(efsadd, i32, i32, i32) | |
90 | +DEF_HELPER_2(efssub, i32, i32, i32) | |
91 | +DEF_HELPER_2(efsmul, i32, i32, i32) | |
92 | +DEF_HELPER_2(efsdiv, i32, i32, i32) | |
93 | +DEF_HELPER_2(evfsadd, i64, i64, i64) | |
94 | +DEF_HELPER_2(evfssub, i64, i64, i64) | |
95 | +DEF_HELPER_2(evfsmul, i64, i64, i64) | |
96 | +DEF_HELPER_2(evfsdiv, i64, i64, i64) | |
97 | +DEF_HELPER_2(efststlt, i32, i32, i32) | |
98 | +DEF_HELPER_2(efststgt, i32, i32, i32) | |
99 | +DEF_HELPER_2(efststeq, i32, i32, i32) | |
100 | +DEF_HELPER_2(efscmplt, i32, i32, i32) | |
101 | +DEF_HELPER_2(efscmpgt, i32, i32, i32) | |
102 | +DEF_HELPER_2(efscmpeq, i32, i32, i32) | |
103 | +DEF_HELPER_2(evfststlt, i32, i64, i64) | |
104 | +DEF_HELPER_2(evfststgt, i32, i64, i64) | |
105 | +DEF_HELPER_2(evfststeq, i32, i64, i64) | |
106 | +DEF_HELPER_2(evfscmplt, i32, i64, i64) | |
107 | +DEF_HELPER_2(evfscmpgt, i32, i64, i64) | |
108 | +DEF_HELPER_2(evfscmpeq, i32, i64, i64) | |
109 | +DEF_HELPER_1(efdcfsi, i64, i32) | |
110 | +DEF_HELPER_1(efdcfsid, i64, i64) | |
111 | +DEF_HELPER_1(efdcfui, i64, i32) | |
112 | +DEF_HELPER_1(efdcfuid, i64, i64) | |
113 | +DEF_HELPER_1(efdctsi, i32, i64) | |
114 | +DEF_HELPER_1(efdctui, i32, i64) | |
115 | +DEF_HELPER_1(efdctsiz, i32, i64) | |
116 | +DEF_HELPER_1(efdctsidz, i64, i64) | |
117 | +DEF_HELPER_1(efdctuiz, i32, i64) | |
118 | +DEF_HELPER_1(efdctuidz, i64, i64) | |
119 | +DEF_HELPER_1(efdcfsf, i64, i32) | |
120 | +DEF_HELPER_1(efdcfuf, i64, i32) | |
121 | +DEF_HELPER_1(efdctsf, i32, i64) | |
122 | +DEF_HELPER_1(efdctuf, i32, i64) | |
123 | +DEF_HELPER_1(efscfd, i32, i64) | |
124 | +DEF_HELPER_1(efdcfs, i64, i32) | |
125 | +DEF_HELPER_2(efdadd, i64, i64, i64) | |
126 | +DEF_HELPER_2(efdsub, i64, i64, i64) | |
127 | +DEF_HELPER_2(efdmul, i64, i64, i64) | |
128 | +DEF_HELPER_2(efddiv, i64, i64, i64) | |
129 | +DEF_HELPER_2(efdtstlt, i32, i64, i64) | |
130 | +DEF_HELPER_2(efdtstgt, i32, i64, i64) | |
131 | +DEF_HELPER_2(efdtsteq, i32, i64, i64) | |
132 | +DEF_HELPER_2(efdcmplt, i32, i64, i64) | |
133 | +DEF_HELPER_2(efdcmpgt, i32, i64, i64) | |
134 | +DEF_HELPER_2(efdcmpeq, i32, i64, i64) | |
135 | + | |
69 | 136 | #include "def-helper.h" | ... | ... |
target-ppc/op.c
... | ... | @@ -960,468 +960,4 @@ void OPPROTO op_srli32_T1_64 (void) |
960 | 960 | RETURN(); |
961 | 961 | } |
962 | 962 | |
963 | -void OPPROTO op_evfssub (void) | |
964 | -{ | |
965 | - do_evfssub(); | |
966 | - RETURN(); | |
967 | -} | |
968 | - | |
969 | -void OPPROTO op_evfsadd (void) | |
970 | -{ | |
971 | - do_evfsadd(); | |
972 | - RETURN(); | |
973 | -} | |
974 | - | |
975 | -void OPPROTO op_evfsnabs (void) | |
976 | -{ | |
977 | - do_evfsnabs(); | |
978 | - RETURN(); | |
979 | -} | |
980 | - | |
981 | -void OPPROTO op_evfsabs (void) | |
982 | -{ | |
983 | - do_evfsabs(); | |
984 | - RETURN(); | |
985 | -} | |
986 | - | |
987 | -void OPPROTO op_evfsneg (void) | |
988 | -{ | |
989 | - do_evfsneg(); | |
990 | - RETURN(); | |
991 | -} | |
992 | - | |
993 | -void OPPROTO op_evfsdiv (void) | |
994 | -{ | |
995 | - do_evfsdiv(); | |
996 | - RETURN(); | |
997 | -} | |
998 | - | |
999 | -void OPPROTO op_evfsmul (void) | |
1000 | -{ | |
1001 | - do_evfsmul(); | |
1002 | - RETURN(); | |
1003 | -} | |
1004 | - | |
1005 | -void OPPROTO op_evfscmplt (void) | |
1006 | -{ | |
1007 | - do_evfscmplt(); | |
1008 | - RETURN(); | |
1009 | -} | |
1010 | - | |
1011 | -void OPPROTO op_evfscmpgt (void) | |
1012 | -{ | |
1013 | - do_evfscmpgt(); | |
1014 | - RETURN(); | |
1015 | -} | |
1016 | - | |
1017 | -void OPPROTO op_evfscmpeq (void) | |
1018 | -{ | |
1019 | - do_evfscmpeq(); | |
1020 | - RETURN(); | |
1021 | -} | |
1022 | - | |
1023 | -void OPPROTO op_evfscfsi (void) | |
1024 | -{ | |
1025 | - do_evfscfsi(); | |
1026 | - RETURN(); | |
1027 | -} | |
1028 | - | |
1029 | -void OPPROTO op_evfscfui (void) | |
1030 | -{ | |
1031 | - do_evfscfui(); | |
1032 | - RETURN(); | |
1033 | -} | |
1034 | - | |
1035 | -void OPPROTO op_evfscfsf (void) | |
1036 | -{ | |
1037 | - do_evfscfsf(); | |
1038 | - RETURN(); | |
1039 | -} | |
1040 | - | |
1041 | -void OPPROTO op_evfscfuf (void) | |
1042 | -{ | |
1043 | - do_evfscfuf(); | |
1044 | - RETURN(); | |
1045 | -} | |
1046 | - | |
1047 | -void OPPROTO op_evfsctsi (void) | |
1048 | -{ | |
1049 | - do_evfsctsi(); | |
1050 | - RETURN(); | |
1051 | -} | |
1052 | - | |
1053 | -void OPPROTO op_evfsctui (void) | |
1054 | -{ | |
1055 | - do_evfsctui(); | |
1056 | - RETURN(); | |
1057 | -} | |
1058 | - | |
1059 | -void OPPROTO op_evfsctsf (void) | |
1060 | -{ | |
1061 | - do_evfsctsf(); | |
1062 | - RETURN(); | |
1063 | -} | |
1064 | - | |
1065 | -void OPPROTO op_evfsctuf (void) | |
1066 | -{ | |
1067 | - do_evfsctuf(); | |
1068 | - RETURN(); | |
1069 | -} | |
1070 | - | |
1071 | -void OPPROTO op_evfsctuiz (void) | |
1072 | -{ | |
1073 | - do_evfsctuiz(); | |
1074 | - RETURN(); | |
1075 | -} | |
1076 | - | |
1077 | -void OPPROTO op_evfsctsiz (void) | |
1078 | -{ | |
1079 | - do_evfsctsiz(); | |
1080 | - RETURN(); | |
1081 | -} | |
1082 | - | |
1083 | -void OPPROTO op_evfststlt (void) | |
1084 | -{ | |
1085 | - do_evfststlt(); | |
1086 | - RETURN(); | |
1087 | -} | |
1088 | - | |
1089 | -void OPPROTO op_evfststgt (void) | |
1090 | -{ | |
1091 | - do_evfststgt(); | |
1092 | - RETURN(); | |
1093 | -} | |
1094 | - | |
1095 | -void OPPROTO op_evfststeq (void) | |
1096 | -{ | |
1097 | - do_evfststeq(); | |
1098 | - RETURN(); | |
1099 | -} | |
1100 | - | |
1101 | -void OPPROTO op_efssub (void) | |
1102 | -{ | |
1103 | - T0_64 = _do_efssub(T0_64, T1_64); | |
1104 | - RETURN(); | |
1105 | -} | |
1106 | - | |
1107 | -void OPPROTO op_efsadd (void) | |
1108 | -{ | |
1109 | - T0_64 = _do_efsadd(T0_64, T1_64); | |
1110 | - RETURN(); | |
1111 | -} | |
1112 | - | |
1113 | -void OPPROTO op_efsnabs (void) | |
1114 | -{ | |
1115 | - T0_64 = _do_efsnabs(T0_64); | |
1116 | - RETURN(); | |
1117 | -} | |
1118 | - | |
1119 | -void OPPROTO op_efsabs (void) | |
1120 | -{ | |
1121 | - T0_64 = _do_efsabs(T0_64); | |
1122 | - RETURN(); | |
1123 | -} | |
1124 | - | |
1125 | -void OPPROTO op_efsneg (void) | |
1126 | -{ | |
1127 | - T0_64 = _do_efsneg(T0_64); | |
1128 | - RETURN(); | |
1129 | -} | |
1130 | - | |
1131 | -void OPPROTO op_efsdiv (void) | |
1132 | -{ | |
1133 | - T0_64 = _do_efsdiv(T0_64, T1_64); | |
1134 | - RETURN(); | |
1135 | -} | |
1136 | - | |
1137 | -void OPPROTO op_efsmul (void) | |
1138 | -{ | |
1139 | - T0_64 = _do_efsmul(T0_64, T1_64); | |
1140 | - RETURN(); | |
1141 | -} | |
1142 | - | |
1143 | -void OPPROTO op_efscmplt (void) | |
1144 | -{ | |
1145 | - do_efscmplt(); | |
1146 | - RETURN(); | |
1147 | -} | |
1148 | - | |
1149 | -void OPPROTO op_efscmpgt (void) | |
1150 | -{ | |
1151 | - do_efscmpgt(); | |
1152 | - RETURN(); | |
1153 | -} | |
1154 | - | |
1155 | -void OPPROTO op_efscfd (void) | |
1156 | -{ | |
1157 | - do_efscfd(); | |
1158 | - RETURN(); | |
1159 | -} | |
1160 | - | |
1161 | -void OPPROTO op_efscmpeq (void) | |
1162 | -{ | |
1163 | - do_efscmpeq(); | |
1164 | - RETURN(); | |
1165 | -} | |
1166 | - | |
1167 | -void OPPROTO op_efscfsi (void) | |
1168 | -{ | |
1169 | - do_efscfsi(); | |
1170 | - RETURN(); | |
1171 | -} | |
1172 | - | |
1173 | -void OPPROTO op_efscfui (void) | |
1174 | -{ | |
1175 | - do_efscfui(); | |
1176 | - RETURN(); | |
1177 | -} | |
1178 | - | |
1179 | -void OPPROTO op_efscfsf (void) | |
1180 | -{ | |
1181 | - do_efscfsf(); | |
1182 | - RETURN(); | |
1183 | -} | |
1184 | - | |
1185 | -void OPPROTO op_efscfuf (void) | |
1186 | -{ | |
1187 | - do_efscfuf(); | |
1188 | - RETURN(); | |
1189 | -} | |
1190 | - | |
1191 | -void OPPROTO op_efsctsi (void) | |
1192 | -{ | |
1193 | - do_efsctsi(); | |
1194 | - RETURN(); | |
1195 | -} | |
1196 | - | |
1197 | -void OPPROTO op_efsctui (void) | |
1198 | -{ | |
1199 | - do_efsctui(); | |
1200 | - RETURN(); | |
1201 | -} | |
1202 | - | |
1203 | -void OPPROTO op_efsctsf (void) | |
1204 | -{ | |
1205 | - do_efsctsf(); | |
1206 | - RETURN(); | |
1207 | -} | |
1208 | - | |
1209 | -void OPPROTO op_efsctuf (void) | |
1210 | -{ | |
1211 | - do_efsctuf(); | |
1212 | - RETURN(); | |
1213 | -} | |
1214 | - | |
1215 | -void OPPROTO op_efsctsiz (void) | |
1216 | -{ | |
1217 | - do_efsctsiz(); | |
1218 | - RETURN(); | |
1219 | -} | |
1220 | - | |
1221 | -void OPPROTO op_efsctuiz (void) | |
1222 | -{ | |
1223 | - do_efsctuiz(); | |
1224 | - RETURN(); | |
1225 | -} | |
1226 | - | |
1227 | -void OPPROTO op_efststlt (void) | |
1228 | -{ | |
1229 | - T0 = _do_efststlt(T0_64, T1_64); | |
1230 | - RETURN(); | |
1231 | -} | |
1232 | - | |
1233 | -void OPPROTO op_efststgt (void) | |
1234 | -{ | |
1235 | - T0 = _do_efststgt(T0_64, T1_64); | |
1236 | - RETURN(); | |
1237 | -} | |
1238 | - | |
1239 | -void OPPROTO op_efststeq (void) | |
1240 | -{ | |
1241 | - T0 = _do_efststeq(T0_64, T1_64); | |
1242 | - RETURN(); | |
1243 | -} | |
1244 | 963 | |
1245 | -void OPPROTO op_efdsub (void) | |
1246 | -{ | |
1247 | - CPU_DoubleU u1, u2; | |
1248 | - u1.ll = T0_64; | |
1249 | - u2.ll = T1_64; | |
1250 | - u1.d = float64_sub(u1.d, u2.d, &env->spe_status); | |
1251 | - T0_64 = u1.ll; | |
1252 | - RETURN(); | |
1253 | -} | |
1254 | - | |
1255 | -void OPPROTO op_efdadd (void) | |
1256 | -{ | |
1257 | - CPU_DoubleU u1, u2; | |
1258 | - u1.ll = T0_64; | |
1259 | - u2.ll = T1_64; | |
1260 | - u1.d = float64_add(u1.d, u2.d, &env->spe_status); | |
1261 | - T0_64 = u1.ll; | |
1262 | - RETURN(); | |
1263 | -} | |
1264 | - | |
1265 | -void OPPROTO op_efdcfsid (void) | |
1266 | -{ | |
1267 | - do_efdcfsi(); | |
1268 | - RETURN(); | |
1269 | -} | |
1270 | - | |
1271 | -void OPPROTO op_efdcfuid (void) | |
1272 | -{ | |
1273 | - do_efdcfui(); | |
1274 | - RETURN(); | |
1275 | -} | |
1276 | - | |
1277 | -void OPPROTO op_efdnabs (void) | |
1278 | -{ | |
1279 | - T0_64 |= 0x8000000000000000ULL; | |
1280 | - RETURN(); | |
1281 | -} | |
1282 | - | |
1283 | -void OPPROTO op_efdabs (void) | |
1284 | -{ | |
1285 | - T0_64 &= ~0x8000000000000000ULL; | |
1286 | - RETURN(); | |
1287 | -} | |
1288 | - | |
1289 | -void OPPROTO op_efdneg (void) | |
1290 | -{ | |
1291 | - T0_64 ^= 0x8000000000000000ULL; | |
1292 | - RETURN(); | |
1293 | -} | |
1294 | - | |
1295 | -void OPPROTO op_efddiv (void) | |
1296 | -{ | |
1297 | - CPU_DoubleU u1, u2; | |
1298 | - u1.ll = T0_64; | |
1299 | - u2.ll = T1_64; | |
1300 | - u1.d = float64_div(u1.d, u2.d, &env->spe_status); | |
1301 | - T0_64 = u1.ll; | |
1302 | - RETURN(); | |
1303 | -} | |
1304 | - | |
1305 | -void OPPROTO op_efdmul (void) | |
1306 | -{ | |
1307 | - CPU_DoubleU u1, u2; | |
1308 | - u1.ll = T0_64; | |
1309 | - u2.ll = T1_64; | |
1310 | - u1.d = float64_mul(u1.d, u2.d, &env->spe_status); | |
1311 | - T0_64 = u1.ll; | |
1312 | - RETURN(); | |
1313 | -} | |
1314 | - | |
1315 | -void OPPROTO op_efdctsidz (void) | |
1316 | -{ | |
1317 | - do_efdctsiz(); | |
1318 | - RETURN(); | |
1319 | -} | |
1320 | - | |
1321 | -void OPPROTO op_efdctuidz (void) | |
1322 | -{ | |
1323 | - do_efdctuiz(); | |
1324 | - RETURN(); | |
1325 | -} | |
1326 | - | |
1327 | -void OPPROTO op_efdcmplt (void) | |
1328 | -{ | |
1329 | - do_efdcmplt(); | |
1330 | - RETURN(); | |
1331 | -} | |
1332 | - | |
1333 | -void OPPROTO op_efdcmpgt (void) | |
1334 | -{ | |
1335 | - do_efdcmpgt(); | |
1336 | - RETURN(); | |
1337 | -} | |
1338 | - | |
1339 | -void OPPROTO op_efdcfs (void) | |
1340 | -{ | |
1341 | - do_efdcfs(); | |
1342 | - RETURN(); | |
1343 | -} | |
1344 | - | |
1345 | -void OPPROTO op_efdcmpeq (void) | |
1346 | -{ | |
1347 | - do_efdcmpeq(); | |
1348 | - RETURN(); | |
1349 | -} | |
1350 | - | |
1351 | -void OPPROTO op_efdcfsi (void) | |
1352 | -{ | |
1353 | - do_efdcfsi(); | |
1354 | - RETURN(); | |
1355 | -} | |
1356 | - | |
1357 | -void OPPROTO op_efdcfui (void) | |
1358 | -{ | |
1359 | - do_efdcfui(); | |
1360 | - RETURN(); | |
1361 | -} | |
1362 | - | |
1363 | -void OPPROTO op_efdcfsf (void) | |
1364 | -{ | |
1365 | - do_efdcfsf(); | |
1366 | - RETURN(); | |
1367 | -} | |
1368 | - | |
1369 | -void OPPROTO op_efdcfuf (void) | |
1370 | -{ | |
1371 | - do_efdcfuf(); | |
1372 | - RETURN(); | |
1373 | -} | |
1374 | - | |
1375 | -void OPPROTO op_efdctsi (void) | |
1376 | -{ | |
1377 | - do_efdctsi(); | |
1378 | - RETURN(); | |
1379 | -} | |
1380 | - | |
1381 | -void OPPROTO op_efdctui (void) | |
1382 | -{ | |
1383 | - do_efdctui(); | |
1384 | - RETURN(); | |
1385 | -} | |
1386 | - | |
1387 | -void OPPROTO op_efdctsf (void) | |
1388 | -{ | |
1389 | - do_efdctsf(); | |
1390 | - RETURN(); | |
1391 | -} | |
1392 | - | |
1393 | -void OPPROTO op_efdctuf (void) | |
1394 | -{ | |
1395 | - do_efdctuf(); | |
1396 | - RETURN(); | |
1397 | -} | |
1398 | - | |
1399 | -void OPPROTO op_efdctuiz (void) | |
1400 | -{ | |
1401 | - do_efdctuiz(); | |
1402 | - RETURN(); | |
1403 | -} | |
1404 | - | |
1405 | -void OPPROTO op_efdctsiz (void) | |
1406 | -{ | |
1407 | - do_efdctsiz(); | |
1408 | - RETURN(); | |
1409 | -} | |
1410 | - | |
1411 | -void OPPROTO op_efdtstlt (void) | |
1412 | -{ | |
1413 | - T0 = _do_efdtstlt(T0_64, T1_64); | |
1414 | - RETURN(); | |
1415 | -} | |
1416 | - | |
1417 | -void OPPROTO op_efdtstgt (void) | |
1418 | -{ | |
1419 | - T0 = _do_efdtstgt(T0_64, T1_64); | |
1420 | - RETURN(); | |
1421 | -} | |
1422 | - | |
1423 | -void OPPROTO op_efdtsteq (void) | |
1424 | -{ | |
1425 | - T0 = _do_efdtsteq(T0_64, T1_64); | |
1426 | - RETURN(); | |
1427 | -} | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -1757,6 +1757,7 @@ void do_440_dlmzb (void) |
1757 | 1757 | T0 = i; |
1758 | 1758 | } |
1759 | 1759 | |
1760 | +/*****************************************************************************/ | |
1760 | 1761 | /* SPE extension helpers */ |
1761 | 1762 | /* Use a table to make this quicker */ |
1762 | 1763 | static uint8_t hbrev[16] = { |
... | ... | @@ -1800,36 +1801,8 @@ uint32_t helper_cntlzw32 (uint32_t val) |
1800 | 1801 | return clz32(val); |
1801 | 1802 | } |
1802 | 1803 | |
1803 | -#define DO_SPE_OP1(name) \ | |
1804 | -void do_ev##name (void) \ | |
1805 | -{ \ | |
1806 | - T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32) << 32) | \ | |
1807 | - (uint64_t)_do_e##name(T0_64); \ | |
1808 | -} | |
1809 | - | |
1810 | -#define DO_SPE_OP2(name) \ | |
1811 | -void do_ev##name (void) \ | |
1812 | -{ \ | |
1813 | - T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32, T1_64 >> 32) << 32) | \ | |
1814 | - (uint64_t)_do_e##name(T0_64, T1_64); \ | |
1815 | -} | |
1816 | - | |
1817 | -/* Fixed-point vector comparisons */ | |
1818 | -#define DO_SPE_CMP(name) \ | |
1819 | -void do_ev##name (void) \ | |
1820 | -{ \ | |
1821 | - T0 = _do_evcmp_merge((uint64_t)_do_e##name(T0_64 >> 32, \ | |
1822 | - T1_64 >> 32) << 32, \ | |
1823 | - _do_e##name(T0_64, T1_64)); \ | |
1824 | -} | |
1825 | - | |
1826 | -static always_inline uint32_t _do_evcmp_merge (int t0, int t1) | |
1827 | -{ | |
1828 | - return (t0 << 3) | (t1 << 2) | ((t0 | t1) << 1) | (t0 & t1); | |
1829 | -} | |
1830 | - | |
1831 | -/* Single precision floating-point conversions from/to integer */ | |
1832 | -static always_inline uint32_t _do_efscfsi (int32_t val) | |
1804 | +/* Single-precision floating-point conversions */ | |
1805 | +static always_inline uint32_t efscfsi (uint32_t val) | |
1833 | 1806 | { |
1834 | 1807 | CPU_FloatU u; |
1835 | 1808 | |
... | ... | @@ -1838,7 +1811,7 @@ static always_inline uint32_t _do_efscfsi (int32_t val) |
1838 | 1811 | return u.l; |
1839 | 1812 | } |
1840 | 1813 | |
1841 | -static always_inline uint32_t _do_efscfui (uint32_t val) | |
1814 | +static always_inline uint32_t efscfui (uint32_t val) | |
1842 | 1815 | { |
1843 | 1816 | CPU_FloatU u; |
1844 | 1817 | |
... | ... | @@ -1847,7 +1820,7 @@ static always_inline uint32_t _do_efscfui (uint32_t val) |
1847 | 1820 | return u.l; |
1848 | 1821 | } |
1849 | 1822 | |
1850 | -static always_inline int32_t _do_efsctsi (uint32_t val) | |
1823 | +static always_inline int32_t efsctsi (uint32_t val) | |
1851 | 1824 | { |
1852 | 1825 | CPU_FloatU u; |
1853 | 1826 | |
... | ... | @@ -1859,7 +1832,7 @@ static always_inline int32_t _do_efsctsi (uint32_t val) |
1859 | 1832 | return float32_to_int32(u.f, &env->spe_status); |
1860 | 1833 | } |
1861 | 1834 | |
1862 | -static always_inline uint32_t _do_efsctui (uint32_t val) | |
1835 | +static always_inline uint32_t efsctui (uint32_t val) | |
1863 | 1836 | { |
1864 | 1837 | CPU_FloatU u; |
1865 | 1838 | |
... | ... | @@ -1871,7 +1844,7 @@ static always_inline uint32_t _do_efsctui (uint32_t val) |
1871 | 1844 | return float32_to_uint32(u.f, &env->spe_status); |
1872 | 1845 | } |
1873 | 1846 | |
1874 | -static always_inline int32_t _do_efsctsiz (uint32_t val) | |
1847 | +static always_inline uint32_t efsctsiz (uint32_t val) | |
1875 | 1848 | { |
1876 | 1849 | CPU_FloatU u; |
1877 | 1850 | |
... | ... | @@ -1883,7 +1856,7 @@ static always_inline int32_t _do_efsctsiz (uint32_t val) |
1883 | 1856 | return float32_to_int32_round_to_zero(u.f, &env->spe_status); |
1884 | 1857 | } |
1885 | 1858 | |
1886 | -static always_inline uint32_t _do_efsctuiz (uint32_t val) | |
1859 | +static always_inline uint32_t efsctuiz (uint32_t val) | |
1887 | 1860 | { |
1888 | 1861 | CPU_FloatU u; |
1889 | 1862 | |
... | ... | @@ -1895,38 +1868,7 @@ static always_inline uint32_t _do_efsctuiz (uint32_t val) |
1895 | 1868 | return float32_to_uint32_round_to_zero(u.f, &env->spe_status); |
1896 | 1869 | } |
1897 | 1870 | |
1898 | -void do_efscfsi (void) | |
1899 | -{ | |
1900 | - T0_64 = _do_efscfsi(T0_64); | |
1901 | -} | |
1902 | - | |
1903 | -void do_efscfui (void) | |
1904 | -{ | |
1905 | - T0_64 = _do_efscfui(T0_64); | |
1906 | -} | |
1907 | - | |
1908 | -void do_efsctsi (void) | |
1909 | -{ | |
1910 | - T0_64 = _do_efsctsi(T0_64); | |
1911 | -} | |
1912 | - | |
1913 | -void do_efsctui (void) | |
1914 | -{ | |
1915 | - T0_64 = _do_efsctui(T0_64); | |
1916 | -} | |
1917 | - | |
1918 | -void do_efsctsiz (void) | |
1919 | -{ | |
1920 | - T0_64 = _do_efsctsiz(T0_64); | |
1921 | -} | |
1922 | - | |
1923 | -void do_efsctuiz (void) | |
1924 | -{ | |
1925 | - T0_64 = _do_efsctuiz(T0_64); | |
1926 | -} | |
1927 | - | |
1928 | -/* Single precision floating-point conversion to/from fractional */ | |
1929 | -static always_inline uint32_t _do_efscfsf (uint32_t val) | |
1871 | +static always_inline uint32_t efscfsf (uint32_t val) | |
1930 | 1872 | { |
1931 | 1873 | CPU_FloatU u; |
1932 | 1874 | float32 tmp; |
... | ... | @@ -1938,7 +1880,7 @@ static always_inline uint32_t _do_efscfsf (uint32_t val) |
1938 | 1880 | return u.l; |
1939 | 1881 | } |
1940 | 1882 | |
1941 | -static always_inline uint32_t _do_efscfuf (uint32_t val) | |
1883 | +static always_inline uint32_t efscfuf (uint32_t val) | |
1942 | 1884 | { |
1943 | 1885 | CPU_FloatU u; |
1944 | 1886 | float32 tmp; |
... | ... | @@ -1950,7 +1892,7 @@ static always_inline uint32_t _do_efscfuf (uint32_t val) |
1950 | 1892 | return u.l; |
1951 | 1893 | } |
1952 | 1894 | |
1953 | -static always_inline int32_t _do_efsctsf (uint32_t val) | |
1895 | +static always_inline uint32_t efsctsf (uint32_t val) | |
1954 | 1896 | { |
1955 | 1897 | CPU_FloatU u; |
1956 | 1898 | float32 tmp; |
... | ... | @@ -1965,7 +1907,7 @@ static always_inline int32_t _do_efsctsf (uint32_t val) |
1965 | 1907 | return float32_to_int32(u.f, &env->spe_status); |
1966 | 1908 | } |
1967 | 1909 | |
1968 | -static always_inline uint32_t _do_efsctuf (uint32_t val) | |
1910 | +static always_inline uint32_t efsctuf (uint32_t val) | |
1969 | 1911 | { |
1970 | 1912 | CPU_FloatU u; |
1971 | 1913 | float32 tmp; |
... | ... | @@ -1980,102 +1922,220 @@ static always_inline uint32_t _do_efsctuf (uint32_t val) |
1980 | 1922 | return float32_to_uint32(u.f, &env->spe_status); |
1981 | 1923 | } |
1982 | 1924 | |
1983 | -static always_inline int32_t _do_efsctsfz (uint32_t val) | |
1984 | -{ | |
1985 | - CPU_FloatU u; | |
1986 | - float32 tmp; | |
1987 | - | |
1988 | - u.l = val; | |
1989 | - /* NaN are not treated the same way IEEE 754 does */ | |
1990 | - if (unlikely(isnan(u.f))) | |
1991 | - return 0; | |
1992 | - tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
1993 | - u.f = float32_mul(u.f, tmp, &env->spe_status); | |
1994 | - | |
1995 | - return float32_to_int32_round_to_zero(u.f, &env->spe_status); | |
1925 | +#define HELPER_SPE_SINGLE_CONV(name) \ | |
1926 | +uint32_t helper_e##name (uint32_t val) \ | |
1927 | +{ \ | |
1928 | + return e##name(val); \ | |
1929 | +} | |
1930 | +/* efscfsi */ | |
1931 | +HELPER_SPE_SINGLE_CONV(fscfsi); | |
1932 | +/* efscfui */ | |
1933 | +HELPER_SPE_SINGLE_CONV(fscfui); | |
1934 | +/* efscfuf */ | |
1935 | +HELPER_SPE_SINGLE_CONV(fscfuf); | |
1936 | +/* efscfsf */ | |
1937 | +HELPER_SPE_SINGLE_CONV(fscfsf); | |
1938 | +/* efsctsi */ | |
1939 | +HELPER_SPE_SINGLE_CONV(fsctsi); | |
1940 | +/* efsctui */ | |
1941 | +HELPER_SPE_SINGLE_CONV(fsctui); | |
1942 | +/* efsctsiz */ | |
1943 | +HELPER_SPE_SINGLE_CONV(fsctsiz); | |
1944 | +/* efsctuiz */ | |
1945 | +HELPER_SPE_SINGLE_CONV(fsctuiz); | |
1946 | +/* efsctsf */ | |
1947 | +HELPER_SPE_SINGLE_CONV(fsctsf); | |
1948 | +/* efsctuf */ | |
1949 | +HELPER_SPE_SINGLE_CONV(fsctuf); | |
1950 | + | |
1951 | +#define HELPER_SPE_VECTOR_CONV(name) \ | |
1952 | +uint64_t helper_ev##name (uint64_t val) \ | |
1953 | +{ \ | |
1954 | + return ((uint64_t)e##name(val >> 32) << 32) | \ | |
1955 | + (uint64_t)e##name(val); \ | |
1996 | 1956 | } |
1957 | +/* evfscfsi */ | |
1958 | +HELPER_SPE_VECTOR_CONV(fscfsi); | |
1959 | +/* evfscfui */ | |
1960 | +HELPER_SPE_VECTOR_CONV(fscfui); | |
1961 | +/* evfscfuf */ | |
1962 | +HELPER_SPE_VECTOR_CONV(fscfuf); | |
1963 | +/* evfscfsf */ | |
1964 | +HELPER_SPE_VECTOR_CONV(fscfsf); | |
1965 | +/* evfsctsi */ | |
1966 | +HELPER_SPE_VECTOR_CONV(fsctsi); | |
1967 | +/* evfsctui */ | |
1968 | +HELPER_SPE_VECTOR_CONV(fsctui); | |
1969 | +/* evfsctsiz */ | |
1970 | +HELPER_SPE_VECTOR_CONV(fsctsiz); | |
1971 | +/* evfsctuiz */ | |
1972 | +HELPER_SPE_VECTOR_CONV(fsctuiz); | |
1973 | +/* evfsctsf */ | |
1974 | +HELPER_SPE_VECTOR_CONV(fsctsf); | |
1975 | +/* evfsctuf */ | |
1976 | +HELPER_SPE_VECTOR_CONV(fsctuf); | |
1997 | 1977 | |
1998 | -static always_inline uint32_t _do_efsctufz (uint32_t val) | |
1978 | +/* Single-precision floating-point arithmetic */ | |
1979 | +static always_inline uint32_t efsadd (uint32_t op1, uint32_t op2) | |
1999 | 1980 | { |
2000 | - CPU_FloatU u; | |
2001 | - float32 tmp; | |
2002 | - | |
2003 | - u.l = val; | |
2004 | - /* NaN are not treated the same way IEEE 754 does */ | |
2005 | - if (unlikely(isnan(u.f))) | |
2006 | - return 0; | |
2007 | - tmp = uint64_to_float32(1ULL << 32, &env->spe_status); | |
2008 | - u.f = float32_mul(u.f, tmp, &env->spe_status); | |
2009 | - | |
2010 | - return float32_to_uint32_round_to_zero(u.f, &env->spe_status); | |
1981 | + CPU_FloatU u1, u2; | |
1982 | + u1.l = op1; | |
1983 | + u2.l = op2; | |
1984 | + u1.f = float32_add(u1.f, u2.f, &env->spe_status); | |
1985 | + return u1.l; | |
2011 | 1986 | } |
2012 | 1987 | |
2013 | -void do_efscfsf (void) | |
1988 | +static always_inline uint32_t efssub (uint32_t op1, uint32_t op2) | |
2014 | 1989 | { |
2015 | - T0_64 = _do_efscfsf(T0_64); | |
1990 | + CPU_FloatU u1, u2; | |
1991 | + u1.l = op1; | |
1992 | + u2.l = op2; | |
1993 | + u1.f = float32_sub(u1.f, u2.f, &env->spe_status); | |
1994 | + return u1.l; | |
2016 | 1995 | } |
2017 | 1996 | |
2018 | -void do_efscfuf (void) | |
1997 | +static always_inline uint32_t efsmul (uint32_t op1, uint32_t op2) | |
2019 | 1998 | { |
2020 | - T0_64 = _do_efscfuf(T0_64); | |
1999 | + CPU_FloatU u1, u2; | |
2000 | + u1.l = op1; | |
2001 | + u2.l = op2; | |
2002 | + u1.f = float32_mul(u1.f, u2.f, &env->spe_status); | |
2003 | + return u1.l; | |
2021 | 2004 | } |
2022 | 2005 | |
2023 | -void do_efsctsf (void) | |
2006 | +static always_inline uint32_t efsdiv (uint32_t op1, uint32_t op2) | |
2024 | 2007 | { |
2025 | - T0_64 = _do_efsctsf(T0_64); | |
2008 | + CPU_FloatU u1, u2; | |
2009 | + u1.l = op1; | |
2010 | + u2.l = op2; | |
2011 | + u1.f = float32_div(u1.f, u2.f, &env->spe_status); | |
2012 | + return u1.l; | |
2026 | 2013 | } |
2027 | 2014 | |
2028 | -void do_efsctuf (void) | |
2015 | +#define HELPER_SPE_SINGLE_ARITH(name) \ | |
2016 | +uint32_t helper_e##name (uint32_t op1, uint32_t op2) \ | |
2017 | +{ \ | |
2018 | + return e##name(op1, op2); \ | |
2019 | +} | |
2020 | +/* efsadd */ | |
2021 | +HELPER_SPE_SINGLE_ARITH(fsadd); | |
2022 | +/* efssub */ | |
2023 | +HELPER_SPE_SINGLE_ARITH(fssub); | |
2024 | +/* efsmul */ | |
2025 | +HELPER_SPE_SINGLE_ARITH(fsmul); | |
2026 | +/* efsdiv */ | |
2027 | +HELPER_SPE_SINGLE_ARITH(fsdiv); | |
2028 | + | |
2029 | +#define HELPER_SPE_VECTOR_ARITH(name) \ | |
2030 | +uint64_t helper_ev##name (uint64_t op1, uint64_t op2) \ | |
2031 | +{ \ | |
2032 | + return ((uint64_t)e##name(op1 >> 32, op2 >> 32) << 32) | \ | |
2033 | + (uint64_t)e##name(op1, op2); \ | |
2034 | +} | |
2035 | +/* evfsadd */ | |
2036 | +HELPER_SPE_VECTOR_ARITH(fsadd); | |
2037 | +/* evfssub */ | |
2038 | +HELPER_SPE_VECTOR_ARITH(fssub); | |
2039 | +/* evfsmul */ | |
2040 | +HELPER_SPE_VECTOR_ARITH(fsmul); | |
2041 | +/* evfsdiv */ | |
2042 | +HELPER_SPE_VECTOR_ARITH(fsdiv); | |
2043 | + | |
2044 | +/* Single-precision floating-point comparisons */ | |
2045 | +static always_inline uint32_t efststlt (uint32_t op1, uint32_t op2) | |
2029 | 2046 | { |
2030 | - T0_64 = _do_efsctuf(T0_64); | |
2047 | + CPU_FloatU u1, u2; | |
2048 | + u1.l = op1; | |
2049 | + u2.l = op2; | |
2050 | + return float32_lt(u1.f, u2.f, &env->spe_status) ? 4 : 0; | |
2031 | 2051 | } |
2032 | 2052 | |
2033 | -void do_efsctsfz (void) | |
2053 | +static always_inline uint32_t efststgt (uint32_t op1, uint32_t op2) | |
2034 | 2054 | { |
2035 | - T0_64 = _do_efsctsfz(T0_64); | |
2055 | + CPU_FloatU u1, u2; | |
2056 | + u1.l = op1; | |
2057 | + u2.l = op2; | |
2058 | + return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 4; | |
2036 | 2059 | } |
2037 | 2060 | |
2038 | -void do_efsctufz (void) | |
2061 | +static always_inline uint32_t efststeq (uint32_t op1, uint32_t op2) | |
2039 | 2062 | { |
2040 | - T0_64 = _do_efsctufz(T0_64); | |
2063 | + CPU_FloatU u1, u2; | |
2064 | + u1.l = op1; | |
2065 | + u2.l = op2; | |
2066 | + return float32_eq(u1.f, u2.f, &env->spe_status) ? 4 : 0; | |
2041 | 2067 | } |
2042 | 2068 | |
2043 | -/* Double precision floating point helpers */ | |
2044 | -static always_inline int _do_efdcmplt (uint64_t op1, uint64_t op2) | |
2069 | +static always_inline uint32_t efscmplt (uint32_t op1, uint32_t op2) | |
2045 | 2070 | { |
2046 | 2071 | /* XXX: TODO: test special values (NaN, infinites, ...) */ |
2047 | - return _do_efdtstlt(op1, op2); | |
2072 | + return efststlt(op1, op2); | |
2048 | 2073 | } |
2049 | 2074 | |
2050 | -static always_inline int _do_efdcmpgt (uint64_t op1, uint64_t op2) | |
2075 | +static always_inline uint32_t efscmpgt (uint32_t op1, uint32_t op2) | |
2051 | 2076 | { |
2052 | 2077 | /* XXX: TODO: test special values (NaN, infinites, ...) */ |
2053 | - return _do_efdtstgt(op1, op2); | |
2078 | + return efststgt(op1, op2); | |
2054 | 2079 | } |
2055 | 2080 | |
2056 | -static always_inline int _do_efdcmpeq (uint64_t op1, uint64_t op2) | |
2081 | +static always_inline uint32_t efscmpeq (uint32_t op1, uint32_t op2) | |
2057 | 2082 | { |
2058 | 2083 | /* XXX: TODO: test special values (NaN, infinites, ...) */ |
2059 | - return _do_efdtsteq(op1, op2); | |
2084 | + return efststeq(op1, op2); | |
2060 | 2085 | } |
2061 | 2086 | |
2062 | -void do_efdcmplt (void) | |
2087 | +#define HELPER_SINGLE_SPE_CMP(name) \ | |
2088 | +uint32_t helper_e##name (uint32_t op1, uint32_t op2) \ | |
2089 | +{ \ | |
2090 | + return e##name(op1, op2) << 2; \ | |
2091 | +} | |
2092 | +/* efststlt */ | |
2093 | +HELPER_SINGLE_SPE_CMP(fststlt); | |
2094 | +/* efststgt */ | |
2095 | +HELPER_SINGLE_SPE_CMP(fststgt); | |
2096 | +/* efststeq */ | |
2097 | +HELPER_SINGLE_SPE_CMP(fststeq); | |
2098 | +/* efscmplt */ | |
2099 | +HELPER_SINGLE_SPE_CMP(fscmplt); | |
2100 | +/* efscmpgt */ | |
2101 | +HELPER_SINGLE_SPE_CMP(fscmpgt); | |
2102 | +/* efscmpeq */ | |
2103 | +HELPER_SINGLE_SPE_CMP(fscmpeq); | |
2104 | + | |
2105 | +static always_inline uint32_t evcmp_merge (int t0, int t1) | |
2063 | 2106 | { |
2064 | - T0 = _do_efdcmplt(T0_64, T1_64); | |
2107 | + return (t0 << 3) | (t1 << 2) | ((t0 | t1) << 1) | (t0 & t1); | |
2065 | 2108 | } |
2066 | 2109 | |
2067 | -void do_efdcmpgt (void) | |
2068 | -{ | |
2069 | - T0 = _do_efdcmpgt(T0_64, T1_64); | |
2110 | +#define HELPER_VECTOR_SPE_CMP(name) \ | |
2111 | +uint32_t helper_ev##name (uint64_t op1, uint64_t op2) \ | |
2112 | +{ \ | |
2113 | + return evcmp_merge(e##name(op1 >> 32, op2 >> 32), e##name(op1, op2)); \ | |
2070 | 2114 | } |
2115 | +/* evfststlt */ | |
2116 | +HELPER_VECTOR_SPE_CMP(fststlt); | |
2117 | +/* evfststgt */ | |
2118 | +HELPER_VECTOR_SPE_CMP(fststgt); | |
2119 | +/* evfststeq */ | |
2120 | +HELPER_VECTOR_SPE_CMP(fststeq); | |
2121 | +/* evfscmplt */ | |
2122 | +HELPER_VECTOR_SPE_CMP(fscmplt); | |
2123 | +/* evfscmpgt */ | |
2124 | +HELPER_VECTOR_SPE_CMP(fscmpgt); | |
2125 | +/* evfscmpeq */ | |
2126 | +HELPER_VECTOR_SPE_CMP(fscmpeq); | |
2071 | 2127 | |
2072 | -void do_efdcmpeq (void) | |
2128 | +/* Double-precision floating-point conversion */ | |
2129 | +uint64_t helper_efdcfsi (uint32_t val) | |
2073 | 2130 | { |
2074 | - T0 = _do_efdcmpeq(T0_64, T1_64); | |
2131 | + CPU_DoubleU u; | |
2132 | + | |
2133 | + u.d = int32_to_float64(val, &env->spe_status); | |
2134 | + | |
2135 | + return u.ll; | |
2075 | 2136 | } |
2076 | 2137 | |
2077 | -/* Double precision floating-point conversion to/from integer */ | |
2078 | -static always_inline uint64_t _do_efdcfsi (int64_t val) | |
2138 | +uint64_t helper_efdcfsid (uint64_t val) | |
2079 | 2139 | { |
2080 | 2140 | CPU_DoubleU u; |
2081 | 2141 | |
... | ... | @@ -2084,7 +2144,16 @@ static always_inline uint64_t _do_efdcfsi (int64_t val) |
2084 | 2144 | return u.ll; |
2085 | 2145 | } |
2086 | 2146 | |
2087 | -static always_inline uint64_t _do_efdcfui (uint64_t val) | |
2147 | +uint64_t helper_efdcfui (uint32_t val) | |
2148 | +{ | |
2149 | + CPU_DoubleU u; | |
2150 | + | |
2151 | + u.d = uint32_to_float64(val, &env->spe_status); | |
2152 | + | |
2153 | + return u.ll; | |
2154 | +} | |
2155 | + | |
2156 | +uint64_t helper_efdcfuid (uint64_t val) | |
2088 | 2157 | { |
2089 | 2158 | CPU_DoubleU u; |
2090 | 2159 | |
... | ... | @@ -2093,7 +2162,7 @@ static always_inline uint64_t _do_efdcfui (uint64_t val) |
2093 | 2162 | return u.ll; |
2094 | 2163 | } |
2095 | 2164 | |
2096 | -static always_inline int64_t _do_efdctsi (uint64_t val) | |
2165 | +uint32_t helper_efdctsi (uint64_t val) | |
2097 | 2166 | { |
2098 | 2167 | CPU_DoubleU u; |
2099 | 2168 | |
... | ... | @@ -2102,10 +2171,10 @@ static always_inline int64_t _do_efdctsi (uint64_t val) |
2102 | 2171 | if (unlikely(isnan(u.d))) |
2103 | 2172 | return 0; |
2104 | 2173 | |
2105 | - return float64_to_int64(u.d, &env->spe_status); | |
2174 | + return float64_to_int32(u.d, &env->spe_status); | |
2106 | 2175 | } |
2107 | 2176 | |
2108 | -static always_inline uint64_t _do_efdctui (uint64_t val) | |
2177 | +uint32_t helper_efdctui (uint64_t val) | |
2109 | 2178 | { |
2110 | 2179 | CPU_DoubleU u; |
2111 | 2180 | |
... | ... | @@ -2114,10 +2183,10 @@ static always_inline uint64_t _do_efdctui (uint64_t val) |
2114 | 2183 | if (unlikely(isnan(u.d))) |
2115 | 2184 | return 0; |
2116 | 2185 | |
2117 | - return float64_to_uint64(u.d, &env->spe_status); | |
2186 | + return float64_to_uint32(u.d, &env->spe_status); | |
2118 | 2187 | } |
2119 | 2188 | |
2120 | -static always_inline int64_t _do_efdctsiz (uint64_t val) | |
2189 | +uint32_t helper_efdctsiz (uint64_t val) | |
2121 | 2190 | { |
2122 | 2191 | CPU_DoubleU u; |
2123 | 2192 | |
... | ... | @@ -2126,10 +2195,10 @@ static always_inline int64_t _do_efdctsiz (uint64_t val) |
2126 | 2195 | if (unlikely(isnan(u.d))) |
2127 | 2196 | return 0; |
2128 | 2197 | |
2129 | - return float64_to_int64_round_to_zero(u.d, &env->spe_status); | |
2198 | + return float64_to_int32_round_to_zero(u.d, &env->spe_status); | |
2130 | 2199 | } |
2131 | 2200 | |
2132 | -static always_inline uint64_t _do_efdctuiz (uint64_t val) | |
2201 | +uint64_t helper_efdctsidz (uint64_t val) | |
2133 | 2202 | { |
2134 | 2203 | CPU_DoubleU u; |
2135 | 2204 | |
... | ... | @@ -2138,41 +2207,34 @@ static always_inline uint64_t _do_efdctuiz (uint64_t val) |
2138 | 2207 | if (unlikely(isnan(u.d))) |
2139 | 2208 | return 0; |
2140 | 2209 | |
2141 | - return float64_to_uint64_round_to_zero(u.d, &env->spe_status); | |
2210 | + return float64_to_int64_round_to_zero(u.d, &env->spe_status); | |
2142 | 2211 | } |
2143 | 2212 | |
2144 | -void do_efdcfsi (void) | |
2213 | +uint32_t helper_efdctuiz (uint64_t val) | |
2145 | 2214 | { |
2146 | - T0_64 = _do_efdcfsi(T0_64); | |
2147 | -} | |
2215 | + CPU_DoubleU u; | |
2148 | 2216 | |
2149 | -void do_efdcfui (void) | |
2150 | -{ | |
2151 | - T0_64 = _do_efdcfui(T0_64); | |
2152 | -} | |
2217 | + u.ll = val; | |
2218 | + /* NaN are not treated the same way IEEE 754 does */ | |
2219 | + if (unlikely(isnan(u.d))) | |
2220 | + return 0; | |
2153 | 2221 | |
2154 | -void do_efdctsi (void) | |
2155 | -{ | |
2156 | - T0_64 = _do_efdctsi(T0_64); | |
2222 | + return float64_to_uint32_round_to_zero(u.d, &env->spe_status); | |
2157 | 2223 | } |
2158 | 2224 | |
2159 | -void do_efdctui (void) | |
2225 | +uint64_t helper_efdctuidz (uint64_t val) | |
2160 | 2226 | { |
2161 | - T0_64 = _do_efdctui(T0_64); | |
2162 | -} | |
2227 | + CPU_DoubleU u; | |
2163 | 2228 | |
2164 | -void do_efdctsiz (void) | |
2165 | -{ | |
2166 | - T0_64 = _do_efdctsiz(T0_64); | |
2167 | -} | |
2229 | + u.ll = val; | |
2230 | + /* NaN are not treated the same way IEEE 754 does */ | |
2231 | + if (unlikely(isnan(u.d))) | |
2232 | + return 0; | |
2168 | 2233 | |
2169 | -void do_efdctuiz (void) | |
2170 | -{ | |
2171 | - T0_64 = _do_efdctuiz(T0_64); | |
2234 | + return float64_to_uint64_round_to_zero(u.d, &env->spe_status); | |
2172 | 2235 | } |
2173 | 2236 | |
2174 | -/* Double precision floating-point conversion to/from fractional */ | |
2175 | -static always_inline uint64_t _do_efdcfsf (int64_t val) | |
2237 | +uint64_t helper_efdcfsf (uint32_t val) | |
2176 | 2238 | { |
2177 | 2239 | CPU_DoubleU u; |
2178 | 2240 | float64 tmp; |
... | ... | @@ -2184,7 +2246,7 @@ static always_inline uint64_t _do_efdcfsf (int64_t val) |
2184 | 2246 | return u.ll; |
2185 | 2247 | } |
2186 | 2248 | |
2187 | -static always_inline uint64_t _do_efdcfuf (uint64_t val) | |
2249 | +uint64_t helper_efdcfuf (uint32_t val) | |
2188 | 2250 | { |
2189 | 2251 | CPU_DoubleU u; |
2190 | 2252 | float64 tmp; |
... | ... | @@ -2196,7 +2258,7 @@ static always_inline uint64_t _do_efdcfuf (uint64_t val) |
2196 | 2258 | return u.ll; |
2197 | 2259 | } |
2198 | 2260 | |
2199 | -static always_inline int64_t _do_efdctsf (uint64_t val) | |
2261 | +uint32_t helper_efdctsf (uint64_t val) | |
2200 | 2262 | { |
2201 | 2263 | CPU_DoubleU u; |
2202 | 2264 | float64 tmp; |
... | ... | @@ -2211,7 +2273,7 @@ static always_inline int64_t _do_efdctsf (uint64_t val) |
2211 | 2273 | return float64_to_int32(u.d, &env->spe_status); |
2212 | 2274 | } |
2213 | 2275 | |
2214 | -static always_inline uint64_t _do_efdctuf (uint64_t val) | |
2276 | +uint32_t helper_efdctuf (uint64_t val) | |
2215 | 2277 | { |
2216 | 2278 | CPU_DoubleU u; |
2217 | 2279 | float64 tmp; |
... | ... | @@ -2226,68 +2288,7 @@ static always_inline uint64_t _do_efdctuf (uint64_t val) |
2226 | 2288 | return float64_to_uint32(u.d, &env->spe_status); |
2227 | 2289 | } |
2228 | 2290 | |
2229 | -static always_inline int64_t _do_efdctsfz (uint64_t val) | |
2230 | -{ | |
2231 | - CPU_DoubleU u; | |
2232 | - float64 tmp; | |
2233 | - | |
2234 | - u.ll = val; | |
2235 | - /* NaN are not treated the same way IEEE 754 does */ | |
2236 | - if (unlikely(isnan(u.d))) | |
2237 | - return 0; | |
2238 | - tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
2239 | - u.d = float64_mul(u.d, tmp, &env->spe_status); | |
2240 | - | |
2241 | - return float64_to_int32_round_to_zero(u.d, &env->spe_status); | |
2242 | -} | |
2243 | - | |
2244 | -static always_inline uint64_t _do_efdctufz (uint64_t val) | |
2245 | -{ | |
2246 | - CPU_DoubleU u; | |
2247 | - float64 tmp; | |
2248 | - | |
2249 | - u.ll = val; | |
2250 | - /* NaN are not treated the same way IEEE 754 does */ | |
2251 | - if (unlikely(isnan(u.d))) | |
2252 | - return 0; | |
2253 | - tmp = uint64_to_float64(1ULL << 32, &env->spe_status); | |
2254 | - u.d = float64_mul(u.d, tmp, &env->spe_status); | |
2255 | - | |
2256 | - return float64_to_uint32_round_to_zero(u.d, &env->spe_status); | |
2257 | -} | |
2258 | - | |
2259 | -void do_efdcfsf (void) | |
2260 | -{ | |
2261 | - T0_64 = _do_efdcfsf(T0_64); | |
2262 | -} | |
2263 | - | |
2264 | -void do_efdcfuf (void) | |
2265 | -{ | |
2266 | - T0_64 = _do_efdcfuf(T0_64); | |
2267 | -} | |
2268 | - | |
2269 | -void do_efdctsf (void) | |
2270 | -{ | |
2271 | - T0_64 = _do_efdctsf(T0_64); | |
2272 | -} | |
2273 | - | |
2274 | -void do_efdctuf (void) | |
2275 | -{ | |
2276 | - T0_64 = _do_efdctuf(T0_64); | |
2277 | -} | |
2278 | - | |
2279 | -void do_efdctsfz (void) | |
2280 | -{ | |
2281 | - T0_64 = _do_efdctsfz(T0_64); | |
2282 | -} | |
2283 | - | |
2284 | -void do_efdctufz (void) | |
2285 | -{ | |
2286 | - T0_64 = _do_efdctufz(T0_64); | |
2287 | -} | |
2288 | - | |
2289 | -/* Floating point conversion between single and double precision */ | |
2290 | -static always_inline uint32_t _do_efscfd (uint64_t val) | |
2291 | +uint32_t helper_efscfd (uint64_t val) | |
2291 | 2292 | { |
2292 | 2293 | CPU_DoubleU u1; |
2293 | 2294 | CPU_FloatU u2; |
... | ... | @@ -2298,7 +2299,7 @@ static always_inline uint32_t _do_efscfd (uint64_t val) |
2298 | 2299 | return u2.l; |
2299 | 2300 | } |
2300 | 2301 | |
2301 | -static always_inline uint64_t _do_efdcfs (uint32_t val) | |
2302 | +uint64_t helper_efdcfs (uint32_t val) | |
2302 | 2303 | { |
2303 | 2304 | CPU_DoubleU u2; |
2304 | 2305 | CPU_FloatU u1; |
... | ... | @@ -2309,101 +2310,85 @@ static always_inline uint64_t _do_efdcfs (uint32_t val) |
2309 | 2310 | return u2.ll; |
2310 | 2311 | } |
2311 | 2312 | |
2312 | -void do_efscfd (void) | |
2313 | +/* Double precision fixed-point arithmetic */ | |
2314 | +uint64_t helper_efdadd (uint64_t op1, uint64_t op2) | |
2313 | 2315 | { |
2314 | - T0_64 = _do_efscfd(T0_64); | |
2316 | + CPU_DoubleU u1, u2; | |
2317 | + u1.ll = op1; | |
2318 | + u2.ll = op2; | |
2319 | + u1.d = float64_add(u1.d, u2.d, &env->spe_status); | |
2320 | + return u1.ll; | |
2315 | 2321 | } |
2316 | 2322 | |
2317 | -void do_efdcfs (void) | |
2323 | +uint64_t helper_efdsub (uint64_t op1, uint64_t op2) | |
2318 | 2324 | { |
2319 | - T0_64 = _do_efdcfs(T0_64); | |
2325 | + CPU_DoubleU u1, u2; | |
2326 | + u1.ll = op1; | |
2327 | + u2.ll = op2; | |
2328 | + u1.d = float64_sub(u1.d, u2.d, &env->spe_status); | |
2329 | + return u1.ll; | |
2320 | 2330 | } |
2321 | 2331 | |
2322 | -/* Single precision fixed-point vector arithmetic */ | |
2323 | -/* evfsabs */ | |
2324 | -DO_SPE_OP1(fsabs); | |
2325 | -/* evfsnabs */ | |
2326 | -DO_SPE_OP1(fsnabs); | |
2327 | -/* evfsneg */ | |
2328 | -DO_SPE_OP1(fsneg); | |
2329 | -/* evfsadd */ | |
2330 | -DO_SPE_OP2(fsadd); | |
2331 | -/* evfssub */ | |
2332 | -DO_SPE_OP2(fssub); | |
2333 | -/* evfsmul */ | |
2334 | -DO_SPE_OP2(fsmul); | |
2335 | -/* evfsdiv */ | |
2336 | -DO_SPE_OP2(fsdiv); | |
2337 | - | |
2338 | -/* Single-precision floating-point comparisons */ | |
2339 | -static always_inline int _do_efscmplt (uint32_t op1, uint32_t op2) | |
2332 | +uint64_t helper_efdmul (uint64_t op1, uint64_t op2) | |
2340 | 2333 | { |
2341 | - /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2342 | - return _do_efststlt(op1, op2); | |
2334 | + CPU_DoubleU u1, u2; | |
2335 | + u1.ll = op1; | |
2336 | + u2.ll = op2; | |
2337 | + u1.d = float64_mul(u1.d, u2.d, &env->spe_status); | |
2338 | + return u1.ll; | |
2343 | 2339 | } |
2344 | 2340 | |
2345 | -static always_inline int _do_efscmpgt (uint32_t op1, uint32_t op2) | |
2341 | +uint64_t helper_efddiv (uint64_t op1, uint64_t op2) | |
2346 | 2342 | { |
2347 | - /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2348 | - return _do_efststgt(op1, op2); | |
2343 | + CPU_DoubleU u1, u2; | |
2344 | + u1.ll = op1; | |
2345 | + u2.ll = op2; | |
2346 | + u1.d = float64_div(u1.d, u2.d, &env->spe_status); | |
2347 | + return u1.ll; | |
2349 | 2348 | } |
2350 | 2349 | |
2351 | -static always_inline int _do_efscmpeq (uint32_t op1, uint32_t op2) | |
2350 | +/* Double precision floating point helpers */ | |
2351 | +uint32_t helper_efdtstlt (uint64_t op1, uint64_t op2) | |
2352 | 2352 | { |
2353 | - /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2354 | - return _do_efststeq(op1, op2); | |
2353 | + CPU_DoubleU u1, u2; | |
2354 | + u1.ll = op1; | |
2355 | + u2.ll = op2; | |
2356 | + return float64_lt(u1.d, u2.d, &env->spe_status) ? 4 : 0; | |
2355 | 2357 | } |
2356 | 2358 | |
2357 | -void do_efscmplt (void) | |
2359 | +uint32_t helper_efdtstgt (uint64_t op1, uint64_t op2) | |
2358 | 2360 | { |
2359 | - T0 = _do_efscmplt(T0_64, T1_64); | |
2361 | + CPU_DoubleU u1, u2; | |
2362 | + u1.ll = op1; | |
2363 | + u2.ll = op2; | |
2364 | + return float64_le(u1.d, u2.d, &env->spe_status) ? 0 : 4; | |
2360 | 2365 | } |
2361 | 2366 | |
2362 | -void do_efscmpgt (void) | |
2367 | +uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2) | |
2363 | 2368 | { |
2364 | - T0 = _do_efscmpgt(T0_64, T1_64); | |
2369 | + CPU_DoubleU u1, u2; | |
2370 | + u1.ll = op1; | |
2371 | + u2.ll = op2; | |
2372 | + return float64_eq(u1.d, u2.d, &env->spe_status) ? 4 : 0; | |
2365 | 2373 | } |
2366 | 2374 | |
2367 | -void do_efscmpeq (void) | |
2375 | +uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2) | |
2368 | 2376 | { |
2369 | - T0 = _do_efscmpeq(T0_64, T1_64); | |
2377 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2378 | + return helper_efdtstlt(op1, op2); | |
2370 | 2379 | } |
2371 | 2380 | |
2372 | -/* Single-precision floating-point vector comparisons */ | |
2373 | -/* evfscmplt */ | |
2374 | -DO_SPE_CMP(fscmplt); | |
2375 | -/* evfscmpgt */ | |
2376 | -DO_SPE_CMP(fscmpgt); | |
2377 | -/* evfscmpeq */ | |
2378 | -DO_SPE_CMP(fscmpeq); | |
2379 | -/* evfststlt */ | |
2380 | -DO_SPE_CMP(fststlt); | |
2381 | -/* evfststgt */ | |
2382 | -DO_SPE_CMP(fststgt); | |
2383 | -/* evfststeq */ | |
2384 | -DO_SPE_CMP(fststeq); | |
2381 | +uint32_t helper_efdcmpgt (uint64_t op1, uint64_t op2) | |
2382 | +{ | |
2383 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2384 | + return helper_efdtstgt(op1, op2); | |
2385 | +} | |
2385 | 2386 | |
2386 | -/* Single-precision floating-point vector conversions */ | |
2387 | -/* evfscfsi */ | |
2388 | -DO_SPE_OP1(fscfsi); | |
2389 | -/* evfscfui */ | |
2390 | -DO_SPE_OP1(fscfui); | |
2391 | -/* evfscfuf */ | |
2392 | -DO_SPE_OP1(fscfuf); | |
2393 | -/* evfscfsf */ | |
2394 | -DO_SPE_OP1(fscfsf); | |
2395 | -/* evfsctsi */ | |
2396 | -DO_SPE_OP1(fsctsi); | |
2397 | -/* evfsctui */ | |
2398 | -DO_SPE_OP1(fsctui); | |
2399 | -/* evfsctsiz */ | |
2400 | -DO_SPE_OP1(fsctsiz); | |
2401 | -/* evfsctuiz */ | |
2402 | -DO_SPE_OP1(fsctuiz); | |
2403 | -/* evfsctsf */ | |
2404 | -DO_SPE_OP1(fsctsf); | |
2405 | -/* evfsctuf */ | |
2406 | -DO_SPE_OP1(fsctuf); | |
2387 | +uint32_t helper_efdcmpeq (uint64_t op1, uint64_t op2) | |
2388 | +{ | |
2389 | + /* XXX: TODO: test special values (NaN, infinites, ...) */ | |
2390 | + return helper_efdtsteq(op1, op2); | |
2391 | +} | |
2407 | 2392 | |
2408 | 2393 | /*****************************************************************************/ |
2409 | 2394 | /* Softmmu support */ | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -125,155 +125,4 @@ void do_load_403_pb (int num); |
125 | 125 | void do_store_403_pb (int num); |
126 | 126 | #endif |
127 | 127 | |
128 | -/* SPE extension helpers */ | |
129 | -/* Single precision floating-point helpers */ | |
130 | -void do_efscmplt (void); | |
131 | -void do_efscmpgt (void); | |
132 | -void do_efscmpeq (void); | |
133 | -void do_efscfsf (void); | |
134 | -void do_efscfuf (void); | |
135 | -void do_efsctsf (void); | |
136 | -void do_efsctuf (void); | |
137 | - | |
138 | -void do_efscfsi (void); | |
139 | -void do_efscfui (void); | |
140 | -void do_efsctsi (void); | |
141 | -void do_efsctui (void); | |
142 | -void do_efsctsiz (void); | |
143 | -void do_efsctuiz (void); | |
144 | - | |
145 | -/* Double precision floating-point helpers */ | |
146 | -void do_efdcmplt (void); | |
147 | -void do_efdcmpgt (void); | |
148 | -void do_efdcmpeq (void); | |
149 | -void do_efdcfsf (void); | |
150 | -void do_efdcfuf (void); | |
151 | -void do_efdctsf (void); | |
152 | -void do_efdctuf (void); | |
153 | - | |
154 | -void do_efdcfsi (void); | |
155 | -void do_efdcfui (void); | |
156 | -void do_efdctsi (void); | |
157 | -void do_efdctui (void); | |
158 | -void do_efdctsiz (void); | |
159 | -void do_efdctuiz (void); | |
160 | - | |
161 | -void do_efdcfs (void); | |
162 | -void do_efscfd (void); | |
163 | - | |
164 | -/* Floating-point vector helpers */ | |
165 | -void do_evfsabs (void); | |
166 | -void do_evfsnabs (void); | |
167 | -void do_evfsneg (void); | |
168 | -void do_evfsadd (void); | |
169 | -void do_evfssub (void); | |
170 | -void do_evfsmul (void); | |
171 | -void do_evfsdiv (void); | |
172 | -void do_evfscmplt (void); | |
173 | -void do_evfscmpgt (void); | |
174 | -void do_evfscmpeq (void); | |
175 | -void do_evfststlt (void); | |
176 | -void do_evfststgt (void); | |
177 | -void do_evfststeq (void); | |
178 | -void do_evfscfsi (void); | |
179 | -void do_evfscfui (void); | |
180 | -void do_evfscfsf (void); | |
181 | -void do_evfscfuf (void); | |
182 | -void do_evfsctsf (void); | |
183 | -void do_evfsctuf (void); | |
184 | -void do_evfsctsi (void); | |
185 | -void do_evfsctui (void); | |
186 | -void do_evfsctsiz (void); | |
187 | -void do_evfsctuiz (void); | |
188 | - | |
189 | -/* SPE extension */ | |
190 | -/* Single precision floating-point helpers */ | |
191 | -static always_inline uint32_t _do_efsabs (uint32_t val) | |
192 | -{ | |
193 | - return val & ~0x80000000; | |
194 | -} | |
195 | -static always_inline uint32_t _do_efsnabs (uint32_t val) | |
196 | -{ | |
197 | - return val | 0x80000000; | |
198 | -} | |
199 | -static always_inline uint32_t _do_efsneg (uint32_t val) | |
200 | -{ | |
201 | - return val ^ 0x80000000; | |
202 | -} | |
203 | -static always_inline uint32_t _do_efsadd (uint32_t op1, uint32_t op2) | |
204 | -{ | |
205 | - CPU_FloatU u1, u2; | |
206 | - u1.l = op1; | |
207 | - u2.l = op2; | |
208 | - u1.f = float32_add(u1.f, u2.f, &env->spe_status); | |
209 | - return u1.l; | |
210 | -} | |
211 | -static always_inline uint32_t _do_efssub (uint32_t op1, uint32_t op2) | |
212 | -{ | |
213 | - CPU_FloatU u1, u2; | |
214 | - u1.l = op1; | |
215 | - u2.l = op2; | |
216 | - u1.f = float32_sub(u1.f, u2.f, &env->spe_status); | |
217 | - return u1.l; | |
218 | -} | |
219 | -static always_inline uint32_t _do_efsmul (uint32_t op1, uint32_t op2) | |
220 | -{ | |
221 | - CPU_FloatU u1, u2; | |
222 | - u1.l = op1; | |
223 | - u2.l = op2; | |
224 | - u1.f = float32_mul(u1.f, u2.f, &env->spe_status); | |
225 | - return u1.l; | |
226 | -} | |
227 | -static always_inline uint32_t _do_efsdiv (uint32_t op1, uint32_t op2) | |
228 | -{ | |
229 | - CPU_FloatU u1, u2; | |
230 | - u1.l = op1; | |
231 | - u2.l = op2; | |
232 | - u1.f = float32_div(u1.f, u2.f, &env->spe_status); | |
233 | - return u1.l; | |
234 | -} | |
235 | - | |
236 | -static always_inline int _do_efststlt (uint32_t op1, uint32_t op2) | |
237 | -{ | |
238 | - CPU_FloatU u1, u2; | |
239 | - u1.l = op1; | |
240 | - u2.l = op2; | |
241 | - return float32_lt(u1.f, u2.f, &env->spe_status) ? 4 : 0; | |
242 | -} | |
243 | -static always_inline int _do_efststgt (uint32_t op1, uint32_t op2) | |
244 | -{ | |
245 | - CPU_FloatU u1, u2; | |
246 | - u1.l = op1; | |
247 | - u2.l = op2; | |
248 | - return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 4; | |
249 | -} | |
250 | -static always_inline int _do_efststeq (uint32_t op1, uint32_t op2) | |
251 | -{ | |
252 | - CPU_FloatU u1, u2; | |
253 | - u1.l = op1; | |
254 | - u2.l = op2; | |
255 | - return float32_eq(u1.f, u2.f, &env->spe_status) ? 4 : 0; | |
256 | -} | |
257 | -/* Double precision floating-point helpers */ | |
258 | -static always_inline int _do_efdtstlt (uint64_t op1, uint64_t op2) | |
259 | -{ | |
260 | - CPU_DoubleU u1, u2; | |
261 | - u1.ll = op1; | |
262 | - u2.ll = op2; | |
263 | - return float64_lt(u1.d, u2.d, &env->spe_status) ? 4 : 0; | |
264 | -} | |
265 | -static always_inline int _do_efdtstgt (uint64_t op1, uint64_t op2) | |
266 | -{ | |
267 | - CPU_DoubleU u1, u2; | |
268 | - u1.ll = op1; | |
269 | - u2.ll = op2; | |
270 | - return float64_le(u1.d, u2.d, &env->spe_status) ? 0 : 4; | |
271 | -} | |
272 | -static always_inline int _do_efdtsteq (uint64_t op1, uint64_t op2) | |
273 | -{ | |
274 | - CPU_DoubleU u1, u2; | |
275 | - u1.ll = op1; | |
276 | - u2.ll = op2; | |
277 | - return float64_eq(u1.d, u2.d, &env->spe_status) ? 4 : 0; | |
278 | -} | |
279 | 128 | #endif | ... | ... |
target-ppc/translate.c
... | ... | @@ -6861,81 +6861,261 @@ GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0x00000000, PPC_SPE); |
6861 | 6861 | #endif |
6862 | 6862 | |
6863 | 6863 | /*** SPE floating-point extension ***/ |
6864 | -#define GEN_SPEFPUOP_CONV(name) \ | |
6864 | +#if defined(TARGET_PPC64) | |
6865 | +#define GEN_SPEFPUOP_CONV_32_32(name) \ | |
6865 | 6866 | static always_inline void gen_##name (DisasContext *ctx) \ |
6866 | 6867 | { \ |
6867 | - gen_load_gpr64(cpu_T64[0], rB(ctx->opcode)); \ | |
6868 | - gen_op_##name(); \ | |
6869 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
6868 | + TCGv_i32 t0; \ | |
6869 | + TCGv t1; \ | |
6870 | + t0 = tcg_temp_new_i32(); \ | |
6871 | + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ | |
6872 | + gen_helper_##name(t0, t0); \ | |
6873 | + t1 = tcg_temp_new(); \ | |
6874 | + tcg_gen_extu_i32_tl(t1, t0); \ | |
6875 | + tcg_temp_free_i32(t0); \ | |
6876 | + tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ | |
6877 | + 0xFFFFFFFF00000000ULL); \ | |
6878 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1); \ | |
6879 | + tcg_temp_free(t1); \ | |
6870 | 6880 | } |
6871 | - | |
6872 | -#define GEN_SPEFPUOP_ARITH1(name) \ | |
6881 | +#define GEN_SPEFPUOP_CONV_32_64(name) \ | |
6882 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6883 | +{ \ | |
6884 | + TCGv_i32 t0; \ | |
6885 | + TCGv t1; \ | |
6886 | + t0 = tcg_temp_new_i32(); \ | |
6887 | + gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]); \ | |
6888 | + t1 = tcg_temp_new(); \ | |
6889 | + tcg_gen_extu_i32_tl(t1, t0); \ | |
6890 | + tcg_temp_free_i32(t0); \ | |
6891 | + tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ | |
6892 | + 0xFFFFFFFF00000000ULL); \ | |
6893 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1); \ | |
6894 | + tcg_temp_free(t1); \ | |
6895 | +} | |
6896 | +#define GEN_SPEFPUOP_CONV_64_32(name) \ | |
6897 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6898 | +{ \ | |
6899 | + TCGv_i32 t0 = tcg_temp_new_i32(); \ | |
6900 | + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ | |
6901 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0); \ | |
6902 | + tcg_temp_free_i32(t0); \ | |
6903 | +} | |
6904 | +#define GEN_SPEFPUOP_CONV_64_64(name) \ | |
6905 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6906 | +{ \ | |
6907 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ | |
6908 | +} | |
6909 | +#define GEN_SPEFPUOP_ARITH2_32_32(name) \ | |
6873 | 6910 | static always_inline void gen_##name (DisasContext *ctx) \ |
6874 | 6911 | { \ |
6912 | + TCGv_i32 t0, t1; \ | |
6913 | + TCGv_i64 t2; \ | |
6875 | 6914 | if (unlikely(!ctx->spe_enabled)) { \ |
6876 | 6915 | GEN_EXCP_NO_AP(ctx); \ |
6877 | 6916 | return; \ |
6878 | 6917 | } \ |
6879 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
6880 | - gen_op_##name(); \ | |
6881 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
6918 | + t0 = tcg_temp_new_i32(); \ | |
6919 | + t1 = tcg_temp_new_i32(); \ | |
6920 | + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
6921 | + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ | |
6922 | + gen_helper_##name(t0, t0, t1); \ | |
6923 | + tcg_temp_free_i32(t1); \ | |
6924 | + t2 = tcg_temp_new(); \ | |
6925 | + tcg_gen_extu_i32_tl(t2, t0); \ | |
6926 | + tcg_temp_free_i32(t0); \ | |
6927 | + tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ | |
6928 | + 0xFFFFFFFF00000000ULL); \ | |
6929 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2); \ | |
6930 | + tcg_temp_free(t2); \ | |
6882 | 6931 | } |
6883 | - | |
6884 | -#define GEN_SPEFPUOP_ARITH2(name) \ | |
6932 | +#define GEN_SPEFPUOP_ARITH2_64_64(name) \ | |
6885 | 6933 | static always_inline void gen_##name (DisasContext *ctx) \ |
6886 | 6934 | { \ |
6887 | 6935 | if (unlikely(!ctx->spe_enabled)) { \ |
6888 | 6936 | GEN_EXCP_NO_AP(ctx); \ |
6889 | 6937 | return; \ |
6890 | 6938 | } \ |
6891 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
6892 | - gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
6893 | - gen_op_##name(); \ | |
6894 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
6939 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ | |
6940 | + cpu_gpr[rB(ctx->opcode)]); \ | |
6895 | 6941 | } |
6896 | - | |
6897 | -#define GEN_SPEFPUOP_COMP(name) \ | |
6942 | +#define GEN_SPEFPUOP_COMP_32(name) \ | |
6898 | 6943 | static always_inline void gen_##name (DisasContext *ctx) \ |
6899 | 6944 | { \ |
6900 | - TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)]; \ | |
6945 | + TCGv_i32 t0, t1; \ | |
6901 | 6946 | if (unlikely(!ctx->spe_enabled)) { \ |
6902 | 6947 | GEN_EXCP_NO_AP(ctx); \ |
6903 | 6948 | return; \ |
6904 | 6949 | } \ |
6905 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
6906 | - gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
6907 | - gen_op_##name(); \ | |
6908 | - tcg_gen_trunc_tl_i32(crf, cpu_T[0]); \ | |
6909 | - tcg_gen_andi_i32(crf, crf, 0xf); \ | |
6950 | + t0 = tcg_temp_new_i32(); \ | |
6951 | + t1 = tcg_temp_new_i32(); \ | |
6952 | + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
6953 | + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ | |
6954 | + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1); \ | |
6955 | + tcg_temp_free_i32(t0); \ | |
6956 | + tcg_temp_free_i32(t1); \ | |
6957 | +} | |
6958 | +#define GEN_SPEFPUOP_COMP_64(name) \ | |
6959 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6960 | +{ \ | |
6961 | + if (unlikely(!ctx->spe_enabled)) { \ | |
6962 | + GEN_EXCP_NO_AP(ctx); \ | |
6963 | + return; \ | |
6964 | + } \ | |
6965 | + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ | |
6966 | + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ | |
6967 | +} | |
6968 | +#else | |
6969 | +#define GEN_SPEFPUOP_CONV_32_32(name) \ | |
6970 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6971 | +{ \ | |
6972 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ | |
6910 | 6973 | } |
6974 | +#define GEN_SPEFPUOP_CONV_32_64(name) \ | |
6975 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6976 | +{ \ | |
6977 | + TCGv_i64 t0 = tcg_temp_new_i64(); \ | |
6978 | + gen_load_gpr64(t0, rB(ctx->opcode)); \ | |
6979 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0); \ | |
6980 | + tcg_temp_free_i64(t0); \ | |
6981 | +} | |
6982 | +#define GEN_SPEFPUOP_CONV_64_32(name) \ | |
6983 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6984 | +{ \ | |
6985 | + TCGv_i64 t0 = tcg_temp_new_i64(); \ | |
6986 | + gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]); \ | |
6987 | + gen_store_gpr64(rD(ctx->opcode), t0); \ | |
6988 | + tcg_temp_free_i64(t0); \ | |
6989 | +} | |
6990 | +#define GEN_SPEFPUOP_CONV_64_64(name) \ | |
6991 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
6992 | +{ \ | |
6993 | + TCGv_i64 t0 = tcg_temp_new_i64(); \ | |
6994 | + gen_load_gpr64(t0, rB(ctx->opcode)); \ | |
6995 | + gen_helper_##name(t0, t0); \ | |
6996 | + gen_store_gpr64(rD(ctx->opcode), t0); \ | |
6997 | + tcg_temp_free_i64(t0); \ | |
6998 | +} | |
6999 | +#define GEN_SPEFPUOP_ARITH2_32_32(name) \ | |
7000 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
7001 | +{ \ | |
7002 | + if (unlikely(!ctx->spe_enabled)) { \ | |
7003 | + GEN_EXCP_NO_AP(ctx); \ | |
7004 | + return; \ | |
7005 | + } \ | |
7006 | + gen_helper_##name(cpu_gpr[rD(ctx->opcode)], \ | |
7007 | + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ | |
7008 | +} | |
7009 | +#define GEN_SPEFPUOP_ARITH2_64_64(name) \ | |
7010 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
7011 | +{ \ | |
7012 | + TCGv_i64 t0, t1; \ | |
7013 | + if (unlikely(!ctx->spe_enabled)) { \ | |
7014 | + GEN_EXCP_NO_AP(ctx); \ | |
7015 | + return; \ | |
7016 | + } \ | |
7017 | + t0 = tcg_temp_new_i64(); \ | |
7018 | + t1 = tcg_temp_new_i64(); \ | |
7019 | + gen_load_gpr64(t0, rA(ctx->opcode)); \ | |
7020 | + gen_load_gpr64(t1, rB(ctx->opcode)); \ | |
7021 | + gen_helper_##name(t0, t0, t1); \ | |
7022 | + gen_store_gpr64(rD(ctx->opcode), t0); \ | |
7023 | + tcg_temp_free_i64(t0); \ | |
7024 | + tcg_temp_free_i64(t1); \ | |
7025 | +} | |
7026 | +#define GEN_SPEFPUOP_COMP_32(name) \ | |
7027 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
7028 | +{ \ | |
7029 | + if (unlikely(!ctx->spe_enabled)) { \ | |
7030 | + GEN_EXCP_NO_AP(ctx); \ | |
7031 | + return; \ | |
7032 | + } \ | |
7033 | + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ | |
7034 | + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ | |
7035 | +} | |
7036 | +#define GEN_SPEFPUOP_COMP_64(name) \ | |
7037 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
7038 | +{ \ | |
7039 | + TCGv_i64 t0, t1; \ | |
7040 | + if (unlikely(!ctx->spe_enabled)) { \ | |
7041 | + GEN_EXCP_NO_AP(ctx); \ | |
7042 | + return; \ | |
7043 | + } \ | |
7044 | + t0 = tcg_temp_new_i64(); \ | |
7045 | + t1 = tcg_temp_new_i64(); \ | |
7046 | + gen_load_gpr64(t0, rA(ctx->opcode)); \ | |
7047 | + gen_load_gpr64(t1, rB(ctx->opcode)); \ | |
7048 | + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1); \ | |
7049 | + tcg_temp_free_i64(t0); \ | |
7050 | + tcg_temp_free_i64(t1); \ | |
7051 | +} | |
7052 | +#endif | |
6911 | 7053 | |
6912 | 7054 | /* Single precision floating-point vectors operations */ |
6913 | 7055 | /* Arithmetic */ |
6914 | -GEN_SPEFPUOP_ARITH2(evfsadd); | |
6915 | -GEN_SPEFPUOP_ARITH2(evfssub); | |
6916 | -GEN_SPEFPUOP_ARITH2(evfsmul); | |
6917 | -GEN_SPEFPUOP_ARITH2(evfsdiv); | |
6918 | -GEN_SPEFPUOP_ARITH1(evfsabs); | |
6919 | -GEN_SPEFPUOP_ARITH1(evfsnabs); | |
6920 | -GEN_SPEFPUOP_ARITH1(evfsneg); | |
7056 | +GEN_SPEFPUOP_ARITH2_64_64(evfsadd); | |
7057 | +GEN_SPEFPUOP_ARITH2_64_64(evfssub); | |
7058 | +GEN_SPEFPUOP_ARITH2_64_64(evfsmul); | |
7059 | +GEN_SPEFPUOP_ARITH2_64_64(evfsdiv); | |
7060 | +static always_inline void gen_evfsabs (DisasContext *ctx) | |
7061 | +{ | |
7062 | + if (unlikely(!ctx->spe_enabled)) { | |
7063 | + GEN_EXCP_NO_AP(ctx); | |
7064 | + return; | |
7065 | + } | |
7066 | +#if defined(TARGET_PPC64) | |
7067 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL); | |
7068 | +#else | |
7069 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000); | |
7070 | + tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000); | |
7071 | +#endif | |
7072 | +} | |
7073 | +static always_inline void gen_evfsnabs (DisasContext *ctx) | |
7074 | +{ | |
7075 | + if (unlikely(!ctx->spe_enabled)) { | |
7076 | + GEN_EXCP_NO_AP(ctx); | |
7077 | + return; | |
7078 | + } | |
7079 | +#if defined(TARGET_PPC64) | |
7080 | + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL); | |
7081 | +#else | |
7082 | + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); | |
7083 | + tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); | |
7084 | +#endif | |
7085 | +} | |
7086 | +static always_inline void gen_evfsneg (DisasContext *ctx) | |
7087 | +{ | |
7088 | + if (unlikely(!ctx->spe_enabled)) { | |
7089 | + GEN_EXCP_NO_AP(ctx); | |
7090 | + return; | |
7091 | + } | |
7092 | +#if defined(TARGET_PPC64) | |
7093 | + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL); | |
7094 | +#else | |
7095 | + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); | |
7096 | + tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); | |
7097 | +#endif | |
7098 | +} | |
7099 | + | |
6921 | 7100 | /* Conversion */ |
6922 | -GEN_SPEFPUOP_CONV(evfscfui); | |
6923 | -GEN_SPEFPUOP_CONV(evfscfsi); | |
6924 | -GEN_SPEFPUOP_CONV(evfscfuf); | |
6925 | -GEN_SPEFPUOP_CONV(evfscfsf); | |
6926 | -GEN_SPEFPUOP_CONV(evfsctui); | |
6927 | -GEN_SPEFPUOP_CONV(evfsctsi); | |
6928 | -GEN_SPEFPUOP_CONV(evfsctuf); | |
6929 | -GEN_SPEFPUOP_CONV(evfsctsf); | |
6930 | -GEN_SPEFPUOP_CONV(evfsctuiz); | |
6931 | -GEN_SPEFPUOP_CONV(evfsctsiz); | |
7101 | +GEN_SPEFPUOP_CONV_64_64(evfscfui); | |
7102 | +GEN_SPEFPUOP_CONV_64_64(evfscfsi); | |
7103 | +GEN_SPEFPUOP_CONV_64_64(evfscfuf); | |
7104 | +GEN_SPEFPUOP_CONV_64_64(evfscfsf); | |
7105 | +GEN_SPEFPUOP_CONV_64_64(evfsctui); | |
7106 | +GEN_SPEFPUOP_CONV_64_64(evfsctsi); | |
7107 | +GEN_SPEFPUOP_CONV_64_64(evfsctuf); | |
7108 | +GEN_SPEFPUOP_CONV_64_64(evfsctsf); | |
7109 | +GEN_SPEFPUOP_CONV_64_64(evfsctuiz); | |
7110 | +GEN_SPEFPUOP_CONV_64_64(evfsctsiz); | |
7111 | + | |
6932 | 7112 | /* Comparison */ |
6933 | -GEN_SPEFPUOP_COMP(evfscmpgt); | |
6934 | -GEN_SPEFPUOP_COMP(evfscmplt); | |
6935 | -GEN_SPEFPUOP_COMP(evfscmpeq); | |
6936 | -GEN_SPEFPUOP_COMP(evfststgt); | |
6937 | -GEN_SPEFPUOP_COMP(evfststlt); | |
6938 | -GEN_SPEFPUOP_COMP(evfststeq); | |
7113 | +GEN_SPEFPUOP_COMP_64(evfscmpgt); | |
7114 | +GEN_SPEFPUOP_COMP_64(evfscmplt); | |
7115 | +GEN_SPEFPUOP_COMP_64(evfscmpeq); | |
7116 | +GEN_SPEFPUOP_COMP_64(evfststgt); | |
7117 | +GEN_SPEFPUOP_COMP_64(evfststlt); | |
7118 | +GEN_SPEFPUOP_COMP_64(evfststeq); | |
6939 | 7119 | |
6940 | 7120 | /* Opcodes definitions */ |
6941 | 7121 | GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); // |
... | ... | @@ -6955,32 +7135,55 @@ GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU); // |
6955 | 7135 | |
6956 | 7136 | /* Single precision floating-point operations */ |
6957 | 7137 | /* Arithmetic */ |
6958 | -GEN_SPEFPUOP_ARITH2(efsadd); | |
6959 | -GEN_SPEFPUOP_ARITH2(efssub); | |
6960 | -GEN_SPEFPUOP_ARITH2(efsmul); | |
6961 | -GEN_SPEFPUOP_ARITH2(efsdiv); | |
6962 | -GEN_SPEFPUOP_ARITH1(efsabs); | |
6963 | -GEN_SPEFPUOP_ARITH1(efsnabs); | |
6964 | -GEN_SPEFPUOP_ARITH1(efsneg); | |
7138 | +GEN_SPEFPUOP_ARITH2_32_32(efsadd); | |
7139 | +GEN_SPEFPUOP_ARITH2_32_32(efssub); | |
7140 | +GEN_SPEFPUOP_ARITH2_32_32(efsmul); | |
7141 | +GEN_SPEFPUOP_ARITH2_32_32(efsdiv); | |
7142 | +static always_inline void gen_efsabs (DisasContext *ctx) | |
7143 | +{ | |
7144 | + if (unlikely(!ctx->spe_enabled)) { | |
7145 | + GEN_EXCP_NO_AP(ctx); | |
7146 | + return; | |
7147 | + } | |
7148 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL); | |
7149 | +} | |
7150 | +static always_inline void gen_efsnabs (DisasContext *ctx) | |
7151 | +{ | |
7152 | + if (unlikely(!ctx->spe_enabled)) { | |
7153 | + GEN_EXCP_NO_AP(ctx); | |
7154 | + return; | |
7155 | + } | |
7156 | + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); | |
7157 | +} | |
7158 | +static always_inline void gen_efsneg (DisasContext *ctx) | |
7159 | +{ | |
7160 | + if (unlikely(!ctx->spe_enabled)) { | |
7161 | + GEN_EXCP_NO_AP(ctx); | |
7162 | + return; | |
7163 | + } | |
7164 | + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); | |
7165 | +} | |
7166 | + | |
6965 | 7167 | /* Conversion */ |
6966 | -GEN_SPEFPUOP_CONV(efscfui); | |
6967 | -GEN_SPEFPUOP_CONV(efscfsi); | |
6968 | -GEN_SPEFPUOP_CONV(efscfuf); | |
6969 | -GEN_SPEFPUOP_CONV(efscfsf); | |
6970 | -GEN_SPEFPUOP_CONV(efsctui); | |
6971 | -GEN_SPEFPUOP_CONV(efsctsi); | |
6972 | -GEN_SPEFPUOP_CONV(efsctuf); | |
6973 | -GEN_SPEFPUOP_CONV(efsctsf); | |
6974 | -GEN_SPEFPUOP_CONV(efsctuiz); | |
6975 | -GEN_SPEFPUOP_CONV(efsctsiz); | |
6976 | -GEN_SPEFPUOP_CONV(efscfd); | |
7168 | +GEN_SPEFPUOP_CONV_32_32(efscfui); | |
7169 | +GEN_SPEFPUOP_CONV_32_32(efscfsi); | |
7170 | +GEN_SPEFPUOP_CONV_32_32(efscfuf); | |
7171 | +GEN_SPEFPUOP_CONV_32_32(efscfsf); | |
7172 | +GEN_SPEFPUOP_CONV_32_32(efsctui); | |
7173 | +GEN_SPEFPUOP_CONV_32_32(efsctsi); | |
7174 | +GEN_SPEFPUOP_CONV_32_32(efsctuf); | |
7175 | +GEN_SPEFPUOP_CONV_32_32(efsctsf); | |
7176 | +GEN_SPEFPUOP_CONV_32_32(efsctuiz); | |
7177 | +GEN_SPEFPUOP_CONV_32_32(efsctsiz); | |
7178 | +GEN_SPEFPUOP_CONV_32_64(efscfd); | |
7179 | + | |
6977 | 7180 | /* Comparison */ |
6978 | -GEN_SPEFPUOP_COMP(efscmpgt); | |
6979 | -GEN_SPEFPUOP_COMP(efscmplt); | |
6980 | -GEN_SPEFPUOP_COMP(efscmpeq); | |
6981 | -GEN_SPEFPUOP_COMP(efststgt); | |
6982 | -GEN_SPEFPUOP_COMP(efststlt); | |
6983 | -GEN_SPEFPUOP_COMP(efststeq); | |
7181 | +GEN_SPEFPUOP_COMP_32(efscmpgt); | |
7182 | +GEN_SPEFPUOP_COMP_32(efscmplt); | |
7183 | +GEN_SPEFPUOP_COMP_32(efscmpeq); | |
7184 | +GEN_SPEFPUOP_COMP_32(efststgt); | |
7185 | +GEN_SPEFPUOP_COMP_32(efststlt); | |
7186 | +GEN_SPEFPUOP_COMP_32(efststeq); | |
6984 | 7187 | |
6985 | 7188 | /* Opcodes definitions */ |
6986 | 7189 | GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPEFPU); // |
... | ... | @@ -7000,37 +7203,71 @@ GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU); // |
7000 | 7203 | |
7001 | 7204 | /* Double precision floating-point operations */ |
7002 | 7205 | /* Arithmetic */ |
7003 | -GEN_SPEFPUOP_ARITH2(efdadd); | |
7004 | -GEN_SPEFPUOP_ARITH2(efdsub); | |
7005 | -GEN_SPEFPUOP_ARITH2(efdmul); | |
7006 | -GEN_SPEFPUOP_ARITH2(efddiv); | |
7007 | -GEN_SPEFPUOP_ARITH1(efdabs); | |
7008 | -GEN_SPEFPUOP_ARITH1(efdnabs); | |
7009 | -GEN_SPEFPUOP_ARITH1(efdneg); | |
7206 | +GEN_SPEFPUOP_ARITH2_64_64(efdadd); | |
7207 | +GEN_SPEFPUOP_ARITH2_64_64(efdsub); | |
7208 | +GEN_SPEFPUOP_ARITH2_64_64(efdmul); | |
7209 | +GEN_SPEFPUOP_ARITH2_64_64(efddiv); | |
7210 | +static always_inline void gen_efdabs (DisasContext *ctx) | |
7211 | +{ | |
7212 | + if (unlikely(!ctx->spe_enabled)) { | |
7213 | + GEN_EXCP_NO_AP(ctx); | |
7214 | + return; | |
7215 | + } | |
7216 | +#if defined(TARGET_PPC64) | |
7217 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL); | |
7218 | +#else | |
7219 | + tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000); | |
7220 | +#endif | |
7221 | +} | |
7222 | +static always_inline void gen_efdnabs (DisasContext *ctx) | |
7223 | +{ | |
7224 | + if (unlikely(!ctx->spe_enabled)) { | |
7225 | + GEN_EXCP_NO_AP(ctx); | |
7226 | + return; | |
7227 | + } | |
7228 | +#if defined(TARGET_PPC64) | |
7229 | + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL); | |
7230 | +#else | |
7231 | + tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); | |
7232 | +#endif | |
7233 | +} | |
7234 | +static always_inline void gen_efdneg (DisasContext *ctx) | |
7235 | +{ | |
7236 | + if (unlikely(!ctx->spe_enabled)) { | |
7237 | + GEN_EXCP_NO_AP(ctx); | |
7238 | + return; | |
7239 | + } | |
7240 | +#if defined(TARGET_PPC64) | |
7241 | + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL); | |
7242 | +#else | |
7243 | + tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); | |
7244 | +#endif | |
7245 | +} | |
7246 | + | |
7010 | 7247 | /* Conversion */ |
7248 | +GEN_SPEFPUOP_CONV_64_32(efdcfui); | |
7249 | +GEN_SPEFPUOP_CONV_64_32(efdcfsi); | |
7250 | +GEN_SPEFPUOP_CONV_64_32(efdcfuf); | |
7251 | +GEN_SPEFPUOP_CONV_64_32(efdcfsf); | |
7252 | +GEN_SPEFPUOP_CONV_32_64(efdctui); | |
7253 | +GEN_SPEFPUOP_CONV_32_64(efdctsi); | |
7254 | +GEN_SPEFPUOP_CONV_32_64(efdctuf); | |
7255 | +GEN_SPEFPUOP_CONV_32_64(efdctsf); | |
7256 | +GEN_SPEFPUOP_CONV_32_64(efdctuiz); | |
7257 | +GEN_SPEFPUOP_CONV_32_64(efdctsiz); | |
7258 | +GEN_SPEFPUOP_CONV_64_32(efdcfs); | |
7259 | +GEN_SPEFPUOP_CONV_64_64(efdcfuid); | |
7260 | +GEN_SPEFPUOP_CONV_64_64(efdcfsid); | |
7261 | +GEN_SPEFPUOP_CONV_64_64(efdctuidz); | |
7262 | +GEN_SPEFPUOP_CONV_64_64(efdctsidz); | |
7011 | 7263 | |
7012 | -GEN_SPEFPUOP_CONV(efdcfui); | |
7013 | -GEN_SPEFPUOP_CONV(efdcfsi); | |
7014 | -GEN_SPEFPUOP_CONV(efdcfuf); | |
7015 | -GEN_SPEFPUOP_CONV(efdcfsf); | |
7016 | -GEN_SPEFPUOP_CONV(efdctui); | |
7017 | -GEN_SPEFPUOP_CONV(efdctsi); | |
7018 | -GEN_SPEFPUOP_CONV(efdctuf); | |
7019 | -GEN_SPEFPUOP_CONV(efdctsf); | |
7020 | -GEN_SPEFPUOP_CONV(efdctuiz); | |
7021 | -GEN_SPEFPUOP_CONV(efdctsiz); | |
7022 | -GEN_SPEFPUOP_CONV(efdcfs); | |
7023 | -GEN_SPEFPUOP_CONV(efdcfuid); | |
7024 | -GEN_SPEFPUOP_CONV(efdcfsid); | |
7025 | -GEN_SPEFPUOP_CONV(efdctuidz); | |
7026 | -GEN_SPEFPUOP_CONV(efdctsidz); | |
7027 | 7264 | /* Comparison */ |
7028 | -GEN_SPEFPUOP_COMP(efdcmpgt); | |
7029 | -GEN_SPEFPUOP_COMP(efdcmplt); | |
7030 | -GEN_SPEFPUOP_COMP(efdcmpeq); | |
7031 | -GEN_SPEFPUOP_COMP(efdtstgt); | |
7032 | -GEN_SPEFPUOP_COMP(efdtstlt); | |
7033 | -GEN_SPEFPUOP_COMP(efdtsteq); | |
7265 | +GEN_SPEFPUOP_COMP_64(efdcmpgt); | |
7266 | +GEN_SPEFPUOP_COMP_64(efdcmplt); | |
7267 | +GEN_SPEFPUOP_COMP_64(efdcmpeq); | |
7268 | +GEN_SPEFPUOP_COMP_64(efdtstgt); | |
7269 | +GEN_SPEFPUOP_COMP_64(efdtstlt); | |
7270 | +GEN_SPEFPUOP_COMP_64(efdtsteq); | |
7034 | 7271 | |
7035 | 7272 | /* Opcodes definitions */ |
7036 | 7273 | GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPEFPU); // | ... | ... |