Commit 1c97856dcc4557f75eb9a86ec5300f9450a1e1a0

Authored by aurel32
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
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); //
... ...