Changeset 93782 in vbox for trunk/src/VBox
- Timestamp:
- Feb 16, 2022 9:09:02 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r93762 r93782 1144 1144 1145 1145 1146 /* bit scan */ 1146 /* 1147 * BSF - first (least significant) bit set 1148 */ 1147 1149 1148 1150 IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 1150 1152 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1151 1153 /** @todo check what real CPUs do. */ 1152 if (uSrc) 1153 { 1154 uint8_t iBit; 1155 uint32_t u32Src; 1156 if (uSrc & UINT32_MAX) 1157 { 1158 iBit = 0; 1159 u32Src = uSrc; 1160 } 1161 else 1162 { 1163 iBit = 32; 1164 u32Src = uSrc >> 32; 1165 } 1166 if (!(u32Src & UINT16_MAX)) 1167 { 1168 iBit += 16; 1169 u32Src >>= 16; 1170 } 1171 if (!(u32Src & UINT8_MAX)) 1172 { 1173 iBit += 8; 1174 u32Src >>= 8; 1175 } 1176 if (!(u32Src & 0xf)) 1177 { 1178 iBit += 4; 1179 u32Src >>= 4; 1180 } 1181 if (!(u32Src & 0x3)) 1182 { 1183 iBit += 2; 1184 u32Src >>= 2; 1185 } 1186 if (!(u32Src & 1)) 1187 { 1188 iBit += 1; 1189 Assert(u32Src & 2); 1190 } 1191 1192 *puDst = iBit; 1154 unsigned iBit = ASMBitFirstSetU64(uSrc); 1155 if (iBit) 1156 { 1157 *puDst = iBit - 1; 1193 1158 *pfEFlags &= ~X86_EFL_ZF; 1194 1159 } … … 1197 1162 } 1198 1163 1199 IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 1164 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1165 1166 IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 1200 1167 { 1201 1168 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1202 1169 /** @todo check what real CPUs do. */ 1170 unsigned iBit = ASMBitFirstSetU32(uSrc); 1171 if (iBit) 1172 { 1173 *puDst = iBit - 1; 1174 *pfEFlags &= ~X86_EFL_ZF; 1175 } 1176 else 1177 *pfEFlags |= X86_EFL_ZF; 1178 } 1179 1180 1181 IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 1182 { 1183 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1184 /** @todo check what real CPUs do. */ 1185 unsigned iBit = ASMBitFirstSetU16(uSrc); 1186 if (iBit) 1187 { 1188 *puDst = iBit - 1; 1189 *pfEFlags &= ~X86_EFL_ZF; 1190 } 1191 else 1192 *pfEFlags |= X86_EFL_ZF; 1193 } 1194 1195 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1196 1197 /* 1198 * BSR - last (most significant) bit set 1199 */ 1200 1201 IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 1202 { 1203 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1204 /** @todo check what real CPUs do. */ 1205 unsigned iBit = ASMBitLastSetU64(uSrc); 1203 1206 if (uSrc) 1204 1207 { 1205 uint8_t iBit; 1206 uint32_t u32Src; 1207 if (uSrc & UINT64_C(0xffffffff00000000)) 1208 { 1209 iBit = 63; 1210 u32Src = uSrc >> 32; 1211 } 1212 else 1213 { 1214 iBit = 31; 1215 u32Src = uSrc; 1216 } 1217 if (!(u32Src & UINT32_C(0xffff0000))) 1218 { 1219 iBit -= 16; 1220 u32Src <<= 16; 1221 } 1222 if (!(u32Src & UINT32_C(0xff000000))) 1223 { 1224 iBit -= 8; 1225 u32Src <<= 8; 1226 } 1227 if (!(u32Src & UINT32_C(0xf0000000))) 1228 { 1229 iBit -= 4; 1230 u32Src <<= 4; 1231 } 1232 if (!(u32Src & UINT32_C(0xc0000000))) 1233 { 1234 iBit -= 2; 1235 u32Src <<= 2; 1236 } 1237 if (!(u32Src & UINT32_C(0x80000000))) 1238 { 1239 iBit -= 1; 1240 Assert(u32Src & RT_BIT(30)); 1241 } 1242 1243 *puDst = iBit; 1208 *puDst = iBit - 1; 1244 1209 *pfEFlags &= ~X86_EFL_ZF; 1245 1210 } … … 1248 1213 } 1249 1214 1250 1251 /* Unary operands. */ 1252 1253 IEM_DECL_IMPL_DEF(void, iemAImpl_inc_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1254 { 1255 uint64_t uDst = *puDst; 1256 uint64_t uResult = uDst + 1; 1257 *puDst = uResult; 1258 1259 /* 1260 * Calc EFLAGS. 1261 * CF is NOT modified for hysterical raisins (allegedly for carrying and 1262 * borrowing in arithmetic loops on intel 8008). 1263 */ 1264 uint32_t fEfl = *pfEFlags & ~(X86_EFL_STATUS_BITS & ~X86_EFL_CF); 1265 fEfl |= g_afParity[uResult & 0xff]; 1266 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1267 fEfl |= X86_EFL_CALC_ZF(uResult); 1268 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1269 fEfl |= (((uDst ^ RT_BIT_64(63)) & uResult) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1270 *pfEFlags = fEfl; 1271 } 1272 1273 1274 IEM_DECL_IMPL_DEF(void, iemAImpl_dec_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1275 { 1276 uint64_t uDst = *puDst; 1277 uint64_t uResult = uDst - 1; 1278 *puDst = uResult; 1279 1280 /* 1281 * Calc EFLAGS. 1282 * CF is NOT modified for hysterical raisins (allegedly for carrying and 1283 * borrowing in arithmetic loops on intel 8008). 1284 */ 1285 uint32_t fEfl = *pfEFlags & ~(X86_EFL_STATUS_BITS & ~X86_EFL_CF); 1286 fEfl |= g_afParity[uResult & 0xff]; 1287 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1288 fEfl |= X86_EFL_CALC_ZF(uResult); 1289 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1290 fEfl |= ((uDst & (uResult ^ RT_BIT_64(63))) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1291 *pfEFlags = fEfl; 1292 } 1293 1294 1295 IEM_DECL_IMPL_DEF(void, iemAImpl_not_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1296 { 1297 uint64_t uDst = *puDst; 1298 uint64_t uResult = ~uDst; 1299 *puDst = uResult; 1300 /* EFLAGS are not modified. */ 1301 RT_NOREF_PV(pfEFlags); 1302 } 1303 1304 1305 IEM_DECL_IMPL_DEF(void, iemAImpl_neg_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1306 { 1307 uint64_t uDst = 0; 1308 uint64_t uSrc = *puDst; 1309 uint64_t uResult = uDst - uSrc; 1310 *puDst = uResult; 1311 1312 /* Calc EFLAGS. */ 1313 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1314 fEfl |= (uSrc != 0) << X86_EFL_CF_BIT; 1315 fEfl |= g_afParity[uResult & 0xff]; 1316 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1317 fEfl |= X86_EFL_CALC_ZF(uResult); 1318 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1319 fEfl |= ((uSrc & uResult) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1320 *pfEFlags = fEfl; 1321 } 1322 1323 1324 /** 64-bit locked unary operand operation. */ 1325 # define DO_LOCKED_UNARY_OP_U64(a_Mnemonic) \ 1326 do { \ 1327 uint64_t uOld = ASMAtomicReadU64(puDst); \ 1328 uint64_t uTmp; \ 1329 uint32_t fEflTmp; \ 1330 do \ 1331 { \ 1332 uTmp = uOld; \ 1333 fEflTmp = *pfEFlags; \ 1334 iemAImpl_ ## a_Mnemonic ## _u64(&uTmp, &fEflTmp); \ 1335 } while (!ASMAtomicCmpXchgExU64(puDst, uTmp, uOld, &uOld)); \ 1336 *pfEFlags = fEflTmp; \ 1337 } while (0) 1338 1339 IEM_DECL_IMPL_DEF(void, iemAImpl_inc_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1340 { 1341 DO_LOCKED_UNARY_OP_U64(inc); 1342 } 1343 1344 1345 IEM_DECL_IMPL_DEF(void, iemAImpl_dec_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1346 { 1347 DO_LOCKED_UNARY_OP_U64(dec); 1348 } 1349 1350 1351 IEM_DECL_IMPL_DEF(void, iemAImpl_not_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1352 { 1353 DO_LOCKED_UNARY_OP_U64(not); 1354 } 1355 1356 1357 IEM_DECL_IMPL_DEF(void, iemAImpl_neg_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1358 { 1359 DO_LOCKED_UNARY_OP_U64(neg); 1360 } 1361 1362 1363 /* Shift and rotate. */ 1364 1365 IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1366 { 1367 cShift &= 63; 1368 if (cShift) 1369 { 1370 uint64_t uDst = *puDst; 1371 uint64_t uResult; 1372 uResult = uDst << cShift; 1373 uResult |= uDst >> (64 - cShift); 1374 *puDst = uResult; 1375 1376 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1377 it the same way as for 1 bit shifts. */ 1378 AssertCompile(X86_EFL_CF_BIT == 0); 1379 uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); 1380 uint32_t fCarry = (uResult & 1); 1381 fEfl |= fCarry; 1382 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1383 *pfEFlags = fEfl; 1384 } 1385 } 1386 1387 1388 IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1389 { 1390 cShift &= 63; 1391 if (cShift) 1392 { 1393 uint64_t uDst = *puDst; 1394 uint64_t uResult; 1395 uResult = uDst >> cShift; 1396 uResult |= uDst << (64 - cShift); 1397 *puDst = uResult; 1398 1399 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1400 it the same way as for 1 bit shifts (OF = OF XOR New-CF). */ 1401 AssertCompile(X86_EFL_CF_BIT == 0); 1402 uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); 1403 uint32_t fCarry = (uResult >> 63) & X86_EFL_CF; 1404 fEfl |= fCarry; 1405 fEfl |= (((uResult >> 62) ^ fCarry) << X86_EFL_OF_BIT) & X86_EFL_OF; 1406 *pfEFlags = fEfl; 1407 } 1408 } 1409 1410 1411 IEM_DECL_IMPL_DEF(void, iemAImpl_rcl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1412 { 1413 cShift &= 63; 1414 if (cShift) 1415 { 1416 uint32_t fEfl = *pfEFlags; 1417 uint64_t uDst = *puDst; 1418 uint64_t uResult; 1419 uResult = uDst << cShift; 1420 AssertCompile(X86_EFL_CF_BIT == 0); 1421 if (cShift > 1) 1422 uResult |= uDst >> (65 - cShift); 1423 uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (cShift - 1); 1424 *puDst = uResult; 1425 1426 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1427 it the same way as for 1 bit shifts. */ 1428 uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF; 1429 fEfl &= ~(X86_EFL_CF | X86_EFL_OF); 1430 fEfl |= fCarry; 1431 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1432 *pfEFlags = fEfl; 1433 } 1434 } 1435 1436 1437 IEM_DECL_IMPL_DEF(void, iemAImpl_rcr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1438 { 1439 cShift &= 63; 1440 if (cShift) 1441 { 1442 uint32_t fEfl = *pfEFlags; 1443 uint64_t uDst = *puDst; 1444 uint64_t uResult; 1445 uResult = uDst >> cShift; 1446 AssertCompile(X86_EFL_CF_BIT == 0); 1447 if (cShift > 1) 1448 uResult |= uDst << (65 - cShift); 1449 uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (64 - cShift); 1450 *puDst = uResult; 1451 1452 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1453 it the same way as for 1 bit shifts. */ 1454 uint32_t fCarry = (uDst >> (cShift - 1)) & X86_EFL_CF; 1455 fEfl &= ~(X86_EFL_CF | X86_EFL_OF); 1456 fEfl |= fCarry; 1457 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1458 *pfEFlags = fEfl; 1459 } 1460 } 1461 1462 1463 IEM_DECL_IMPL_DEF(void, iemAImpl_shl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1464 { 1465 cShift &= 63; 1466 if (cShift) 1467 { 1468 uint64_t uDst = *puDst; 1469 uint64_t uResult = uDst << cShift; 1470 *puDst = uResult; 1471 1472 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1473 it the same way as for 1 bit shifts. The AF bit is undefined, we 1474 always set it to zero atm. */ 1475 AssertCompile(X86_EFL_CF_BIT == 0); 1476 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1477 uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF; 1478 fEfl |= fCarry; 1479 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1480 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1481 fEfl |= X86_EFL_CALC_ZF(uResult); 1482 fEfl |= g_afParity[uResult & 0xff]; 1483 *pfEFlags = fEfl; 1484 } 1485 } 1486 1487 1488 IEM_DECL_IMPL_DEF(void, iemAImpl_shr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1489 { 1490 cShift &= 63; 1491 if (cShift) 1492 { 1493 uint64_t uDst = *puDst; 1494 uint64_t uResult = uDst >> cShift; 1495 *puDst = uResult; 1496 1497 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1498 it the same way as for 1 bit shifts. The AF bit is undefined, we 1499 always set it to zero atm. */ 1500 AssertCompile(X86_EFL_CF_BIT == 0); 1501 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1502 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1503 fEfl |= (uDst >> 63) << X86_EFL_OF_BIT; 1504 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1505 fEfl |= X86_EFL_CALC_ZF(uResult); 1506 fEfl |= g_afParity[uResult & 0xff]; 1507 *pfEFlags = fEfl; 1508 } 1509 } 1510 1511 1512 IEM_DECL_IMPL_DEF(void, iemAImpl_sar_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1513 { 1514 cShift &= 63; 1515 if (cShift) 1516 { 1517 uint64_t uDst = *puDst; 1518 uint64_t uResult = (int64_t)uDst >> cShift; 1519 *puDst = uResult; 1520 1521 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1522 it the same way as for 1 bit shifts (0). The AF bit is undefined, 1523 we always set it to zero atm. */ 1524 AssertCompile(X86_EFL_CF_BIT == 0); 1525 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1526 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1527 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1528 fEfl |= X86_EFL_CALC_ZF(uResult); 1529 fEfl |= g_afParity[uResult & 0xff]; 1530 *pfEFlags = fEfl; 1531 } 1532 } 1533 1534 1535 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags)) 1536 { 1537 cShift &= 63; 1538 if (cShift) 1539 { 1540 uint64_t uDst = *puDst; 1541 uint64_t uResult; 1542 uResult = uDst << cShift; 1543 uResult |= uSrc >> (64 - cShift); 1544 *puDst = uResult; 1545 1546 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1547 it the same way as for 1 bit shifts. The AF bit is undefined, 1548 we always set it to zero atm. */ 1549 AssertCompile(X86_EFL_CF_BIT == 0); 1550 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1551 fEfl |= (uDst >> (64 - cShift)) & X86_EFL_CF; 1552 fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT; 1553 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1554 fEfl |= X86_EFL_CALC_ZF(uResult); 1555 fEfl |= g_afParity[uResult & 0xff]; 1556 *pfEFlags = fEfl; 1557 } 1558 } 1559 1560 1561 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags)) 1562 { 1563 cShift &= 63; 1564 if (cShift) 1565 { 1566 uint64_t uDst = *puDst; 1567 uint64_t uResult; 1568 uResult = uDst >> cShift; 1569 uResult |= uSrc << (64 - cShift); 1570 *puDst = uResult; 1571 1572 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1573 it the same way as for 1 bit shifts. The AF bit is undefined, 1574 we always set it to zero atm. */ 1575 AssertCompile(X86_EFL_CF_BIT == 0); 1576 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1577 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1578 fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT; 1579 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1580 fEfl |= X86_EFL_CALC_ZF(uResult); 1581 fEfl |= g_afParity[uResult & 0xff]; 1582 *pfEFlags = fEfl; 1583 } 1584 } 1585 1586 1587 /* misc */ 1215 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1216 1217 IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 1218 { 1219 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1220 /** @todo check what real CPUs do. */ 1221 unsigned iBit = ASMBitLastSetU32(uSrc); 1222 if (uSrc) 1223 { 1224 *puDst = iBit - 1; 1225 *pfEFlags &= ~X86_EFL_ZF; 1226 } 1227 else 1228 *pfEFlags |= X86_EFL_ZF; 1229 } 1230 1231 1232 IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 1233 { 1234 /* Note! "undefined" flags: OF, SF, AF, PF, CF. */ 1235 /** @todo check what real CPUs do. */ 1236 unsigned iBit = ASMBitLastSetU16(uSrc); 1237 if (uSrc) 1238 { 1239 *puDst = iBit - 1; 1240 *pfEFlags &= ~X86_EFL_ZF; 1241 } 1242 else 1243 *pfEFlags |= X86_EFL_ZF; 1244 } 1245 1246 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1247 1248 1249 /* 1250 * XCHG 1251 */ 1588 1252 1589 1253 IEM_DECL_IMPL_DEF(void, iemAImpl_xchg_u64,(uint64_t *puMem, uint64_t *puReg)) … … 1705 1369 } 1706 1370 1707 # endif 1708 1709 1710 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */ 1711 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) 1712 1713 /* multiplication and division */ 1714 1371 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1372 1373 1374 /* 1375 * MUL 1376 */ 1715 1377 1716 1378 IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Factor, uint32_t *pfEFlags)) … … 1731 1393 } 1732 1394 1395 1396 /* 1397 * IMUL 1398 */ 1733 1399 1734 1400 IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Factor, uint32_t *pfEFlags)) … … 1789 1455 1790 1456 1457 /* 1458 * DIV 1459 */ 1791 1460 1792 1461 IEM_DECL_IMPL_DEF(int, iemAImpl_div_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Divisor, uint32_t *pfEFlags)) … … 1826 1495 } 1827 1496 1497 1498 /* 1499 * IDIV 1500 */ 1828 1501 1829 1502 IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64Divisor, uint32_t *pfEFlags)) … … 1913 1586 1914 1587 1588 /********************************************************************************************************************************* 1589 * Unary operations. * 1590 *********************************************************************************************************************************/ 1591 1592 IEM_DECL_IMPL_DEF(void, iemAImpl_inc_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1593 { 1594 uint64_t uDst = *puDst; 1595 uint64_t uResult = uDst + 1; 1596 *puDst = uResult; 1597 1598 /* 1599 * Calc EFLAGS. 1600 * CF is NOT modified for hysterical raisins (allegedly for carrying and 1601 * borrowing in arithmetic loops on intel 8008). 1602 */ 1603 uint32_t fEfl = *pfEFlags & ~(X86_EFL_STATUS_BITS & ~X86_EFL_CF); 1604 fEfl |= g_afParity[uResult & 0xff]; 1605 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1606 fEfl |= X86_EFL_CALC_ZF(uResult); 1607 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1608 fEfl |= (((uDst ^ RT_BIT_64(63)) & uResult) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1609 *pfEFlags = fEfl; 1610 } 1611 1612 1613 IEM_DECL_IMPL_DEF(void, iemAImpl_dec_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1614 { 1615 uint64_t uDst = *puDst; 1616 uint64_t uResult = uDst - 1; 1617 *puDst = uResult; 1618 1619 /* 1620 * Calc EFLAGS. 1621 * CF is NOT modified for hysterical raisins (allegedly for carrying and 1622 * borrowing in arithmetic loops on intel 8008). 1623 */ 1624 uint32_t fEfl = *pfEFlags & ~(X86_EFL_STATUS_BITS & ~X86_EFL_CF); 1625 fEfl |= g_afParity[uResult & 0xff]; 1626 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1627 fEfl |= X86_EFL_CALC_ZF(uResult); 1628 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1629 fEfl |= ((uDst & (uResult ^ RT_BIT_64(63))) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1630 *pfEFlags = fEfl; 1631 } 1632 1633 1634 IEM_DECL_IMPL_DEF(void, iemAImpl_not_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1635 { 1636 uint64_t uDst = *puDst; 1637 uint64_t uResult = ~uDst; 1638 *puDst = uResult; 1639 /* EFLAGS are not modified. */ 1640 RT_NOREF_PV(pfEFlags); 1641 } 1642 1643 1644 IEM_DECL_IMPL_DEF(void, iemAImpl_neg_u64,(uint64_t *puDst, uint32_t *pfEFlags)) 1645 { 1646 uint64_t uDst = 0; 1647 uint64_t uSrc = *puDst; 1648 uint64_t uResult = uDst - uSrc; 1649 *puDst = uResult; 1650 1651 /* Calc EFLAGS. */ 1652 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1653 fEfl |= (uSrc != 0) << X86_EFL_CF_BIT; 1654 fEfl |= g_afParity[uResult & 0xff]; 1655 fEfl |= ((uint32_t)uResult ^ (uint32_t)uDst) & X86_EFL_AF; 1656 fEfl |= X86_EFL_CALC_ZF(uResult); 1657 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1658 fEfl |= ((uSrc & uResult) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 1659 *pfEFlags = fEfl; 1660 } 1661 1662 1663 /** 64-bit locked unary operand operation. */ 1664 # define DO_LOCKED_UNARY_OP_U64(a_Mnemonic) \ 1665 do { \ 1666 uint64_t uOld = ASMAtomicReadU64(puDst); \ 1667 uint64_t uTmp; \ 1668 uint32_t fEflTmp; \ 1669 do \ 1670 { \ 1671 uTmp = uOld; \ 1672 fEflTmp = *pfEFlags; \ 1673 iemAImpl_ ## a_Mnemonic ## _u64(&uTmp, &fEflTmp); \ 1674 } while (!ASMAtomicCmpXchgExU64(puDst, uTmp, uOld, &uOld)); \ 1675 *pfEFlags = fEflTmp; \ 1676 } while (0) 1677 1678 IEM_DECL_IMPL_DEF(void, iemAImpl_inc_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1679 { 1680 DO_LOCKED_UNARY_OP_U64(inc); 1681 } 1682 1683 1684 IEM_DECL_IMPL_DEF(void, iemAImpl_dec_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1685 { 1686 DO_LOCKED_UNARY_OP_U64(dec); 1687 } 1688 1689 1690 IEM_DECL_IMPL_DEF(void, iemAImpl_not_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1691 { 1692 DO_LOCKED_UNARY_OP_U64(not); 1693 } 1694 1695 1696 IEM_DECL_IMPL_DEF(void, iemAImpl_neg_u64_locked,(uint64_t *puDst, uint32_t *pfEFlags)) 1697 { 1698 DO_LOCKED_UNARY_OP_U64(neg); 1699 } 1700 1701 1702 /* Shift and rotate. */ 1703 1704 IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1705 { 1706 cShift &= 63; 1707 if (cShift) 1708 { 1709 uint64_t uDst = *puDst; 1710 uint64_t uResult; 1711 uResult = uDst << cShift; 1712 uResult |= uDst >> (64 - cShift); 1713 *puDst = uResult; 1714 1715 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1716 it the same way as for 1 bit shifts. */ 1717 AssertCompile(X86_EFL_CF_BIT == 0); 1718 uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); 1719 uint32_t fCarry = (uResult & 1); 1720 fEfl |= fCarry; 1721 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1722 *pfEFlags = fEfl; 1723 } 1724 } 1725 1726 1727 IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1728 { 1729 cShift &= 63; 1730 if (cShift) 1731 { 1732 uint64_t uDst = *puDst; 1733 uint64_t uResult; 1734 uResult = uDst >> cShift; 1735 uResult |= uDst << (64 - cShift); 1736 *puDst = uResult; 1737 1738 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1739 it the same way as for 1 bit shifts (OF = OF XOR New-CF). */ 1740 AssertCompile(X86_EFL_CF_BIT == 0); 1741 uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); 1742 uint32_t fCarry = (uResult >> 63) & X86_EFL_CF; 1743 fEfl |= fCarry; 1744 fEfl |= (((uResult >> 62) ^ fCarry) << X86_EFL_OF_BIT) & X86_EFL_OF; 1745 *pfEFlags = fEfl; 1746 } 1747 } 1748 1749 1750 IEM_DECL_IMPL_DEF(void, iemAImpl_rcl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1751 { 1752 cShift &= 63; 1753 if (cShift) 1754 { 1755 uint32_t fEfl = *pfEFlags; 1756 uint64_t uDst = *puDst; 1757 uint64_t uResult; 1758 uResult = uDst << cShift; 1759 AssertCompile(X86_EFL_CF_BIT == 0); 1760 if (cShift > 1) 1761 uResult |= uDst >> (65 - cShift); 1762 uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (cShift - 1); 1763 *puDst = uResult; 1764 1765 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1766 it the same way as for 1 bit shifts. */ 1767 uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF; 1768 fEfl &= ~(X86_EFL_CF | X86_EFL_OF); 1769 fEfl |= fCarry; 1770 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1771 *pfEFlags = fEfl; 1772 } 1773 } 1774 1775 1776 IEM_DECL_IMPL_DEF(void, iemAImpl_rcr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1777 { 1778 cShift &= 63; 1779 if (cShift) 1780 { 1781 uint32_t fEfl = *pfEFlags; 1782 uint64_t uDst = *puDst; 1783 uint64_t uResult; 1784 uResult = uDst >> cShift; 1785 AssertCompile(X86_EFL_CF_BIT == 0); 1786 if (cShift > 1) 1787 uResult |= uDst << (65 - cShift); 1788 uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (64 - cShift); 1789 *puDst = uResult; 1790 1791 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1792 it the same way as for 1 bit shifts. */ 1793 uint32_t fCarry = (uDst >> (cShift - 1)) & X86_EFL_CF; 1794 fEfl &= ~(X86_EFL_CF | X86_EFL_OF); 1795 fEfl |= fCarry; 1796 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1797 *pfEFlags = fEfl; 1798 } 1799 } 1800 1801 1802 IEM_DECL_IMPL_DEF(void, iemAImpl_shl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1803 { 1804 cShift &= 63; 1805 if (cShift) 1806 { 1807 uint64_t uDst = *puDst; 1808 uint64_t uResult = uDst << cShift; 1809 *puDst = uResult; 1810 1811 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1812 it the same way as for 1 bit shifts. The AF bit is undefined, we 1813 always set it to zero atm. */ 1814 AssertCompile(X86_EFL_CF_BIT == 0); 1815 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1816 uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF; 1817 fEfl |= fCarry; 1818 fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT; 1819 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1820 fEfl |= X86_EFL_CALC_ZF(uResult); 1821 fEfl |= g_afParity[uResult & 0xff]; 1822 *pfEFlags = fEfl; 1823 } 1824 } 1825 1826 1827 IEM_DECL_IMPL_DEF(void, iemAImpl_shr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1828 { 1829 cShift &= 63; 1830 if (cShift) 1831 { 1832 uint64_t uDst = *puDst; 1833 uint64_t uResult = uDst >> cShift; 1834 *puDst = uResult; 1835 1836 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1837 it the same way as for 1 bit shifts. The AF bit is undefined, we 1838 always set it to zero atm. */ 1839 AssertCompile(X86_EFL_CF_BIT == 0); 1840 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1841 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1842 fEfl |= (uDst >> 63) << X86_EFL_OF_BIT; 1843 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1844 fEfl |= X86_EFL_CALC_ZF(uResult); 1845 fEfl |= g_afParity[uResult & 0xff]; 1846 *pfEFlags = fEfl; 1847 } 1848 } 1849 1850 1851 IEM_DECL_IMPL_DEF(void, iemAImpl_sar_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) 1852 { 1853 cShift &= 63; 1854 if (cShift) 1855 { 1856 uint64_t uDst = *puDst; 1857 uint64_t uResult = (int64_t)uDst >> cShift; 1858 *puDst = uResult; 1859 1860 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1861 it the same way as for 1 bit shifts (0). The AF bit is undefined, 1862 we always set it to zero atm. */ 1863 AssertCompile(X86_EFL_CF_BIT == 0); 1864 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1865 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1866 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1867 fEfl |= X86_EFL_CALC_ZF(uResult); 1868 fEfl |= g_afParity[uResult & 0xff]; 1869 *pfEFlags = fEfl; 1870 } 1871 } 1872 1873 1874 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags)) 1875 { 1876 cShift &= 63; 1877 if (cShift) 1878 { 1879 uint64_t uDst = *puDst; 1880 uint64_t uResult; 1881 uResult = uDst << cShift; 1882 uResult |= uSrc >> (64 - cShift); 1883 *puDst = uResult; 1884 1885 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1886 it the same way as for 1 bit shifts. The AF bit is undefined, 1887 we always set it to zero atm. */ 1888 AssertCompile(X86_EFL_CF_BIT == 0); 1889 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1890 fEfl |= (uDst >> (64 - cShift)) & X86_EFL_CF; 1891 fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT; 1892 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1893 fEfl |= X86_EFL_CALC_ZF(uResult); 1894 fEfl |= g_afParity[uResult & 0xff]; 1895 *pfEFlags = fEfl; 1896 } 1897 } 1898 1899 1900 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags)) 1901 { 1902 cShift &= 63; 1903 if (cShift) 1904 { 1905 uint64_t uDst = *puDst; 1906 uint64_t uResult; 1907 uResult = uDst >> cShift; 1908 uResult |= uSrc << (64 - cShift); 1909 *puDst = uResult; 1910 1911 /* Calc EFLAGS. The OF bit is undefined if cShift > 1, we implement 1912 it the same way as for 1 bit shifts. The AF bit is undefined, 1913 we always set it to zero atm. */ 1914 AssertCompile(X86_EFL_CF_BIT == 0); 1915 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 1916 fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; 1917 fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT; 1918 fEfl |= X86_EFL_CALC_SF(uResult, 64); 1919 fEfl |= X86_EFL_CALC_ZF(uResult); 1920 fEfl |= g_afParity[uResult & 0xff]; 1921 *pfEFlags = fEfl; 1922 } 1923 } 1924 1925 1915 1926 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */ 1916 1927
Note:
See TracChangeset
for help on using the changeset viewer.