VirtualBox

Changeset 47138 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 14, 2013 6:05:53 PM (12 years ago)
Author:
vboxsync
Message:

IEM: idiv and div missing bits and fixes.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r46955 r47138  
    67556755#define IEM_MC_CALL_VOID_AIMPL_3(a_pfn, a0, a1, a2)       (a_pfn)((a0), (a1), (a2))
    67566756#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))
    67576758#define IEM_MC_CALL_AIMPL_4(a_rc, a_pfn, a0, a1, a2, a3)  (a_rc) = (a_pfn)((a0), (a1), (a2), (a3))
    67586759
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r46995 r47138  
    13921392        PROLOGUE_4_ARGS
    13931393
     1394        ; div by chainsaw check.
    13941395        test    A2_16, A2_16
    13951396        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.
    13961400 %if %4 == 0
    13971401        cmp     [A1], A2_16
    13981402        jae     .div_overflow
    13991403 %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:
    14011435 %endif
    14021436
     
    14321466        PROLOGUE_4_ARGS
    14331467
     1468        ; div by chainsaw check.
    14341469        test    A2_32, A2_32
    14351470        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.
    14361474 %if %4 == 0
    14371475        cmp     [A1], A2_32
    14381476        jae     .div_overflow
    14391477 %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
    14411515 %endif
    14421516
     
    14641538        EPILOGUE_4_ARGS
    14651539
     1540.div_overflow:
     1541 %if %4 != 0
     1542        pop     A2
     1543 %endif
    14661544.div_zero:
    1467 .div_overflow:
    14681545        mov     eax, -1
    14691546        jmp     .return
     
    14801557        jae     .div_overflow
    14811558 %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
    14831597 %endif
    14841598
     
    15061620        EPILOGUE_4_ARGS_EX 12
    15071621
     1622.div_overflow:
     1623 %if %4 != 0
     1624        pop     A2
     1625 %endif
    15081626.div_zero:
    1509 .div_overflow:
    15101627        mov     eax, -1
    15111628        jmp     .return
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r46956 r47138  
    1506715067        /* register access */
    1506815068        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     else
    15081     {
    15082         /* memory access. */
    15083         IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
    15084 
    1508515069        IEM_MC_BEGIN(3, 1);
    1508615070        IEM_MC_ARG(uint16_t *,      pu16AX,     0);
    1508715071        IEM_MC_ARG(uint8_t,         u8Value,    1);
    1508815072        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);
    1508915096        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst);
     15097        IEM_MC_LOCAL(int32_t,       rc);
    1509015098
    1509115099        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
     
    1509315101        IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX);
    1509415102        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
    1509815110        IEM_MC_END();
    1509915111    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette