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