Changeset 47138 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jul 14, 2013 6:05:53 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r46955 r47138 6755 6755 #define IEM_MC_CALL_VOID_AIMPL_3(a_pfn, a0, a1, a2) (a_pfn)((a0), (a1), (a2)) 6756 6756 #define IEM_MC_CALL_VOID_AIMPL_4(a_pfn, a0, a1, a2, a3) (a_pfn)((a0), (a1), (a2), (a3)) 6757 #define IEM_MC_CALL_AIMPL_3(a_rc, a_pfn, a0, a1, a2) (a_rc) = (a_pfn)((a0), (a1), (a2)) 6757 6758 #define IEM_MC_CALL_AIMPL_4(a_rc, a_pfn, a0, a1, a2, a3) (a_rc) = (a_pfn)((a0), (a1), (a2), (a3)) 6758 6759 -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r46995 r47138 1392 1392 PROLOGUE_4_ARGS 1393 1393 1394 ; div by chainsaw check. 1394 1395 test A2_16, A2_16 1395 1396 jz .div_zero 1397 1398 ; Overflow check - unsigned division is simple to verify, haven't 1399 ; found a simple way to check signed division yet unfortunately. 1396 1400 %if %4 == 0 1397 1401 cmp [A1], A2_16 1398 1402 jae .div_overflow 1399 1403 %else 1400 ;; @todo idiv overflow checking. 1404 mov T0_16, [A1] 1405 shl T0_32, 16 1406 mov T0_16, [A0] ; T0 = dividend 1407 mov T1, A2 ; T1 = divisor 1408 test T1_16, T1_16 1409 js .divisor_negative 1410 test T0_32, T0_32 1411 jns .both_positive 1412 neg T0_32 1413 .one_of_each: ; OK range is 2^(result-with - 1) + (divisor - 1). 1414 push T0 ; Start off like unsigned below. 1415 shr T0_32, 15 1416 cmp T0_16, T1_16 1417 pop T0 1418 jb .div_no_overflow 1419 ja .div_overflow 1420 and T0_16, 0x7fff ; Special case for covering (divisor - 1). 1421 cmp T0_16, T1_16 1422 jae .div_overflow 1423 jmp .div_no_overflow 1424 1425 .divisor_negative: 1426 neg T1_16 1427 test T0_32, T0_32 1428 jns .one_of_each 1429 neg T0_32 1430 .both_positive: ; Same as unsigned shifted by sign indicator bit. 1431 shr T0_32, 15 1432 cmp T0_16, T1_16 1433 jae .div_overflow 1434 .div_no_overflow: 1401 1435 %endif 1402 1436 … … 1432 1466 PROLOGUE_4_ARGS 1433 1467 1468 ; div by chainsaw check. 1434 1469 test A2_32, A2_32 1435 1470 jz .div_zero 1471 1472 ; Overflow check - unsigned division is simple to verify, haven't 1473 ; found a simple way to check signed division yet unfortunately. 1436 1474 %if %4 == 0 1437 1475 cmp [A1], A2_32 1438 1476 jae .div_overflow 1439 1477 %else 1440 ;; @todo idiv overflow checking. 1478 push A2 ; save A2 so we modify it (we out of regs on x86). 1479 mov T0_32, [A0] ; T0 = dividend low 1480 mov T1_32, [A1] ; T1 = dividend high 1481 test A2_32, A2_32 1482 js .divisor_negative 1483 test T1_32, T1_32 1484 jns .both_positive 1485 neg T0_32 1486 neg T1_32 1487 .one_of_each: ; OK range is 2^(result-with - 1) + (divisor - 1). 1488 push T0 ; Start off like unsigned below. 1489 shl T1_32, 1 1490 shr T0_32, 31 1491 or T1_32, T0_32 1492 cmp T1_32, A2_32 1493 pop T0 1494 jb .div_no_overflow 1495 ja .div_overflow 1496 and T0_32, 0x7fffffff ; Special case for covering (divisor - 1). 1497 cmp T0_32, A2_32 1498 jae .div_overflow 1499 jmp .div_no_overflow 1500 1501 .divisor_negative: 1502 neg A2_32 1503 test T1_32, T1_32 1504 jns .one_of_each 1505 neg T0_32 1506 neg T1_32 1507 .both_positive: ; Same as unsigned shifted by sign indicator bit. 1508 shl T1_32, 1 1509 shr T0_32, 31 1510 or T1_32, T0_32 1511 cmp T1_32, A2_32 1512 jae .div_overflow 1513 .div_no_overflow: 1514 pop A2 1441 1515 %endif 1442 1516 … … 1464 1538 EPILOGUE_4_ARGS 1465 1539 1540 .div_overflow: 1541 %if %4 != 0 1542 pop A2 1543 %endif 1466 1544 .div_zero: 1467 .div_overflow:1468 1545 mov eax, -1 1469 1546 jmp .return … … 1480 1557 jae .div_overflow 1481 1558 %else 1482 ;; @todo idiv overflow checking. 1559 push A2 ; save A2 so we modify it (we out of regs on x86). 1560 mov T0, [A0] ; T0 = dividend low 1561 mov T1, [A1] ; T1 = dividend high 1562 test A2, A2 1563 js .divisor_negative 1564 test T1, T1 1565 jns .both_positive 1566 neg T0 1567 neg T1 1568 .one_of_each: ; OK range is 2^(result-with - 1) + (divisor - 1). 1569 push T0 ; Start off like unsigned below. 1570 shl T1, 1 1571 shr T0, 63 1572 or T1, T0 1573 cmp T1, A2 1574 pop T0 1575 jb .div_no_overflow 1576 ja .div_overflow 1577 mov T1, 0x7fffffffffffffff 1578 and T0, T1 ; Special case for covering (divisor - 1). 1579 cmp T0, A2 1580 jae .div_overflow 1581 jmp .div_no_overflow 1582 1583 .divisor_negative: 1584 neg A2 1585 test T1, T1 1586 jns .one_of_each 1587 neg T0 1588 neg T1 1589 .both_positive: ; Same as unsigned shifted by sign indicator bit. 1590 shl T1, 1 1591 shr T0, 63 1592 or T1, T0 1593 cmp T1, A2 1594 jae .div_overflow 1595 .div_no_overflow: 1596 pop A2 1483 1597 %endif 1484 1598 … … 1506 1620 EPILOGUE_4_ARGS_EX 12 1507 1621 1622 .div_overflow: 1623 %if %4 != 0 1624 pop A2 1625 %endif 1508 1626 .div_zero: 1509 .div_overflow:1510 1627 mov eax, -1 1511 1628 jmp .return -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r46956 r47138 15067 15067 /* register access */ 15068 15068 IEMOP_HLP_NO_LOCK_PREFIX(); 15069 IEM_MC_BEGIN(3, 0);15070 IEM_MC_ARG(uint16_t *, pu16AX, 0);15071 IEM_MC_ARG(uint8_t, u8Value, 1);15072 IEM_MC_ARG(uint32_t *, pEFlags, 2);15073 IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB);15074 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);15075 IEM_MC_REF_EFLAGS(pEFlags);15076 IEM_MC_CALL_VOID_AIMPL_3(pfnU8, pu16AX, u8Value, pEFlags);15077 IEM_MC_ADVANCE_RIP();15078 IEM_MC_END();15079 }15080 else15081 {15082 /* memory access. */15083 IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */15084 15085 15069 IEM_MC_BEGIN(3, 1); 15086 15070 IEM_MC_ARG(uint16_t *, pu16AX, 0); 15087 15071 IEM_MC_ARG(uint8_t, u8Value, 1); 15088 15072 IEM_MC_ARG(uint32_t *, pEFlags, 2); 15073 IEM_MC_LOCAL(int32_t, rc); 15074 15075 IEM_MC_FETCH_GREG_U8(u8Value, (bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB); 15076 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); 15077 IEM_MC_REF_EFLAGS(pEFlags); 15078 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags); 15079 IEM_MC_IF_LOCAL_IS_Z(rc) { 15080 IEM_MC_ADVANCE_RIP(); 15081 } IEM_MC_ELSE() { 15082 IEM_MC_RAISE_DIVIDE_ERROR(); 15083 } IEM_MC_ENDIF(); 15084 15085 IEM_MC_END(); 15086 } 15087 else 15088 { 15089 /* memory access. */ 15090 IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */ 15091 15092 IEM_MC_BEGIN(3, 2); 15093 IEM_MC_ARG(uint16_t *, pu16AX, 0); 15094 IEM_MC_ARG(uint8_t, u8Value, 1); 15095 IEM_MC_ARG(uint32_t *, pEFlags, 2); 15089 15096 IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); 15097 IEM_MC_LOCAL(int32_t, rc); 15090 15098 15091 15099 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); … … 15093 15101 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); 15094 15102 IEM_MC_REF_EFLAGS(pEFlags); 15095 IEM_MC_CALL_VOID_AIMPL_3(pfnU8, pu16AX, u8Value, pEFlags); 15096 15097 IEM_MC_ADVANCE_RIP(); 15103 IEM_MC_CALL_AIMPL_3(rc, pfnU8, pu16AX, u8Value, pEFlags); 15104 IEM_MC_IF_LOCAL_IS_Z(rc) { 15105 IEM_MC_ADVANCE_RIP(); 15106 } IEM_MC_ELSE() { 15107 IEM_MC_RAISE_DIVIDE_ERROR(); 15108 } IEM_MC_ENDIF(); 15109 15098 15110 IEM_MC_END(); 15099 15111 }
Note:
See TracChangeset
for help on using the changeset viewer.