VirtualBox

Changeset 106179 in vbox for trunk


Ignore:
Timestamp:
Sep 29, 2024 1:14:19 AM (2 months ago)
Author:
vboxsync
Message:

VMM/IEM: Reworked the div, idiv, mul and imul assembly workers and how we raise division error exceptions. The latter is to simplify eflags management. bugref:10720

Location:
trunk/src/VBox/VMM
Files:
11 edited

Legend:

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

    r105486 r106179  
    443443        or      T0_32, %1               ; combine the flags. ASSUMES T0 = eax!
    444444        ;mov     %1, T0_32               ; save the flags.
     445 %else
     446        mov     T0_32, %1
    445447 %endif
    446448%endmacro
     
    513515; Calculates the new EFLAGS using fixed clear and set bit masks.
    514516;
    515 ; @remarks  Clobbers T0.
     517; @remarks  Clobbers/returns T0.
    516518; @param        1       The parameter (A0..A3) holding the eflags value.
    517519; @param        2       Mask of additional flags to always clear
    518520; @param        3       Mask of additional flags to always set.
    519521;
    520 %macro IEM_ADJUST_FLAGS 3
     522%macro IEM_ADJUST_FLAGS_RETVAL 3
     523        mov     T0_32, %1               ; Load flags. ASSUMES T0 is EAX!
    521524 %if (%2 | %3) != 0
    522         mov     T0_32, %1               ; Load flags.
    523525  %if (%2) != 0
    524526        and     T0_32, ~(%2)            ; Remove the always cleared flags.
     
    527529        or      T0_32, %3               ; Add the always set flags.
    528530  %endif
    529         mov     %1, T0_32               ; Save the result.
    530531 %endif
    531532%endmacro
     
    25382539; The 8-bit function only operates on AX, so it takes no DX pointer.  The other
    25392540; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
    2540 ; pointer to eflags in A3.
    2541 ;
    2542 ; The functions all return 0 so the caller can be used for div/idiv as well as
    2543 ; for the mul/imul implementation.
     2541; incoming eflags in A3.
     2542;
     2543; The functions all return eflags. Since valid eflags can't ever be zero, we can
     2544; use the same macros/tests framework as div/idiv.
    25442545;
    25452546; @param        1       The instruction mnemonic.
     
    25552556BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8 %+ %4, 12
    25562557        PROLOGUE_3_ARGS
    2557         IEM_MAYBE_LOAD_FLAGS_OLD                     A2, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2558        IEM_MAYBE_LOAD_FLAGS                         A2_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    25582559        mov     al, [A0]
    25592560        %1      A1_8
    25602561        mov     [A0], ax
    25612562 %if %5 != 1
    2562         IEM_SAVE_FLAGS_OLD                           A2, %2, %3, 0
     2563        IEM_SAVE_FLAGS_RETVAL                        A2_32, %2, %3, 0
    25632564 %else
    2564         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_OLD     A2, %2, X86_EFL_AF | X86_EFL_ZF, ax, 8, xAX ; intel
     2565        movzx   edx, ax
     2566        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_RETVAL  A2_32, %2, X86_EFL_AF | X86_EFL_ZF, dx, 8, xDX ; intel
    25652567 %endif
    2566         xor     eax, eax
    25672568        EPILOGUE_3_ARGS
    25682569ENDPROC iemAImpl_ %+ %1 %+ _u8 %+ %4
     
    25702571BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ %4, 16
    25712572        PROLOGUE_4_ARGS
    2572         IEM_MAYBE_LOAD_FLAGS_OLD                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2573        IEM_MAYBE_LOAD_FLAGS                         A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    25732574        mov     ax, [A0]
    25742575 %ifdef ASM_CALL64_GCC
     
    25832584 %endif
    25842585 %if %5 != 1
    2585         IEM_SAVE_FLAGS_OLD                           A3, %2, %3, 0
     2586        IEM_SAVE_FLAGS_RETVAL                        A3_32, %2, %3, 0
    25862587 %else
    2587         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_OLD     A3, %2, X86_EFL_AF | X86_EFL_ZF, ax, 16, xAX ; intel
     2588        movzx   edx, ax
     2589        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_RETVAL  A3_32, %2, X86_EFL_AF | X86_EFL_ZF, dx, 16, xDX ; intel
    25882590 %endif
    2589         xor     eax, eax
    25902591        EPILOGUE_4_ARGS
    25912592ENDPROC iemAImpl_ %+ %1 %+ _u16 %+ %4
     
    25932594BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ %4, 16
    25942595        PROLOGUE_4_ARGS
    2595         IEM_MAYBE_LOAD_FLAGS_OLD                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2596        IEM_MAYBE_LOAD_FLAGS                         A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    25962597        mov     eax, [A0]
    25972598 %ifdef ASM_CALL64_GCC
     
    26062607 %endif
    26072608 %if %5 != 1
    2608         IEM_SAVE_FLAGS_OLD                           A3, %2, %3, 0
     2609        IEM_SAVE_FLAGS_RETVAL                        A3_32, %2, %3, 0
    26092610 %else
    2610         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_OLD     A3, %2, X86_EFL_AF | X86_EFL_ZF, eax, 32, xAX ; intel
     2611        mov     edx, eax
     2612        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_RETVAL  A3_32, %2, X86_EFL_AF | X86_EFL_ZF, edx, 32, xDX ; intel
    26112613 %endif
    2612         xor     eax, eax
    26132614        EPILOGUE_4_ARGS
    26142615ENDPROC iemAImpl_ %+ %1 %+ _u32 %+ %4
     
    26172618BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ %4, 20
    26182619        PROLOGUE_4_ARGS
    2619         IEM_MAYBE_LOAD_FLAGS_OLD                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2620        IEM_MAYBE_LOAD_FLAGS                         A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    26202621        mov     rax, [A0]
    26212622  %ifdef ASM_CALL64_GCC
     
    26302631  %endif
    26312632  %if %5 != 1
    2632         IEM_SAVE_FLAGS_OLD                           A3, %2, %3, 0
     2633        IEM_SAVE_FLAGS_RETVAL                        A3_32, %2, %3, 0
    26332634  %else
    2634         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_OLD     A3, %2, X86_EFL_AF | X86_EFL_ZF, rax, 64, xAX ; intel
     2635        mov     T2, rax
     2636        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF_RETVAL  A3_32, %2, X86_EFL_AF | X86_EFL_ZF, T2, 64, T2 ; intel
    26352637  %endif
    2636         xor     eax, eax
    26372638        EPILOGUE_4_ARGS_EX 12
    26382639ENDPROC iemAImpl_ %+ %1 %+ _u64 %+ %4
    26392640 %endif ; !RT_ARCH_AMD64
    2640 
    26412641%endmacro
    26422642
     
    26882688;
    26892689; The 8-bit function only operates on AX, so it takes no DX pointer.  The other
    2690 ; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
    2691 ; pointer to eflags in A3.
    2692 ;
    2693 ; The functions all return 0 on success and -1 if a divide error should be
    2694 ; raised by the caller.
     2690; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and
     2691; incoming eflags in A3.
     2692;
     2693; The functions returns the new EFLAGS on success and zero on divide error.
     2694; The new EFLAGS value can never be zero, given that bit 1 always set.
    26952695;
    26962696; @param        1       The instruction mnemonic.
     
    27512751 %endif
    27522752
    2753         IEM_MAYBE_LOAD_FLAGS_OLD A2, %2, %3, %3 ; Undefined flags may be passed thru (Intel)
     2753        IEM_MAYBE_LOAD_FLAGS    A2_32, %2, %3, %3 ; Undefined flags may be passed thru (Intel)
    27542754        mov     ax, [A0]
    27552755        %1      A1_8
    27562756        mov     [A0], ax
    27572757 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
    2758         IEM_ADJUST_FLAGS_OLD    A2, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     2758        IEM_ADJUST_FLAGS_RETVAL A2_32, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    27592759 %else
    2760         IEM_SAVE_FLAGS_OLD      A2, %2, %3, 0
     2760        IEM_SAVE_FLAGS_RETVAL   A2_32, %2, %3, 0
    27612761 %endif
    2762         xor     eax, eax
    2763 
    27642762.return:
    27652763        EPILOGUE_3_ARGS
     
    27672765.div_zero:
    27682766.div_overflow:
    2769         mov     eax, -1
     2767        xor     eax, eax
    27702768        jmp     .return
    27712769ENDPROC iemAImpl_ %+ %1 %+ _u8 %+ %5
     
    28172815 %endif
    28182816
    2819         IEM_MAYBE_LOAD_FLAGS_OLD A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2817        IEM_MAYBE_LOAD_FLAGS     A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    28202818 %ifdef ASM_CALL64_GCC
    28212819        mov     T1, A2
     
    28342832 %endif
    28352833 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
    2836         IEM_ADJUST_FLAGS_OLD    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     2834        IEM_ADJUST_FLAGS_RETVAL A3_32, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    28372835 %else
    2838         IEM_SAVE_FLAGS_OLD      A3, %2, %3, 0
     2836        IEM_SAVE_FLAGS_RETVAL   A3_32, %2, %3, 0
    28392837 %endif
    2840         xor     eax, eax
    28412838
    28422839.return:
     
    28452842.div_zero:
    28462843.div_overflow:
    2847         mov     eax, -1
     2844        xor     eax, eax
    28482845        jmp     .return
    28492846ENDPROC iemAImpl_ %+ %1 %+ _u16 %+ %5
     
    29032900 %endif
    29042901
    2905         IEM_MAYBE_LOAD_FLAGS_OLD A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2902        IEM_MAYBE_LOAD_FLAGS    A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    29062903        mov     eax, [A0]
    29072904 %ifdef ASM_CALL64_GCC
     
    29212918 %endif
    29222919 %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
    2923         IEM_ADJUST_FLAGS_OLD    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     2920        IEM_ADJUST_FLAGS_RETVAL A3_32, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    29242921 %else
    2925         IEM_SAVE_FLAGS_OLD      A3, %2, %3, 0
     2922        IEM_SAVE_FLAGS_RETVAL   A3_32, %2, %3, 0
    29262923 %endif
    2927         xor     eax, eax
    29282924
    29292925.return:
     
    29352931 %endif
    29362932.div_zero:
    2937         mov     eax, -1
     2933        xor     eax, eax
    29382934        jmp     .return
    29392935ENDPROC iemAImpl_ %+ %1 %+ _u32 %+ %5
     
    29912987  %endif
    29922988
    2993         IEM_MAYBE_LOAD_FLAGS_OLD A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
     2989        IEM_MAYBE_LOAD_FLAGS    A3_32, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    29942990        mov     rax, [A0]
    29952991  %ifdef ASM_CALL64_GCC
     
    30093005  %endif
    30103006  %if %6 == 2 ; AMD64 3990X: Set AF and clear PF, ZF and SF.
    3011         IEM_ADJUST_FLAGS_OLD    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
     3007        IEM_ADJUST_FLAGS_RETVAL A3_32, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    30123008  %else
    3013         IEM_SAVE_FLAGS_OLD      A3, %2, %3, 0
     3009        IEM_SAVE_FLAGS_RETVAL   A3_32, %2, %3, 0
    30143010  %endif
    3015         xor     eax, eax
    30163011
    30173012.return:
     
    30233018  %endif
    30243019.div_zero:
    3025         mov     eax, -1
     3020        xor     eax, eax
    30263021        jmp     .return
    30273022ENDPROC iemAImpl_ %+ %1 %+ _u64 %+ %5
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r105462 r106179  
    24752475 */
    24762476# define EMIT_MUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul, a_Suffix, a_fIntelFlags) \
    2477 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_mul_u,a_cBitsWidth,a_Suffix), a_Args) \
     2477IEM_DECL_IMPL_DEF(uint32_t, RT_CONCAT3(iemAImpl_mul_u,a_cBitsWidth,a_Suffix), a_Args) \
    24782478{ \
    24792479    RTUINT ## a_cBitsWidth2x ## U Result; \
     
    24822482    \
    24832483    /* Calc EFLAGS: */ \
    2484     uint32_t fEfl = *pfEFlags; \
    24852484    if (a_fIntelFlags) \
    24862485    { /* Intel: 6700K and 10980XE behavior */ \
    2487         fEfl &= ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \
     2486        fEFlags &= ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \
    24882487        if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
    2489             fEfl |= X86_EFL_SF; \
    2490         fEfl |= IEM_EFL_CALC_PARITY(Result.s.Lo); \
     2488            fEFlags |= X86_EFL_SF; \
     2489        fEFlags |= IEM_EFL_CALC_PARITY(Result.s.Lo); \
    24912490        if (Result.s.Hi != 0) \
    2492             fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2491            fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    24932492    } \
    24942493    else \
    24952494    { /* AMD: 3990X */ \
    24962495        if (Result.s.Hi != 0) \
    2497             fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2496            fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    24982497        else \
    2499             fEfl &= ~(X86_EFL_CF | X86_EFL_OF); \
     2498            fEFlags &= ~(X86_EFL_CF | X86_EFL_OF); \
    25002499    } \
    2501     *pfEFlags = fEfl; \
    2502     return 0; \
     2500    return fEFlags; \
    25032501} \
    25042502
     
    25092507
    25102508# ifndef DOXYGEN_RUNNING /* this totally confuses doxygen for some reason */
    2511 EMIT_MUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor, uint32_t *pfEFlags), (puA, puD, uFactor, pfEFlags),
     2509EMIT_MUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor, uint32_t fEFlags), (puA, puD, uFactor, pfEFlags),
    25122510         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL_U128)
    25132511#  if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2514 EMIT_MUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor, uint32_t *pfEFlags),  (puA, puD, uFactor, pfEFlags),
     2512EMIT_MUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor, uint32_t fEFlags),  (puA, puD, uFactor, pfEFlags),
    25152513         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
    2516 EMIT_MUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor, uint32_t *pfEFlags),  (puA, puD, uFactor, pfEFlags),
     2514EMIT_MUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor, uint32_t fEFlags),  (puA, puD, uFactor, pfEFlags),
    25172515         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
    2518 EMIT_MUL(8, 16, (uint16_t *puAX, uint8_t uFactor, uint32_t *pfEFlags),                  (puAX,     uFactor, pfEFlags),
     2516EMIT_MUL(8, 16, (uint16_t *puAX, uint8_t uFactor, uint32_t fEFlags),                  (puAX,     uFactor, pfEFlags),
    25192517         MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_MUL)
    25202518#  endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     
    25532551# define EMIT_IMUL_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul, \
    25542552                         a_Suffix, a_fIntelFlags) \
    2555 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_imul_u,a_cBitsWidth,a_Suffix),a_Args) \
     2553IEM_DECL_IMPL_DEF(uint32_t, RT_CONCAT3(iemAImpl_imul_u,a_cBitsWidth,a_Suffix),a_Args) \
    25562554{ \
    25572555    RTUINT ## a_cBitsWidth2x ## U Result; \
    2558     uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); \
     2556    fEFlags &= ~(X86_EFL_CF | X86_EFL_OF); \
    25592557    \
    25602558    uint ## a_cBitsWidth ## _t const uFactor1 = a_fnLoadF1(); \
     
    25652563            a_fnMul(Result, uFactor1, uFactor2, a_cBitsWidth2x); \
    25662564            if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \
    2567                 fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2565                fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    25682566        } \
    25692567        else \
     
    25722570            a_fnMul(Result, uFactor1, uPositiveFactor2, a_cBitsWidth2x); \
    25732571            if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \
    2574                 fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2572                fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    25752573            a_fnNeg(Result, a_cBitsWidth2x); \
    25762574        } \
     
    25832581            a_fnMul(Result, uPositiveFactor1, uFactor2, a_cBitsWidth2x); \
    25842582            if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \
    2585                 fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2583                fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    25862584            a_fnNeg(Result, a_cBitsWidth2x); \
    25872585        } \
     
    25922590            a_fnMul(Result, uPositiveFactor1, uPositiveFactor2, a_cBitsWidth2x); \
    25932591            if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \
    2594                 fEfl |= X86_EFL_CF | X86_EFL_OF; \
     2592                fEFlags |= X86_EFL_CF | X86_EFL_OF; \
    25952593        } \
    25962594    } \
     
    25992597    if (a_fIntelFlags) \
    26002598    { \
    2601         fEfl &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \
     2599        fEFlags &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \
    26022600        if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
    2603             fEfl |= X86_EFL_SF;  \
    2604         fEfl |= IEM_EFL_CALC_PARITY(Result.s.Lo & 0xff); \
     2601            fEFlags |= X86_EFL_SF;  \
     2602        fEFlags |= IEM_EFL_CALC_PARITY(Result.s.Lo & 0xff); \
    26052603    } \
    2606     *pfEFlags = fEfl; \
    2607     return 0; \
     2604    return fEFlags; \
    26082605}
    26092606# define EMIT_IMUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul) \
     
    26132610
    26142611# ifndef DOXYGEN_RUNNING /* this totally confuses doxygen for some reason */
    2615 EMIT_IMUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor2, uint32_t *pfEFlags), (puA, puD, uFactor2, pfEFlags),
     2612EMIT_IMUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor2, uint32_t fEFlags), (puA, puD, uFactor2, pfEFlags),
    26162613          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG_U128, MULDIV_MUL_U128)
    26172614#  if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2618 EMIT_IMUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor2, uint32_t *pfEFlags),  (puA, puD, uFactor2, pfEFlags),
     2615EMIT_IMUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor2, uint32_t fEFlags),  (puA, puD, uFactor2, pfEFlags),
    26192616          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
    2620 EMIT_IMUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor2, uint32_t *pfEFlags),  (puA, puD, uFactor2, pfEFlags),
     2617EMIT_IMUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor2, uint32_t fEFlags),  (puA, puD, uFactor2, pfEFlags),
    26212618          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
    2622 EMIT_IMUL(8, 16, (uint16_t *puAX, uint8_t uFactor2, uint32_t *pfEFlags),                  (puAX,     uFactor2, pfEFlags),
     2619EMIT_IMUL(8, 16, (uint16_t *puAX, uint8_t uFactor2, uint32_t fEFlags),                  (puAX,     uFactor2, pfEFlags),
    26232620          MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_NEG, MULDIV_MUL)
    26242621#  endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     
    26342631{ \
    26352632    a_uType uIgn; \
    2636     iemAImpl_imul_u ## a_cBits(puDst, &uIgn, uSrc, &fEFlags); \
    2637     return fEFlags; \
     2633    return iemAImpl_imul_u ## a_cBits(puDst, &uIgn, uSrc, fEFlags); \
    26382634} \
    26392635\
     
    26412637{ \
    26422638    a_uType uIgn; \
    2643     iemAImpl_imul_u ## a_cBits ## _intel(puDst, &uIgn, uSrc, &fEFlags); \
    2644     return fEFlags; \
     2639    return iemAImpl_imul_u ## a_cBits ## _intel(puDst, &uIgn, uSrc, fEFlags); \
    26452640} \
    26462641\
     
    26482643{ \
    26492644    a_uType uIgn; \
    2650     iemAImpl_imul_u ## a_cBits ## _amd(puDst, &uIgn, uSrc, &fEFlags); \
    2651     return fEFlags; \
     2645    return iemAImpl_imul_u ## a_cBits ## _amd(puDst, &uIgn, uSrc, fEFlags); \
    26522646}
    26532647
     
    26642658# define EMIT_DIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem, \
    26652659                        a_Suffix, a_fIntelFlags) \
    2666 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_div_u,a_cBitsWidth,a_Suffix),a_Args) \
     2660IEM_DECL_IMPL_DEF(uint32_t, RT_CONCAT3(iemAImpl_div_u,a_cBitsWidth,a_Suffix),a_Args) \
    26672661{ \
    26682662    RTUINT ## a_cBitsWidth2x ## U Dividend; \
     
    26772671        /* Calc EFLAGS: Intel 6700K and 10980XE leaves them alone.  AMD 3990X sets AF and clears PF, ZF and SF. */ \
    26782672        if (!a_fIntelFlags) \
    2679             *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
    2680         return 0; \
     2673            fEFlags = (fEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
     2674        return fEFlags; \
    26812675    } \
    26822676    /* #DE */ \
    2683     return -1; \
     2677    return 0; \
    26842678}
    26852679# define EMIT_DIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem) \
     
    26892683
    26902684# ifndef DOXYGEN_RUNNING /* this totally confuses doxygen for some reason */
    2691 EMIT_DIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     2685EMIT_DIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t fEFlags), (puA, puD, uDivisor, pfEFlags),
    26922686         DIV_LOAD, DIV_STORE, MULDIV_MODDIV_U128)
    26932687#  if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2694 EMIT_DIV(32,64, (uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     2688EMIT_DIV(32,64, (uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t fEFlags), (puA, puD, uDivisor, pfEFlags),
    26952689         DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
    2696 EMIT_DIV(16,32, (uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     2690EMIT_DIV(16,32, (uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t fEFlags), (puA, puD, uDivisor, pfEFlags),
    26972691         DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
    2698 EMIT_DIV(8,16,  (uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags),                (puAX,     uDivisor, pfEFlags),
     2692EMIT_DIV(8,16,  (uint16_t *puAX, uint8_t uDivisor, uint32_t fEFlags),                (puAX,     uDivisor, pfEFlags),
    26992693         DIV_LOAD_U8, DIV_STORE_U8, MULDIV_MODDIV)
    27002694#  endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     
    27112705# define EMIT_IDIV_INNER(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem, \
    27122706                         a_Suffix, a_fIntelFlags) \
    2713 IEM_DECL_IMPL_DEF(int, RT_CONCAT3(iemAImpl_idiv_u,a_cBitsWidth,a_Suffix),a_Args) \
     2707IEM_DECL_IMPL_DEF(uint32_t, RT_CONCAT3(iemAImpl_idiv_u,a_cBitsWidth,a_Suffix),a_Args) \
    27142708{ \
    27152709    /* Note! Skylake leaves all flags alone. */ \
     
    27482742                    a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \
    27492743                    if (!a_fIntelFlags) \
    2750                         *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
    2751                     return 0; \
     2744                        fEFlags = (fEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
     2745                    return fEFlags; \
    27522746                } \
    27532747            } \
     
    27592753                    a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \
    27602754                    if (!a_fIntelFlags) \
    2761                         *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
    2762                     return 0; \
     2755                        fEFlags = (fEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
     2756                    return fEFlags; \
    27632757                } \
    27642758            } \
     
    27732767                    a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, Remainder.s.Lo); \
    27742768                    if (!a_fIntelFlags) \
    2775                         *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
    2776                     return 0; \
     2769                        fEFlags = (fEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
     2770                    return fEFlags; \
    27772771                } \
    27782772            } \
     
    27842778                    a_fnStore(Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \
    27852779                    if (!a_fIntelFlags) \
    2786                         *pfEFlags = (*pfEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
    2787                     return 0; \
     2780                        fEFlags = (fEFlags & ~(X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF)) | X86_EFL_AF; \
     2781                    return fEFlags; \
    27882782                } \
    27892783            } \
     
    27912785    } \
    27922786    /* #DE */ \
    2793     return -1; \
     2787    return 0; \
    27942788}
    27952789# define EMIT_IDIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem) \
     
    27992793
    28002794# ifndef DOXYGEN_RUNNING /* this totally confuses doxygen for some reason */
    2801 EMIT_IDIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     2795EMIT_IDIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t fEFlags), (puA, puD, uDivisor, pfEFlags),
    28022796          DIV_LOAD, DIV_STORE, MULDIV_NEG_U128, MULDIV_MODDIV_U128)
    28032797#  if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2804 EMIT_IDIV(32,64,(uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags),  (puA, puD, uDivisor, pfEFlags),
     2798EMIT_IDIV(32,64,(uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t fEFlags),  (puA, puD, uDivisor, pfEFlags),
    28052799          DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
    2806 EMIT_IDIV(16,32,(uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags),  (puA, puD, uDivisor, pfEFlags),
     2800EMIT_IDIV(16,32,(uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t fEFlags),  (puA, puD, uDivisor, pfEFlags),
    28072801          DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
    2808 EMIT_IDIV(8,16,(uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags),                  (puAX,     uDivisor, pfEFlags),
     2802EMIT_IDIV(8,16,(uint16_t *puAX, uint8_t uDivisor, uint32_t fEFlags),                  (puAX,     uDivisor, pfEFlags),
    28092803          DIV_LOAD_U8, DIV_STORE_U8, MULDIV_NEG, MULDIV_MODDIV)
    28102804#  endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h

    r106061 r106179  
    1456414564        IEM_MC_BEGIN(0, 0); \
    1456514565        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14566        IEM_MC_ARG(uint8_t,         u8Value,    1); \
     14567        IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    1456614568        IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
    14567         IEM_MC_ARG(uint8_t,         u8Value,    1); \
    14568         IEM_MC_ARG(uint32_t *,      pEFlags,    2); \
     14569        IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
     14570        IEM_MC_ARG_EFLAGS(          fEFlagsIn,  2); \
     14571        IEM_MC_CALL_AIMPL_3(uint32_t, fEFlagsRet, pfnU8, pu16AX, u8Value, fEFlagsIn); \
    1456914572        \
    14570         IEM_MC_FETCH_GREG_U8(u8Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    14571         IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
    14572         IEM_MC_REF_EFLAGS(pEFlags); \
    14573         IEM_MC_CALL_AIMPL_3(int32_t, rc, pfnU8, pu16AX, u8Value, pEFlags); \
    14574         IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14575             IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14576         } IEM_MC_ELSE() { \
    14577             IEM_MC_RAISE_DIVIDE_ERROR(); \
    14578         } IEM_MC_ENDIF(); \
    14579         \
     14573        IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14574        IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14575        IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1458014576        IEM_MC_END(); \
    1458114577    } \
     
    1458414580        /* memory access. */ \
    1458514581        IEM_MC_BEGIN(0, 0); \
    14586         IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
    14587         IEM_MC_ARG(uint8_t,         u8Value,    1); \
    14588         IEM_MC_ARG(uint32_t *,      pEFlags,    2); \
    1458914582        IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    14590         \
    1459114583        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
    1459214584        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14585        \
     14586        IEM_MC_ARG(uint8_t,         u8Value,    1); \
    1459314587        IEM_MC_FETCH_MEM_U8(u8Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
     14588        IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
    1459414589        IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
    14595         IEM_MC_REF_EFLAGS(pEFlags); \
    14596         IEM_MC_CALL_AIMPL_3(int32_t, rc, pfnU8, pu16AX, u8Value, pEFlags); \
    14597         IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14598             IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14599         } IEM_MC_ELSE() { \
    14600             IEM_MC_RAISE_DIVIDE_ERROR(); \
    14601         } IEM_MC_ENDIF(); \
     14590        IEM_MC_ARG_EFLAGS(          fEFlagsIn,  2); \
     14591        IEM_MC_CALL_AIMPL_3(uint32_t, fEFlagsRet, pfnU8, pu16AX, u8Value, fEFlagsIn); \
    1460214592        \
     14593        IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14594        IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14595        IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1460314596        IEM_MC_END(); \
    1460414597    } (void)0
     
    1461614609                IEM_MC_BEGIN(0, 0); \
    1461714610                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14611                IEM_MC_ARG(uint16_t,        u16Value,   2); \
     14612                IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    1461814613                IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
     14614                IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
    1461914615                IEM_MC_ARG(uint16_t *,      pu16DX,     1); \
    14620                 IEM_MC_ARG(uint16_t,        u16Value,   2); \
    14621                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
     14616                IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX); \
     14617                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14618                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU16, pu16AX, pu16DX, u16Value, fEFlagsIn); \
    1462214619                \
    14623                 IEM_MC_FETCH_GREG_U16(u16Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    14624                 IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
    14625                 IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX); \
    14626                 IEM_MC_REF_EFLAGS(pEFlags); \
    14627                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags); \
    14628                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14629                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14630                 } IEM_MC_ELSE() { \
    14631                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14632                 } IEM_MC_ENDIF(); \
    14633                 \
     14620                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14621                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14622                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1463414623                IEM_MC_END(); \
    1463514624                break; \
     
    1463814627                IEM_MC_BEGIN(IEM_MC_F_MIN_386, 0); \
    1463914628                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14629                IEM_MC_ARG(uint32_t,        u32Value,   2); \
     14630                IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    1464014631                IEM_MC_ARG(uint32_t *,      pu32AX,     0); \
     14632                IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX); \
    1464114633                IEM_MC_ARG(uint32_t *,      pu32DX,     1); \
    14642                 IEM_MC_ARG(uint32_t,        u32Value,   2); \
    14643                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
     14634                IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX); \
     14635                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14636                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU32, pu32AX, pu32DX, u32Value, fEFlagsIn); \
    1464414637                \
    14645                 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    14646                 IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX); \
    14647                 IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX); \
    14648                 IEM_MC_REF_EFLAGS(pEFlags); \
    14649                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags); \
    14650                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14651                     IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX); \
    14652                     IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX); \
    14653                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14654                 } IEM_MC_ELSE() { \
    14655                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14656                 } IEM_MC_ENDIF(); \
    14657                 \
     14638                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14639                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14640                IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX); \
     14641                IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX); \
     14642                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1465814643                IEM_MC_END(); \
    1465914644                break; \
     
    1466214647                IEM_MC_BEGIN(IEM_MC_F_64BIT, 0); \
    1466314648                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14649                IEM_MC_ARG(uint64_t,        u64Value,   2); \
     14650                IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    1466414651                IEM_MC_ARG(uint64_t *,      pu64AX,     0); \
     14652                IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX); \
    1466514653                IEM_MC_ARG(uint64_t *,      pu64DX,     1); \
    14666                 IEM_MC_ARG(uint64_t,        u64Value,   2); \
    14667                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
     14654                IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX); \
     14655                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14656                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU64, pu64AX, pu64DX, u64Value, fEFlagsIn); \
    1466814657                \
    14669                 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_RM(pVCpu, bRm)); \
    14670                 IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX); \
    14671                 IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX); \
    14672                 IEM_MC_REF_EFLAGS(pEFlags); \
    14673                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags); \
    14674                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14675                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14676                 } IEM_MC_ELSE() { \
    14677                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14678                 } IEM_MC_ENDIF(); \
    14679                 \
     14658                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14659                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14660                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1468014661                IEM_MC_END(); \
    1468114662                break; \
     
    1469114672            case IEMMODE_16BIT: \
    1469214673                IEM_MC_BEGIN(0, 0); \
    14693                 IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
    14694                 IEM_MC_ARG(uint16_t *,      pu16DX,     1); \
    14695                 IEM_MC_ARG(uint16_t,        u16Value,   2); \
    14696                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
    1469714674                IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    14698                 \
    1469914675                IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
    1470014676                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14677                \
     14678                IEM_MC_ARG(uint16_t,        u16Value,   2); \
    1470114679                IEM_MC_FETCH_MEM_U16(u16Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
     14680                IEM_MC_ARG(uint16_t *,      pu16AX,     0); \
    1470214681                IEM_MC_REF_GREG_U16(pu16AX, X86_GREG_xAX); \
     14682                IEM_MC_ARG(uint16_t *,      pu16DX,     1); \
    1470314683                IEM_MC_REF_GREG_U16(pu16DX, X86_GREG_xDX); \
    14704                 IEM_MC_REF_EFLAGS(pEFlags); \
    14705                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU16, pu16AX, pu16DX, u16Value, pEFlags); \
    14706                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14707                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14708                 } IEM_MC_ELSE() { \
    14709                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14710                 } IEM_MC_ENDIF(); \
     14684                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14685                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU16, pu16AX, pu16DX, u16Value, fEFlagsIn); \
    1471114686                \
     14687                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14688                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14689                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1471214690                IEM_MC_END(); \
    1471314691                break; \
     
    1471514693            case IEMMODE_32BIT: \
    1471614694                IEM_MC_BEGIN(IEM_MC_F_MIN_386, 0); \
    14717                 IEM_MC_ARG(uint32_t *,      pu32AX,     0); \
    14718                 IEM_MC_ARG(uint32_t *,      pu32DX,     1); \
    14719                 IEM_MC_ARG(uint32_t,        u32Value,   2); \
    14720                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
    1472114695                IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    14722                 \
    1472314696                IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
    1472414697                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14698                \
     14699                IEM_MC_ARG(uint32_t,        u32Value,   2); \
    1472514700                IEM_MC_FETCH_MEM_U32(u32Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
     14701                IEM_MC_ARG(uint32_t *,      pu32AX,     0); \
    1472614702                IEM_MC_REF_GREG_U32(pu32AX, X86_GREG_xAX); \
     14703                IEM_MC_ARG(uint32_t *,      pu32DX,     1); \
    1472714704                IEM_MC_REF_GREG_U32(pu32DX, X86_GREG_xDX); \
    14728                 IEM_MC_REF_EFLAGS(pEFlags); \
    14729                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU32, pu32AX, pu32DX, u32Value, pEFlags); \
    14730                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14731                     IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX); \
    14732                     IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX); \
    14733                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14734                 } IEM_MC_ELSE() { \
    14735                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14736                 } IEM_MC_ENDIF(); \
     14705                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14706                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU32, pu32AX, pu32DX, u32Value, fEFlagsIn); \
    1473714707                \
     14708                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14709                IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xAX); \
     14710                IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xDX); \
     14711                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14712                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1473814713                IEM_MC_END(); \
    1473914714                break; \
     
    1474114716            case IEMMODE_64BIT: \
    1474214717                IEM_MC_BEGIN(IEM_MC_F_64BIT, 0); \
    14743                 IEM_MC_ARG(uint64_t *,      pu64AX,     0); \
    14744                 IEM_MC_ARG(uint64_t *,      pu64DX,     1); \
    14745                 IEM_MC_ARG(uint64_t,        u64Value,   2); \
    14746                 IEM_MC_ARG(uint32_t *,      pEFlags,    3); \
    1474714718                IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
    14748                 \
    1474914719                IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
    1475014720                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
     14721                \
     14722                IEM_MC_ARG(uint64_t,        u64Value,   2); \
    1475114723                IEM_MC_FETCH_MEM_U64(u64Value, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
     14724                IEM_MC_ARG(uint64_t *,      pu64AX,     0); \
    1475214725                IEM_MC_REF_GREG_U64(pu64AX, X86_GREG_xAX); \
     14726                IEM_MC_ARG(uint64_t *,      pu64DX,     1); \
    1475314727                IEM_MC_REF_GREG_U64(pu64DX, X86_GREG_xDX); \
    14754                 IEM_MC_REF_EFLAGS(pEFlags); \
    14755                 IEM_MC_CALL_AIMPL_4(int32_t, rc, pImpl->pfnU64, pu64AX, pu64DX, u64Value, pEFlags); \
    14756                 IEM_MC_IF_LOCAL_IS_Z(rc) { \
    14757                     IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    14758                 } IEM_MC_ELSE() { \
    14759                     IEM_MC_RAISE_DIVIDE_ERROR(); \
    14760                 } IEM_MC_ENDIF(); \
     14728                IEM_MC_ARG_EFLAGS(          fEFlagsIn,  3); \
     14729                IEM_MC_CALL_AIMPL_4(uint32_t, fEFlagsRet, pImpl->pfnU64, pu64AX, pu64DX, u64Value, fEFlagsIn); \
    1476114730                \
     14731                IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(fEFlagsRet); \
     14732                IEM_MC_COMMIT_EFLAGS(fEFlagsRet); \
     14733                IEM_MC_ADVANCE_RIP_AND_FINISH(); \
    1476214734                IEM_MC_END(); \
    1476314735                break; \
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r106097 r106179  
    33043304    'IEM_MC_PUSH_U32_SREG':                                      (McBlock.parseMcGeneric,           True,  True,  True,  ),
    33053305    'IEM_MC_PUSH_U64':                                           (McBlock.parseMcGeneric,           True,  True,  True,  ),
    3306     'IEM_MC_RAISE_DIVIDE_ERROR':                                 (McBlock.parseMcGeneric,           True,  True,  True,  ),
     3306    'IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO':                (McBlock.parseMcGeneric,           True,  True,  True,  ),
    33073307    'IEM_MC_RAISE_GP0_IF_CPL_NOT_ZERO':                          (McBlock.parseMcGeneric,           True,  True,  False, ),
    33083308    'IEM_MC_RAISE_GP0_IF_EFF_ADDR_UNALIGNED':                    (McBlock.parseMcGeneric,           True,  True,  True,  ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veLiveness.h

    r106114 r106179  
    508508#define IEM_MC_NO_NATIVE_RECOMPILE()                                NOP()
    509509
    510 #define IEM_MC_RAISE_DIVIDE_ERROR()                                 IEM_LIVENESS_MARK_POTENTIAL_CALL()
     510#define IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(a_uVar)          IEM_LIVENESS_MARK_POTENTIAL_CALL()
    511511#define IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE()                   IEM_LIVENESS_MARK_POTENTIAL_CALL(); IEM_LIVENESS_CR0_INPUT()
    512512#define IEM_MC_MAYBE_RAISE_WAIT_DEVICE_NOT_AVAILABLE()              IEM_LIVENESS_MARK_POTENTIAL_CALL(); IEM_LIVENESS_CR0_INPUT()
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h

    r106123 r106179  
    29222922
    29232923
    2924 #define IEM_MC_RAISE_DIVIDE_ERROR() \
    2925     off = iemNativeEmitRaiseDivideError(pReNative, off, pCallEntry->idxInstr)
     2924#define IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(a_uVar) \
     2925    off = iemNativeEmitRaiseDivideErrorIfLocalIsZero(pReNative, off, a_uVar, pCallEntry->idxInstr)
    29262926
    29272927/**
    2928  * Emits code to raise a \#DE.
     2928 * Emits code to raise a \#DE if a local variable is zero.
    29292929 *
    29302930 * @returns New code buffer offset, UINT32_MAX on failure.
    29312931 * @param   pReNative       The native recompile state.
    29322932 * @param   off             The code buffer offset.
     2933 * @param   idxVar          The variable to check. This must be 32-bit (EFLAGS).
    29332934 * @param   idxInstr        The current instruction.
    29342935 */
    29352936DECL_INLINE_THROW(uint32_t)
    2936 iemNativeEmitRaiseDivideError(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr)
    2937 {
    2938     /*
    2939      * Make sure we don't have any outstanding guest register writes as we may
    2940      */
     2937iemNativeEmitRaiseDivideErrorIfLocalIsZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVar, uint8_t idxInstr)
     2938{
     2939    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar);
     2940    IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxVar, sizeof(uint32_t));
     2941
     2942    /* Make sure we don't have any outstanding guest register writes as we may. */
    29412943    off = iemNativeRegFlushPendingWrites(pReNative, off);
    29422944
     2945    /* Set the instruction number if we're counting. */
    29432946#ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    29442947    off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr));
     
    29472950#endif
    29482951
    2949     /* raise \#DE exception unconditionally. */
    2950     return iemNativeEmitTbExit(pReNative, off, kIemNativeLabelType_RaiseDe);
     2952    /* Do the job we're here for. */
     2953    uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVar, &off);
     2954    off = iemNativeEmitTestIfGprIsZeroAndTbExit(pReNative, off, idxVarReg, false /*f64Bit*/, kIemNativeLabelType_RaiseDe);
     2955    iemNativeVarRegisterRelease(pReNative, idxVar);
     2956
     2957    return off;
    29512958}
    29522959
     
    29842991
    29852992    uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVarEffAddr, &off);
    2986 
    29872993    off = iemNativeEmitTestAnyBitsInGprAndTbExitIfAnySet(pReNative, off, idxVarReg, cbAlign - 1,
    29882994                                                         kIemNativeLabelType_RaiseGp0);
    2989 
    29902995    iemNativeVarRegisterRelease(pReNative, idxVarEffAddr);
     2996
    29912997    return off;
    29922998}
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r106090 r106179  
    27232723                        or oStmt.sName.startswith('IEM_MC_CALL_CIMPL_')
    27242724                        or oStmt.sName.startswith('IEM_MC_DEFER_TO_CIMPL_')
    2725                         or oStmt.sName in ('IEM_MC_RAISE_DIVIDE_ERROR',)):
     2725                        or oStmt.sName in ('IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO',)):
    27262726                        aoDecoderStmts.pop();
    27272727                        if not fIsConditional:
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r106125 r106179  
    23662366    /** Native recompiler: Number of times status flags calc has been skipped. */
    23672367    STAMCOUNTER             StatNativeEflSkippedArithmetic;
     2368    /** Native recompiler: Number of times status flags calc has been postponed. */
     2369    STAMCOUNTER             StatNativeEflPostponedArithmetic;
    23682370    /** Native recompiler: Total number instructions in this category. */
    23692371    STAMCOUNTER             StatNativeEflTotalArithmetic;
     
    23712373    /** Native recompiler: Number of times status flags calc has been skipped. */
    23722374    STAMCOUNTER             StatNativeEflSkippedLogical;
     2375    /** Native recompiler: Number of times status flags calc has been postponed. */
     2376    STAMCOUNTER             StatNativeEflPostponedLogical;
    23732377    /** Native recompiler: Total number instructions in this category. */
    23742378    STAMCOUNTER             StatNativeEflTotalLogical;
     
    23762380    /** Native recompiler: Number of times status flags calc has been skipped. */
    23772381    STAMCOUNTER             StatNativeEflSkippedShift;
     2382    /** Native recompiler: Number of times status flags calc has been postponed. */
     2383    STAMCOUNTER             StatNativeEflPostponedShift;
    23782384    /** Native recompiler: Total number instructions in this category. */
    23792385    STAMCOUNTER             StatNativeEflTotalShift;
     
    25502556
    25512557#ifdef IEM_WITH_TLB_TRACE
    2552     //uint64_t                au64Padding[0];
     2558    uint64_t                au64Padding[5];
    25532559#else
    2554     uint64_t                au64Padding[2];
     2560    uint64_t                au64Padding[7];
    25552561#endif
    25562562
     
    35383544/** @name Multiplication and division operations.
    35393545 * @{ */
    3540 typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t *pEFlags));
     3546typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLMULDIVU8,(uint16_t *pu16AX, uint8_t u8FactorDivisor, uint32_t fEFlags));
    35413547typedef FNIEMAIMPLMULDIVU8  *PFNIEMAIMPLMULDIVU8;
    35423548FNIEMAIMPLMULDIVU8 iemAImpl_mul_u8,  iemAImpl_mul_u8_amd,  iemAImpl_mul_u8_intel;
     
    35453551FNIEMAIMPLMULDIVU8 iemAImpl_idiv_u8, iemAImpl_idiv_u8_amd, iemAImpl_idiv_u8_intel;
    35463552
    3547 typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t *pEFlags));
     3553typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLMULDIVU16,(uint16_t *pu16AX, uint16_t *pu16DX, uint16_t u16FactorDivisor, uint32_t fEFlags));
    35483554typedef FNIEMAIMPLMULDIVU16  *PFNIEMAIMPLMULDIVU16;
    35493555FNIEMAIMPLMULDIVU16 iemAImpl_mul_u16,  iemAImpl_mul_u16_amd,  iemAImpl_mul_u16_intel;
     
    35523558FNIEMAIMPLMULDIVU16 iemAImpl_idiv_u16, iemAImpl_idiv_u16_amd, iemAImpl_idiv_u16_intel;
    35533559
    3554 typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t *pEFlags));
     3560typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLMULDIVU32,(uint32_t *pu32EAX, uint32_t *pu32EDX, uint32_t u32FactorDivisor, uint32_t fEFlags));
    35553561typedef FNIEMAIMPLMULDIVU32  *PFNIEMAIMPLMULDIVU32;
    35563562FNIEMAIMPLMULDIVU32 iemAImpl_mul_u32,  iemAImpl_mul_u32_amd,  iemAImpl_mul_u32_intel;
     
    35593565FNIEMAIMPLMULDIVU32 iemAImpl_idiv_u32, iemAImpl_idiv_u32_amd, iemAImpl_idiv_u32_intel;
    35603566
    3561 typedef IEM_DECL_IMPL_TYPE(int, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t *pEFlags));
     3567typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLMULDIVU64,(uint64_t *pu64RAX, uint64_t *pu64RDX, uint64_t u64FactorDivisor, uint32_t fEFlags));
    35623568typedef FNIEMAIMPLMULDIVU64  *PFNIEMAIMPLMULDIVU64;
    35633569FNIEMAIMPLMULDIVU64 iemAImpl_mul_u64,  iemAImpl_mul_u64_amd,  iemAImpl_mul_u64_intel;
  • trunk/src/VBox/VMM/include/IEMMc.h

    r106097 r106179  
    109109
    110110
    111 #define IEM_MC_RAISE_DIVIDE_ERROR()                     return iemRaiseDivideError(pVCpu)
     111#define IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(a_uVar) \
     112    do { \
     113        if (RT_LIKELY((a_uVar) != 0)) \
     114        { /* probable */ } \
     115        else return iemRaiseDivideError(pVCpu); \
     116    } while (0)
    112117#define IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE()       \
    113118    do { \
  • trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp

    r105275 r106179  
    29912991            MULDIVU8_TEST_T Test;
    29922992            Test.fEflIn    = RandEFlags();
    2993             Test.fEflOut   = Test.fEflIn;
    29942993            Test.uDstIn    = RandU16Dst(iTest);
    29952994            Test.uDstOut   = Test.uDstIn;
    29962995            Test.uSrcIn    = RandU8Src(iTest);
    2997             Test.rc        = g_aMulDivU8[iFn].pfnNative(&Test.uDstOut, Test.uSrcIn, &Test.fEflOut);
     2996            uint32_t const fEflRet = g_aMulDivU8[iFn].pfnNative(&Test.uDstOut, Test.uSrcIn, Test.fEflIn);
     2997            Test.fEflOut   = fEflRet ? fEflRet : Test.fEflIn;
     2998            Test.rc        = fEflRet ? 0       : -1;
    29982999            GenerateBinaryWrite(&BinOut, &Test, sizeof(Test));
    29993000        }
     
    30033004            Test.fEflIn    = g_aMulDivU8[iFn].paFixedTests[iTest].fEflIn == UINT32_MAX ? RandEFlags()
    30043005                           : g_aMulDivU8[iFn].paFixedTests[iTest].fEflIn;
    3005             Test.fEflOut   = Test.fEflIn;
    30063006            Test.uDstIn    = g_aMulDivU8[iFn].paFixedTests[iTest].uDstIn;
    30073007            Test.uDstOut   = Test.uDstIn;
    30083008            Test.uSrcIn    = g_aMulDivU8[iFn].paFixedTests[iTest].uSrcIn;
    3009             Test.rc        = g_aMulDivU8[iFn].pfnNative(&Test.uDstOut, Test.uSrcIn, &Test.fEflOut);
     3009            uint32_t const fEflRet = g_aMulDivU8[iFn].pfnNative(&Test.uDstOut, Test.uSrcIn, Test.fEflIn);
     3010            Test.fEflOut   = fEflRet ? fEflRet : Test.fEflIn;
     3011            Test.rc        = fEflRet ? 0       : -1;
    30103012            if (g_aMulDivU8[iFn].paFixedTests[iTest].rc == 0 || g_aMulDivU8[iFn].paFixedTests[iTest].rc == -1)
    30113013                Test.rc = g_aMulDivU8[iFn].paFixedTests[iTest].rc;
     
    30223024    uint32_t const fEflIn = pEntry->fEflIn;
    30233025    uint16_t const uDstIn = pEntry->uDstIn;
    3024     uint8_t  const uSrcIn  = pEntry->uSrcIn;
     3026    uint8_t  const uSrcIn = pEntry->uSrcIn;
    30253027    cIterations /= 4;
    30263028    RTThreadYield();
    3027     uint64_t const nsStart     = RTTimeNanoTS();
     3029    uint64_t const nsStart = RTTimeNanoTS();
    30283030    for (uint32_t i = 0; i < cIterations; i++)
    30293031    {
    3030         uint32_t fBenchEfl  = fEflIn;
    30313032        uint16_t uBenchDst = uDstIn;
    3032         pfn(&uBenchDst, uSrcIn, &fBenchEfl);
    3033 
    3034         fBenchEfl = fEflIn;
     3033        pfn(&uBenchDst, uSrcIn, fEflIn);
     3034
    30353035        uBenchDst = uDstIn;
    3036         pfn(&uBenchDst, uSrcIn, &fBenchEfl);
    3037 
    3038         fBenchEfl = fEflIn;
     3036        pfn(&uBenchDst, uSrcIn, fEflIn);
     3037
    30393038        uBenchDst = uDstIn;
    3040         pfn(&uBenchDst, uSrcIn, &fBenchEfl);
    3041 
    3042         fBenchEfl = fEflIn;
     3039        pfn(&uBenchDst, uSrcIn, fEflIn);
     3040
    30433041        uBenchDst = uDstIn;
    3044         pfn(&uBenchDst, uSrcIn, &fBenchEfl);
     3042        pfn(&uBenchDst, uSrcIn, fEflIn);
    30453043    }
    30463044    return RTTimeNanoTS() - nsStart;
     
    30633061            for (uint32_t iTest = 0; iTest < cTests; iTest++ )
    30643062            {
    3065                 uint32_t fEfl  = paTests[iTest].fEflIn;
    3066                 uint16_t uDst  = paTests[iTest].uDstIn;
    3067                 int      rc    = g_aMulDivU8[iFn].pfn(&uDst, paTests[iTest].uSrcIn, &fEfl);
     3063                uint16_t uDst = paTests[iTest].uDstIn;
     3064                uint32_t fEfl = pfn(&uDst, paTests[iTest].uSrcIn, paTests[iTest].fEflIn);
     3065                int      rc   = fEfl ? 0    : -1;
     3066                fEfl          = fEfl ? fEfl : paTests[iTest].fEflIn;
    30683067                if (   uDst != paTests[iTest].uDstOut
    30693068                    || (fEfl | fEflIgn) != (paTests[iTest].fEflOut | fEflIgn)
     
    30783077                else
    30793078                {
    3080                      *g_pu16  = paTests[iTest].uDstIn;
    3081                      *g_pfEfl = paTests[iTest].fEflIn;
    3082                      rc = g_aMulDivU8[iFn].pfn(g_pu16, paTests[iTest].uSrcIn, g_pfEfl);
    3083                      RTTEST_CHECK(g_hTest, *g_pu16  == paTests[iTest].uDstOut);
    3084                      RTTEST_CHECK(g_hTest, (*g_pfEfl | fEflIgn) == (paTests[iTest].fEflOut | fEflIgn));
    3085                      RTTEST_CHECK(g_hTest, rc  == paTests[iTest].rc);
     3079                     *g_pu16 = paTests[iTest].uDstIn;
     3080                     fEfl = pfn(g_pu16, paTests[iTest].uSrcIn, paTests[iTest].fEflIn);
     3081                     rc   = fEfl ? 0    : -1;
     3082                     fEfl = fEfl ? fEfl : paTests[iTest].fEflIn;
     3083                     RTTEST_CHECK(g_hTest, *g_pu16 == paTests[iTest].uDstOut);
     3084                     RTTEST_CHECK(g_hTest, (fEfl | fEflIgn) == (paTests[iTest].fEflOut | fEflIgn));
     3085                     RTTEST_CHECK(g_hTest, rc == paTests[iTest].rc);
    30863086                }
    30873087            }
     
    31603160        { \
    31613161            Test.fEflIn    = RandEFlags(); \
    3162             Test.fEflOut   = Test.fEflIn; \
    31633162            Test.uDst1In   = RandU ## a_cBits ## Dst(iTest); \
    31643163            Test.uDst1Out  = Test.uDst1In; \
     
    31663165            Test.uDst2Out  = Test.uDst2In; \
    31673166            Test.uSrcIn    = RandU ## a_cBits ## Src(iTest); \
    3168             Test.rc        = a_aSubTests[iFn].pfnNative(&Test.uDst1Out, &Test.uDst2Out, Test.uSrcIn, &Test.fEflOut); \
     3167            uint32_t const fEflRet = a_aSubTests[iFn].pfnNative(&Test.uDst1Out, &Test.uDst2Out, Test.uSrcIn, Test.fEflIn); \
     3168            Test.fEflOut   = fEflRet ? fEflRet : Test.fEflIn; \
     3169            Test.rc        = fEflRet ? 0       : -1; \
    31693170            GenerateBinaryWrite(&BinOut, &Test, sizeof(Test)); \
    31703171        } \
     
    31733174            Test.fEflIn    = a_aSubTests[iFn].paFixedTests[iTest].fEflIn == UINT32_MAX ? RandEFlags() \
    31743175                           : a_aSubTests[iFn].paFixedTests[iTest].fEflIn; \
    3175             Test.fEflOut   = Test.fEflIn; \
    31763176            Test.uDst1In   = a_aSubTests[iFn].paFixedTests[iTest].uDst1In; \
    31773177            Test.uDst1Out  = Test.uDst1In; \
     
    31793179            Test.uDst2Out  = Test.uDst2In; \
    31803180            Test.uSrcIn    = a_aSubTests[iFn].paFixedTests[iTest].uSrcIn; \
    3181             Test.rc        = a_aSubTests[iFn].pfnNative(&Test.uDst1Out, &Test.uDst2Out, Test.uSrcIn, &Test.fEflOut); \
     3181            uint32_t const fEflRet = a_aSubTests[iFn].pfnNative(&Test.uDst1Out, &Test.uDst2Out, Test.uSrcIn, Test.fEflIn); \
     3182            Test.fEflOut   = fEflRet ? fEflRet : Test.fEflIn; \
     3183            Test.rc        = fEflRet ? 0       : -1; \
    31823184            if (a_aSubTests[iFn].paFixedTests[iTest].rc == 0 || a_aSubTests[iFn].paFixedTests[iTest].rc == -1) \
    31833185                Test.rc = a_aSubTests[iFn].paFixedTests[iTest].rc; \
     
    32163218    cIterations /= 4; \
    32173219    RTThreadYield(); \
    3218     uint64_t const nsStart     = RTTimeNanoTS(); \
     3220    uint64_t const nsStart = RTTimeNanoTS(); \
    32193221    for (uint32_t i = 0; i < cIterations; i++) \
    32203222    { \
    3221         uint32_t fBenchEfl  = fEflIn; \
    32223223        a_uType  uBenchDst1 = uDst1In;  \
    32233224        a_uType  uBenchDst2 = uDst2In;  \
    3224         pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3225        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, fEflIn); \
    32253226        \
    3226         fBenchEfl  = fEflIn; \
    32273227        uBenchDst1 = uDst1In; \
    32283228        uBenchDst2 = uDst2In; \
    3229         pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3229        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, fEflIn); \
    32303230        \
    3231         fBenchEfl  = fEflIn; \
    32323231        uBenchDst1 = uDst1In; \
    32333232        uBenchDst2 = uDst2In; \
    3234         pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3233        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, fEflIn); \
    32353234        \
    3236         fBenchEfl  = fEflIn; \
    32373235        uBenchDst1 = uDst1In; \
    32383236        uBenchDst2 = uDst2In; \
    3239         pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3237        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, fEflIn); \
    32403238    } \
    32413239    return RTTimeNanoTS() - nsStart; \
     
    32583256            for (uint32_t iTest = 0; iTest < cTests; iTest++ ) \
    32593257            { \
    3260                 uint32_t fEfl  = paTests[iTest].fEflIn; \
    32613258                a_uType  uDst1 = paTests[iTest].uDst1In; \
    32623259                a_uType  uDst2 = paTests[iTest].uDst2In; \
    3263                 int rc = pfn(&uDst1, &uDst2, paTests[iTest].uSrcIn, &fEfl); \
     3260                uint32_t fEfl = pfn(&uDst1, &uDst2, paTests[iTest].uSrcIn, paTests[iTest].fEflIn); \
     3261                int      rc   = fEfl ? 0    : -1; \
     3262                fEfl          = fEfl ? fEfl : paTests[iTest].fEflIn; \
    32643263                if (   uDst1 != paTests[iTest].uDst1Out \
    32653264                    || uDst2 != paTests[iTest].uDst2Out \
     
    32803279                     *g_pu ## a_cBits        = paTests[iTest].uDst1In; \
    32813280                     *g_pu ## a_cBits ## Two = paTests[iTest].uDst2In; \
    3282                      *g_pfEfl                = paTests[iTest].fEflIn; \
    3283                      rc  = pfn(g_pu ## a_cBits, g_pu ## a_cBits ## Two, paTests[iTest].uSrcIn, g_pfEfl); \
     3281                     fEfl = pfn(g_pu ## a_cBits, g_pu ## a_cBits ## Two, paTests[iTest].uSrcIn, paTests[iTest].fEflIn); \
     3282                     rc   = fEfl ? 0    : -1; \
     3283                     fEfl = fEfl ? fEfl : paTests[iTest].fEflIn; \
    32843284                     RTTEST_CHECK(g_hTest, *g_pu ## a_cBits        == paTests[iTest].uDst1Out); \
    32853285                     RTTEST_CHECK(g_hTest, *g_pu ## a_cBits ## Two == paTests[iTest].uDst2Out); \
    3286                      RTTEST_CHECK(g_hTest, (*g_pfEfl | fEflIgn)    == (paTests[iTest].fEflOut | fEflIgn)); \
     3286                     RTTEST_CHECK(g_hTest, (fEfl | fEflIgn)        == (paTests[iTest].fEflOut | fEflIgn)); \
    32873287                     RTTEST_CHECK(g_hTest, rc                      == paTests[iTest].rc); \
    32883288                } \
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r106097 r106179  
    618618#define IEM_MC_IND_CALL_U64_AND_FINISH(a_u64NewIP)      do { (void)fMcBegin; CHK_TYPE(uint64_t, a_u64NewIP); return VINF_SUCCESS; } while (0)
    619619#define IEM_MC_RETN_AND_FINISH(a_u16Pop)                do { (void)fMcBegin; return VINF_SUCCESS; } while (0)
    620 #define IEM_MC_RAISE_DIVIDE_ERROR()                     do { (void)fMcBegin; return VERR_TRPM_ACTIVE_TRAP; } while (0)
     620#define IEM_MC_RAISE_DIVIDE_ERROR_IF_LOCAL_IS_ZERO(a_uVar) do { (void)fMcBegin; CHK_VAR(a_uVar); if (a_uVar == 0) return VERR_TRPM_ACTIVE_TRAP; } while (0)
    621621#define IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE()       do { (void)fMcBegin; } while (0)
    622622#define IEM_MC_MAYBE_RAISE_WAIT_DEVICE_NOT_AVAILABLE()  do { (void)fMcBegin; } while (0)
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