VirtualBox

Ignore:
Timestamp:
Mar 11, 2022 3:01:42 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented Intel and AMD EFLAGS variants for the assembly MUL, IMUL, DIV, and IDIV instructions. bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r94164 r94174  
    336336
    337337;;
     338; Calculates the new EFLAGS based on the CPU EFLAGS (%2), a clear mask (%3),
     339; signed input (%4[%5]) and parity index (%6).
     340;
     341; This is used by MUL and IMUL, where we got result (%4 & %6) in xAX which is
     342; also T0. So, we have to use T1 for the EFLAGS calculation and save T0/xAX
     343; while we extract the %2 flags from the CPU EFLAGS or use T2 (only AMD64).
     344;
     345; @remarks  Clobbers T0, T1, stack, %6, EFLAGS.
     346; @param        1       The register pointing to the EFLAGS.
     347; @param        2       The mask of modified flags to save.
     348; @param        3       Mask of additional flags to always clear
     349; @param        4       The result register to set SF by.
     350; @param        5       The width of the %4 register in bits (8, 16, 32, or 64).
     351; @param        6       The (full) register containing the parity table index. Will be modified!
     352
     353%macro IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF 6
     354 %ifdef RT_ARCH_AMD64
     355        pushf
     356        pop     T2
     357 %else
     358        push    T0
     359        pushf
     360        pop     T0
     361 %endif
     362        mov     T1_32, [%1]             ; load flags.
     363        and     T1_32, ~(%2 | %3 | X86_EFL_PF | X86_EFL_SF)  ; clear the modified, always cleared flags and the two flags we calc.
     364 %ifdef RT_ARCH_AMD64
     365        and     T2_32, (%2)             ; select the modified flags.
     366        or      T1_32, T2_32            ; combine the flags.
     367 %else
     368        and     T0_32, (%2)             ; select the modified flags.
     369        or      T1_32, T0_32            ; combine the flags.
     370        pop     T0
     371 %endif
     372
     373        ; First calculate SF as it's likely to be refereing to the same register as %6 does.
     374        bt      %4, %5 - 1
     375        jnc     %%sf_clear
     376        or      T1_32, X86_EFL_SF
     377 %%sf_clear:
     378
     379        ; Parity last.
     380        and     %6, 0xff
     381 %ifdef RT_ARCH_AMD64
     382        lea     T2, [NAME(g_afParity) xWrtRIP]
     383        or      T1_8, [T2 + %6]
     384 %else
     385        or      T1_8, [NAME(g_afParity) + %6]
     386 %endif
     387
     388        mov     [%1], T1_32             ; save the result.
     389%endmacro
     390
     391;;
    338392; Calculates the new EFLAGS using fixed clear and set bit masks.
    339393;
     
    359413; Calculates the new EFLAGS using fixed clear and set bit masks.
    360414;
    361 ; @remarks  Clobbers T0, %4.
     415; @remarks  Clobbers T0, %4, EFLAGS.
    362416; @param        1       The register pointing to the EFLAGS.
    363417; @param        2       Mask of additional flags to always clear
     
    14961550; @param        2       The modified flags.
    14971551; @param        3       The undefined flags.
     1552; @param        4       Name suffix.
     1553; @param        5       EFLAGS behaviour: 0 for native, 1 for intel and 2 for AMD.
    14981554;
    14991555; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
    15001556;
    1501 %macro IEMIMPL_MUL_OP 3
     1557%macro IEMIMPL_MUL_OP 5
    15021558BEGINCODE
    1503 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_intel, 12
    1504 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_amd, 12
    1505 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
    1506         PROLOGUE_3_ARGS
    1507         IEM_MAYBE_LOAD_FLAGS A2, %2, %3
     1559BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8 %+ %4, 12
     1560        PROLOGUE_3_ARGS
     1561        IEM_MAYBE_LOAD_FLAGS                     A2, %2, %3
    15081562        mov     al, [A0]
    15091563        %1      A1_8
    15101564        mov     [A0], ax
    1511         IEM_SAVE_FLAGS       A2, %2, %3
     1565 %if %5 != 1
     1566        IEM_SAVE_FLAGS                           A2, %2, %3
     1567 %else
     1568        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A2, %2, X86_EFL_AF | X86_EFL_ZF, ax, 8, xAX
     1569 %endif
    15121570        xor     eax, eax
    15131571        EPILOGUE_3_ARGS
    1514 ENDPROC iemAImpl_ %+ %1 %+ _u8
    1515 
    1516 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_intel, 16
    1517 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_amd, 16
    1518 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
    1519         PROLOGUE_4_ARGS
    1520         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     1572ENDPROC iemAImpl_ %+ %1 %+ _u8 %+ %4
     1573
     1574BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ %4, 16
     1575        PROLOGUE_4_ARGS
     1576        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
    15211577        mov     ax, [A0]
    15221578 %ifdef ASM_CALL64_GCC
     
    15301586        mov     [T1], dx
    15311587 %endif
    1532         IEM_SAVE_FLAGS       A3, %2, %3
     1588 %if %5 != 1
     1589        IEM_SAVE_FLAGS                           A3, %2, %3
     1590 %else
     1591        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, ax, 16, xAX
     1592 %endif
    15331593        xor     eax, eax
    15341594        EPILOGUE_4_ARGS
    1535 ENDPROC iemAImpl_ %+ %1 %+ _u16
    1536 
    1537 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_intel, 16
    1538 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_amd, 16
    1539 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    1540         PROLOGUE_4_ARGS
    1541         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     1595ENDPROC iemAImpl_ %+ %1 %+ _u16 %+ %4
     1596
     1597BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ %4, 16
     1598        PROLOGUE_4_ARGS
     1599        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
    15421600        mov     eax, [A0]
    15431601 %ifdef ASM_CALL64_GCC
     
    15511609        mov     [T1], edx
    15521610 %endif
    1553         IEM_SAVE_FLAGS       A3, %2, %3
     1611 %if %5 != 1
     1612        IEM_SAVE_FLAGS                           A3, %2, %3
     1613 %else
     1614        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, eax, 32, xAX
     1615 %endif
    15541616        xor     eax, eax
    15551617        EPILOGUE_4_ARGS
    1556 ENDPROC iemAImpl_ %+ %1 %+ _u32
     1618ENDPROC iemAImpl_ %+ %1 %+ _u32 %+ %4
    15571619
    15581620 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp.
    1559 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_intel, 20
    1560 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_amd, 20
    1561 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
    1562         PROLOGUE_4_ARGS
    1563         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     1621BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ %4, 20
     1622        PROLOGUE_4_ARGS
     1623        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
    15641624        mov     rax, [A0]
    15651625  %ifdef ASM_CALL64_GCC
     
    15731633        mov     [T1], rdx
    15741634  %endif
    1575         IEM_SAVE_FLAGS       A3, %2, %3
     1635  %if %5 != 1
     1636        IEM_SAVE_FLAGS                           A3, %2, %3
     1637  %else
     1638        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, rax, 64, xAX
     1639  %endif
    15761640        xor     eax, eax
    15771641        EPILOGUE_4_ARGS_EX 12
    1578 ENDPROC iemAImpl_ %+ %1 %+ _u64
     1642ENDPROC iemAImpl_ %+ %1 %+ _u64 %+ %4
    15791643 %endif ; !RT_ARCH_AMD64
    15801644
    15811645%endmacro
    15821646
    1583 IEMIMPL_MUL_OP mul,  (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
    1584 IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
     1647IEMIMPL_MUL_OP mul,  (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF),       , 0
     1648IEMIMPL_MUL_OP mul,  (X86_EFL_OF | X86_EFL_CF), 0,                                                   _intel, 1
     1649IEMIMPL_MUL_OP mul,  (X86_EFL_OF | X86_EFL_CF), 0,                                                   _amd,   2
     1650IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF),       , 0
     1651IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), 0,                                                   _intel, 1
     1652IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), 0,                                                   _amd,   2
    15851653
    15861654
     
    16341702; @param        3       The undefined flags.
    16351703; @param        4       1 if signed, 0 if unsigned.
     1704; @param        5       Function suffix.
     1705; @param        6       EFLAGS variation: 0 for native, 1 for intel (ignored),
     1706;                       2 for AMD (set AF, clear PF, ZF and SF).
    16361707;
    16371708; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
    16381709;
    1639 %macro IEMIMPL_DIV_OP 4
     1710%macro IEMIMPL_DIV_OP 6
    16401711BEGINCODE
    1641 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_intel, 12
    1642 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_amd, 12
    1643 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
     1712BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8 %+ %5, 12
    16441713        PROLOGUE_3_ARGS
    16451714
     
    16901759        %1      A1_8
    16911760        mov     [A0], ax
    1692         IEM_SAVE_FLAGS       A2, %2, %3
     1761 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
     1762        IEM_ADJUST_FLAGS    A2, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     1763 %else
     1764        IEM_SAVE_FLAGS      A2, %2, %3
     1765 %endif
    16931766        xor     eax, eax
    16941767
     
    17001773        mov     eax, -1
    17011774        jmp     .return
    1702 ENDPROC iemAImpl_ %+ %1 %+ _u8
    1703 
    1704 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_intel, 16
    1705 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_amd, 16
    1706 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
     1775ENDPROC iemAImpl_ %+ %1 %+ _u8 %+ %5
     1776
     1777BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ %5, 16
    17071778        PROLOGUE_4_ARGS
    17081779
     
    17661837        mov     [T1], dx
    17671838 %endif
    1768         IEM_SAVE_FLAGS       A3, %2, %3
     1839 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
     1840        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     1841 %else
     1842        IEM_SAVE_FLAGS      A3, %2, %3
     1843 %endif
    17691844        xor     eax, eax
    17701845
     
    17761851        mov     eax, -1
    17771852        jmp     .return
    1778 ENDPROC iemAImpl_ %+ %1 %+ _u16
    1779 
    1780 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_intel, 16
    1781 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_amd, 16
    1782 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
     1853ENDPROC iemAImpl_ %+ %1 %+ _u16 %+ %5
     1854
     1855BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ %5, 16
    17831856        PROLOGUE_4_ARGS
    17841857
     
    18471920        mov     [T1], edx
    18481921 %endif
    1849         IEM_SAVE_FLAGS       A3, %2, %3
     1922 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
     1923        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     1924 %else
     1925        IEM_SAVE_FLAGS      A3, %2, %3
     1926 %endif
    18501927        xor     eax, eax
    18511928
     
    18601937        mov     eax, -1
    18611938        jmp     .return
    1862 ENDPROC iemAImpl_ %+ %1 %+ _u32
     1939ENDPROC iemAImpl_ %+ %1 %+ _u32 %+ %5
    18631940
    18641941 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp.
    1865 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_intel, 20
    1866 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_amd, 20
    1867 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
     1942BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ %5, 20
    18681943        PROLOGUE_4_ARGS
    18691944
     
    19292004        mov     [T1], rdx
    19302005  %endif
    1931         IEM_SAVE_FLAGS       A3, %2, %3
     2006  %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
     2007        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     2008  %else
     2009        IEM_SAVE_FLAGS      A3, %2, %3
     2010  %endif
    19322011        xor     eax, eax
    19332012
     
    19422021        mov     eax, -1
    19432022        jmp     .return
    1944 ENDPROC iemAImpl_ %+ %1 %+ _u64
     2023ENDPROC iemAImpl_ %+ %1 %+ _u64 %+ %5
    19452024 %endif ; !RT_ARCH_AMD64
    19462025
    19472026%endmacro
    19482027
    1949 IEMIMPL_DIV_OP div,  0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
    1950 IEMIMPL_DIV_OP idiv, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 1
     2028IEMIMPL_DIV_OP div,  0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,       , 0
     2029IEMIMPL_DIV_OP div,  0, 0,                                                                             0, _intel, 1
     2030IEMIMPL_DIV_OP div,  0, 0,                                                                             0, _amd,   2
     2031IEMIMPL_DIV_OP idiv, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 1,       , 0
     2032IEMIMPL_DIV_OP idiv, 0, 0,                                                                             1, _intel, 1
     2033IEMIMPL_DIV_OP idiv, 0, 0,                                                                             1, _amd,   2
    19512034
    19522035
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