VirtualBox

Changeset 104051 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Mar 26, 2024 2:10:26 AM (11 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162442
Message:

VMM/IEM: Optimizing (hopefully) and correcting flag handling in IEMAImpl.asm. Prep for shl, shr, and friends. bugref:10376

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

Legend:

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

    r103909 r104051  
    274274
    275275;;
     276; This is handy for generating absolutly correct EFLAGS.
     277;%define IEM_AIMPL_WITH_LOAD_AND_SAVE_ALL_STATUS_FLAGS
     278
     279;;
    276280; Load the relevant flags from [%1] if there are undefined flags (%3).
    277281;
    278282; @remarks      Clobbers T0, stack. Changes EFLAGS.
    279 ; @param        A2      The register pointing to the flags.
    280283; @param        1       The parameter (A0..A3) pointing to the eflags.
    281284; @param        2       The set of modified flags.
    282285; @param        3       The set of undefined flags.
    283 ; @param        4       Force loading the flags.
    284 ;
    285 %macro IEM_MAYBE_LOAD_FLAGS 3-4 1
    286  %if (%3 + %4) != 0
     286; @param        4       The flags that must be loaded.
     287;
     288%macro IEM_MAYBE_LOAD_FLAGS 4
     289 %ifdef IEM_AIMPL_WITH_LOAD_AND_SAVE_ALL_STATUS_FLAGS
     290        pushf                                                   ; store current flags
     291        mov     T0_32, [%1]                                     ; load the guest flags
     292        and     dword [xSP], ~(%2 | %3 | X86_EFL_STATUS_BITS)   ; mask out the modified and undefined flags
     293        and     T0_32, (%2 | %3 | X86_EFL_STATUS_BITS)          ; select the modified and undefined flags.
     294        or      [xSP], T0                                       ; merge guest flags with host flags.
     295        popf                                                    ; load the mixed flags.
     296
     297 %elif (%3 + %4) != 0
     298  %if 1        ; This approach seems faster on intel 10980XE
     299   %if (%3 | %4) == X86_EFL_CF
     300        ; Use bt to load bit into CF
     301        bt      dword [%1], X86_EFL_CF_BIT
     302   %else
     303        ; Use ADD to set OF and SHAF for the rest. ASSUMES T0_32 is eax!
     304        mov     eax, [%1]
     305    %if (%3 | %4) == X86_EFL_OF
     306        ; Use ADD to set OF.
     307        shl     eax, 31 - X86_EFL_OF_BIT
     308        add     eax, 80000000h
     309    %elif ((%3 | %4) & X86_EFL_OF) != 0
     310        ; Use ADD to set OF.
     311        xchg    al, ah
     312        shl     al, 15 - X86_EFL_OF_BIT
     313        add     al, 80h
     314        ; Use SAHF to set the other status flags.
     315        sahf
     316    %else ; OF not needed; so al -> ah and load ah into eflags.
     317     %if 1 ; Pretty similar on 10980XE, but shl seems faster on average.
     318        shl     eax, 8
     319     %else
     320        xchg    al, ah
     321     %endif
     322        sahf
     323    %endif
     324   %endif
     325
     326  %else
    287327        pushf                           ; store current flags
    288328        mov     T0_32, [%1]             ; load the guest flags
     
    291331        or      [xSP], T0               ; merge guest flags with host flags.
    292332        popf                            ; load the mixed flags.
     333  %endif
    293334 %endif
    294335%endmacro
     
    298339;
    299340; @remarks      Clobbers T0, stack. Changes EFLAGS.
    300 ; @param        A2      The register pointing to the flags.
    301341; @param        1       The parameter (A0..A3) pointing to the eflags.
    302342; @param        2       The set of flags to load.
     
    304344;
    305345%macro IEM_LOAD_FLAGS 3
     346 %ifdef IEM_AIMPL_WITH_LOAD_AND_SAVE_ALL_STATUS_FLAGS
     347        pushf                                                   ; store current flags
     348        mov     T0_32, [%1]                                     ; load the guest flags
     349        and     dword [xSP], ~(%2 | %3 | X86_EFL_STATUS_BITS)   ; mask out the modified, undefined and status flags
     350        and     T0_32, (%2 | %3 | X86_EFL_STATUS_BITS)          ; select the modified, undefined and status flags.
     351        or      [xSP], T0                                       ; merge guest flags with host flags.
     352        popf                                                    ; load the mixed flags.
     353
     354 %elif 1        ; This approach seems faster on intel 10980XE
     355  %if (%3 | %2) == X86_EFL_CF
     356        ; Use bt to load bit into CF
     357        bt      dword [%1], X86_EFL_CF_BIT
     358  %else
     359        mov     eax, [%1]                 ; ASSUMES T0_32 is eax!!
     360   %if (%3 | %2) == X86_EFL_OF
     361        ; Use ADD to set OF.
     362        shl     eax, 31 - X86_EFL_OF_BIT
     363        add     eax, 80000000h
     364   %elif ((%3 | %2) & X86_EFL_OF) != 0
     365        ; Use ADD to set OF.
     366        xchg    al, ah
     367        shl     al, 15 - X86_EFL_OF_BIT
     368        add     al, 80h
     369        ; Use SAHF to set the other status flags.
     370        sahf
     371   %else ; OF not needed; so al -> ah and load ah into eflags.
     372    %if 1 ; Pretty similar on 10980XE, but shl seems faster on average.
     373        shl     eax, 8
     374    %else
     375        xchg    al, ah
     376    %endif
     377        sahf
     378   %endif
     379  %endif ; (%3 | %2) != X86_EFL_CF
     380
     381 %else
    306382        pushf                           ; store current flags
    307383        mov     T0_32, [%1]             ; load the guest flags
     
    310386        or      [xSP], T0               ; merge guest flags with host flags.
    311387        popf                            ; load the mixed flags.
     388 %endif
    312389%endmacro
    313390
     
    319396; @param        2       The mask of modified flags to save.
    320397; @param        3       The mask of undefined flags to (maybe) save.
    321 ;
    322 %macro IEM_SAVE_FLAGS 3
    323  %if (%2 | %3) != 0
     398; @param        4       The mask of flags that are zeroed (and thus doesn't require loading, just clearing)
     399;
     400%macro IEM_SAVE_FLAGS 3-4 0
     401 %if (%2 | %3 | %4) != 0
     402        mov     T1_32, [%1]                                     ; flags
     403  %ifdef IEM_AIMPL_WITH_LOAD_AND_SAVE_ALL_STATUS_FLAGS
    324404        pushf
    325         pop     T1
    326         mov     T0_32, [%1]             ; flags
    327         and     T0_32, ~(%2 | %3)       ; clear the modified & undefined flags.
    328         and     T1_32, (%2 | %3)        ; select the modified and undefined flags.
     405        pop     T0
     406        and     T1_32, ~(%2 | %3 | %4 | X86_EFL_STATUS_BITS)    ; clear the modified & undefined & zeroed & status flags.
     407        and     T0_32, (%2 | %3 | X86_EFL_STATUS_BITS)          ; select the modified, undefined and status flags.
     408  %else
     409   %if (%2 | %3 | %4) == X86_EFL_CF
     410        setc    T0_8
     411   %elif (%2 | %3) == X86_EFL_OF
     412        seto    T0_8
     413        shl     T0_32, X86_EFL_OF_BIT
     414   %elif (%2 | %3) == X86_EFL_ZF
     415        setz    T0_8                    ; On 10980XE this is faster than the next option 5596 vs 5936 ps/call (cmpxchg8b-positive).
     416        shl     T0_32, X86_EFL_ZF_BIT
     417   %elif (%2 | %3) <= 0xff
     418        lahf
     419        movzx   eax, ah                 ; ASSUMES T0_32 is eax!
     420   %elif 1                              ; The locked functions are generally faster on 10980XE with this approach
     421        lahf                            ; while there seems only to be a tiny advantage in most other test.
     422        movzx   eax, ah                 ; ASSUMES T0_32 is eax!
     423        jno     .of_is_clear
     424        or      eax, X86_EFL_OF
     425.of_is_clear:
     426   %else
     427        pushf                           ; this is a bit slow
     428        pop     T0
     429   %endif
     430        and     T1_32, ~(%2 | %3 | %4)  ; clear the modified & undefined & zeroed flags.
     431        and     T0_32, (%2 | %3)        ; select the modified and undefined flags.
     432  %endif
    329433        or      T0_32, T1_32            ; combine the flags.
    330434        mov     [%1], T0_32             ; save the flags.
     
    494598; @param        3       The modified flags.
    495599; @param        4       The undefined flags.
    496 ; @param        5       Force flag loading (ADC, SBC).
    497 ;
    498 %macro IEMIMPL_BIN_OP 5
     600; @param        5       The flags that must be loaded (ADC, SBC).
     601; @param        6       The flags that will be zeroed by the operation.
     602;
     603%macro IEMIMPL_BIN_OP 6
    499604BEGINCODE
    500605BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
     
    502607        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    503608        %1      byte [A0], A1_8
    504         IEM_SAVE_FLAGS                 A2, %3, %4
     609        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    505610        EPILOGUE_3_ARGS
    506611ENDPROC iemAImpl_ %+ %1 %+ _u8
     
    510615        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    511616        %1      word [A0], A1_16
    512         IEM_SAVE_FLAGS                 A2, %3, %4
     617        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    513618        EPILOGUE_3_ARGS
    514619ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    518623        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    519624        %1      dword [A0], A1_32
    520         IEM_SAVE_FLAGS                 A2, %3, %4
     625        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    521626        EPILOGUE_3_ARGS
    522627ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    527632        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    528633        %1      qword [A0], A1
    529         IEM_SAVE_FLAGS                 A2, %3, %4
     634        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    530635        EPILOGUE_3_ARGS_EX 8
    531636ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    538643        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    539644        lock %1 byte [A0], A1_8
    540         IEM_SAVE_FLAGS                 A2, %3, %4
     645        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    541646        EPILOGUE_3_ARGS
    542647ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
     
    546651        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    547652        lock %1 word [A0], A1_16
    548         IEM_SAVE_FLAGS                 A2, %3, %4
     653        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    549654        EPILOGUE_3_ARGS
    550655ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
     
    554659        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    555660        lock %1 dword [A0], A1_32
    556         IEM_SAVE_FLAGS                 A2, %3, %4
     661        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    557662        EPILOGUE_3_ARGS
    558663ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
     
    563668        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, %5
    564669        lock %1 qword [A0], A1
    565         IEM_SAVE_FLAGS                 A2, %3, %4
     670        IEM_SAVE_FLAGS                 A2, %3, %4, %6
    566671        EPILOGUE_3_ARGS_EX 8
    567672ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
     
    570675%endmacro
    571676
    572 ;            instr,lock, modified-flags,                                                               undefined flags, force loading flags
    573 IEMIMPL_BIN_OP add,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0
    574 IEMIMPL_BIN_OP adc,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               1
    575 IEMIMPL_BIN_OP sub,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0
    576 IEMIMPL_BIN_OP sbb,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               1
    577 IEMIMPL_BIN_OP or,   1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF),              X86_EFL_AF,      0
    578 IEMIMPL_BIN_OP xor,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF),              X86_EFL_AF,      0
    579 IEMIMPL_BIN_OP and,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF),              X86_EFL_AF,      0
    580 IEMIMPL_BIN_OP cmp,  0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0
    581 IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF),              X86_EFL_AF,      0
     677;            instr,lock, modified-flags,                                                               undefined flags, must be loaded, zeroed flags
     678IEMIMPL_BIN_OP add,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0,              0
     679IEMIMPL_BIN_OP adc,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               X86_EFL_CF,     0
     680IEMIMPL_BIN_OP sub,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0,              0
     681IEMIMPL_BIN_OP sbb,  1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               X86_EFL_CF,     0
     682IEMIMPL_BIN_OP cmp,  0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0,               0,              0
     683IEMIMPL_BIN_OP or,   1, (X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF),                                        X86_EFL_AF,      0,              X86_EFL_OF | X86_EFL_CF
     684IEMIMPL_BIN_OP xor,  1, (X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF),                                        X86_EFL_AF,      0,              X86_EFL_OF | X86_EFL_CF
     685IEMIMPL_BIN_OP and,  1, (X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF),                                        X86_EFL_AF,      0,              X86_EFL_OF | X86_EFL_CF
     686IEMIMPL_BIN_OP test, 0, (X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF),                                        X86_EFL_AF,      0,              X86_EFL_OF | X86_EFL_CF
    582687
    583688
     
    595700; @param        2       The modified flags.
    596701; @param        3       The undefined flags.
    597 ;
    598 %macro IEMIMPL_VEX_BIN_OP 3
     702; @param        4       The zeroed flags.
     703;
     704%macro IEMIMPL_VEX_BIN_OP 4
    599705BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    600706        PROLOGUE_4_ARGS
    601         IEM_MAYBE_LOAD_FLAGS           A3, %2, %3
     707        IEM_MAYBE_LOAD_FLAGS           A3, %2, %3, 0 ;; @todo do we need to load undefined flags for any platform?
    602708        %1      T0_32, A1_32, A2_32
    603709        mov     [A0], T0_32
    604         IEM_SAVE_FLAGS                 A3, %2, %3
     710        IEM_SAVE_FLAGS                 A3, %2, %3, %4
    605711        EPILOGUE_4_ARGS
    606712ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    609715BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
    610716        PROLOGUE_4_ARGS
    611         IEM_MAYBE_LOAD_FLAGS           A3, %2, %3
     717        IEM_MAYBE_LOAD_FLAGS           A3, %2, %3, 0
    612718        %1      T0, A1, A2
    613719        mov     [A0], T0
    614         IEM_SAVE_FLAGS                 A3, %2, %3
     720        IEM_SAVE_FLAGS                 A3, %2, %3, %4
    615721        EPILOGUE_4_ARGS
    616722ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    618724%endmacro
    619725
    620 ;                 instr,  modified-flags,                                                                undefined-flags
    621 IEMIMPL_VEX_BIN_OP andn,  (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF),                           (X86_EFL_AF | X86_EFL_PF)
    622 IEMIMPL_VEX_BIN_OP bextr, (X86_EFL_OF | X86_EFL_ZF | X86_EFL_CF),                                        (X86_EFL_SF | X86_EFL_AF | X86_EFL_PF)
    623 IEMIMPL_VEX_BIN_OP bzhi,  (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF),                           (X86_EFL_AF | X86_EFL_PF)
     726;                 instr,  modified-flags,                       undefined-flags,                        zeroed-flags
     727IEMIMPL_VEX_BIN_OP andn,  X86_EFL_SF | X86_EFL_ZF,              X86_EFL_AF | X86_EFL_PF,                X86_EFL_OF | X86_EFL_CF
     728IEMIMPL_VEX_BIN_OP bextr, X86_EFL_ZF,                           X86_EFL_SF | X86_EFL_AF | X86_EFL_PF,   X86_EFL_OF | X86_EFL_CF
     729IEMIMPL_VEX_BIN_OP bzhi,  X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF, X86_EFL_AF | X86_EFL_PF,                X86_EFL_OF
    624730
    625731;;
     
    635741; @param        2       The modified flags.
    636742; @param        3       The undefined flags.
    637 ;
    638 %macro IEMIMPL_VEX_BIN_OP_2 3
     743; @param        4       The zeroed flags.
     744;
     745%macro IEMIMPL_VEX_BIN_OP_2 4
    639746BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
    640747        PROLOGUE_4_ARGS
    641         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     748        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3, 0 ;; @todo check if any undefined flags are passed thru
    642749        mov     T0_32, [A0]
    643750        %1      T0_32, A1_32
    644751        mov     [A0], T0_32
    645         IEM_SAVE_FLAGS                 A2, %2, %3
     752        IEM_SAVE_FLAGS                 A2, %2, %3, %4
    646753        EPILOGUE_4_ARGS
    647754ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    650757BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 12
    651758        PROLOGUE_4_ARGS
    652         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     759        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3, 0
    653760        mov     T0, [A0]
    654761        %1      T0, A1
    655762        mov     [A0], T0
    656         IEM_SAVE_FLAGS                 A2, %2, %3
     763        IEM_SAVE_FLAGS                 A2, %2, %3, %4
    657764        EPILOGUE_4_ARGS
    658765ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    660767%endmacro
    661768
    662 ;                    instr,  modified-flags,                                      undefined-flags
    663 IEMIMPL_VEX_BIN_OP_2 blsr,   (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF)
    664 IEMIMPL_VEX_BIN_OP_2 blsmsk, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF)
    665 IEMIMPL_VEX_BIN_OP_2 blsi,   (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF)
     769;                    instr,     modified-flags,                         undefined-flags             zeroed-flags
     770IEMIMPL_VEX_BIN_OP_2 blsr,      (X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF),  X86_EFL_OF
     771IEMIMPL_VEX_BIN_OP_2 blsmsk,    (X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF),  X86_EFL_OF
     772IEMIMPL_VEX_BIN_OP_2 blsi,      (X86_EFL_SF | X86_EFL_ZF | X86_EFL_CF), (X86_EFL_AF | X86_EFL_PF),  X86_EFL_OF
    666773
    667774
     
    874981BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
    875982        PROLOGUE_3_ARGS
    876         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     983        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    877984        %1      word [A0], A1_16
    878         IEM_SAVE_FLAGS                 A2, %3, %4
     985        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    879986        EPILOGUE_3_ARGS
    880987ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    882989BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
    883990        PROLOGUE_3_ARGS
    884         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     991        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    885992        %1      dword [A0], A1_32
    886         IEM_SAVE_FLAGS                 A2, %3, %4
     993        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    887994        EPILOGUE_3_ARGS
    888995ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    891998BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
    892999        PROLOGUE_3_ARGS
    893         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     1000        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    8941001        %1      qword [A0], A1
    895         IEM_SAVE_FLAGS                 A2, %3, %4
     1002        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    8961003        EPILOGUE_3_ARGS_EX 8
    8971004ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    9021009BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 12
    9031010        PROLOGUE_3_ARGS
    904         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     1011        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    9051012        lock %1 word [A0], A1_16
    906         IEM_SAVE_FLAGS                 A2, %3, %4
     1013        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    9071014        EPILOGUE_3_ARGS
    9081015ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
     
    9101017BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 12
    9111018        PROLOGUE_3_ARGS
    912         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     1019        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    9131020        lock %1 dword [A0], A1_32
    914         IEM_SAVE_FLAGS                 A2, %3, %4
     1021        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    9151022        EPILOGUE_3_ARGS
    9161023ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
     
    9191026BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
    9201027        PROLOGUE_3_ARGS
    921         IEM_MAYBE_LOAD_FLAGS           A2, %3, %4
     1028        IEM_MAYBE_LOAD_FLAGS           A2, %3, %4, 0
    9221029        lock %1 qword [A0], A1
    923         IEM_SAVE_FLAGS                 A2, %3, %4
     1030        IEM_SAVE_FLAGS                 A2, %3, %4, 0
    9241031        EPILOGUE_3_ARGS_EX 8
    9251032ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
     
    9271034 %endif ; locked
    9281035%endmacro
     1036
     1037;  Undefined flags are passed thru here by the intel and amd CPUs we have.
    9291038;                      modified efl, undefined eflags
    930 IEMIMPL_BIT_OP bt,  0, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
    931 IEMIMPL_BIT_OP btc, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
    932 IEMIMPL_BIT_OP bts, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
    933 IEMIMPL_BIT_OP btr, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
     1039IEMIMPL_BIT_OP bt,  0, (X86_EFL_CF), 0 ;passed-thru (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
     1040IEMIMPL_BIT_OP btc, 1, (X86_EFL_CF), 0 ;passed-thru (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
     1041IEMIMPL_BIT_OP bts, 1, (X86_EFL_CF), 0 ;passed-thru (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
     1042IEMIMPL_BIT_OP btr, 1, (X86_EFL_CF), 0 ;passed-thru (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
    9341043
    9351044;;
     
    9441053; In the ZF case the destination register is 'undefined', however it seems that
    9451054; both AMD and Intel just leaves it as is.  The undefined EFLAGS differs between
    946 ; AMD and Intel and accoridng to https://www.sandpile.org/x86/flags.htm between
     1055; AMD and Intel and according to https://www.sandpile.org/x86/flags.htm between
    9471056; Intel microarchitectures.  We only implement 'intel' and 'amd' variation with
    948 ; the behaviour of more recent CPUs (Intel 10980X and AMD 3990X).
     1057; the behaviour of more recent CPUs (Intel 10980XE and AMD 3990X).
     1058;
     1059; Intel: Clear all and calculate PF in addition to ZF.
     1060; AMD:   Passthru all flags other than ZF.
    9491061;
    9501062; @param        1       The instruction mnemonic.
     
    9551067%macro IEMIMPL_BIT_OP2 4
    9561068BEGINCODE
     1069;   16-bit
     1070
    9571071BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
    9581072        PROLOGUE_3_ARGS
    959         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1073        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3, %3 ; Must load undefined flags since AMD passes them thru
    9601074        %1      T0_16, A1_16
    9611075%if %4 != 0
     
    9641078        mov     [A0], T0_16
    9651079.unchanged_dst:
    966         IEM_SAVE_FLAGS                 A2, %2, %3
     1080        IEM_SAVE_FLAGS                 A2, %2, %3, 0
    9671081        EPILOGUE_3_ARGS
    9681082ENDPROC iemAImpl_ %+ %1 %+ _u16
    9691083
    970 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _intel, 12
    971         PROLOGUE_3_ARGS
    972         %1      T1_16, A1_16
    973 %if %4 != 0
    974         jz      .unchanged_dst
    975 %endif
    976         mov     [A0], T1_16
    977         IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
    978         EPILOGUE_3_ARGS
    979 .unchanged_dst:
    980         IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
    981         EPILOGUE_3_ARGS
    982 ENDPROC iemAImpl_ %+ %1 %+ _u16_intel
    983 
    984 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _amd, 12
    985         PROLOGUE_3_ARGS
    986         %1      T0_16, A1_16
    987 %if %4 != 0
    988         jz      .unchanged_dst
    989 %endif
    990         mov     [A0], T0_16
    991 .unchanged_dst:
    992         IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
    993         EPILOGUE_3_ARGS
    994 ENDPROC iemAImpl_ %+ %1 %+ _u16_amd
    995 
     1084;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _intel, 12
     1085;bad;        PROLOGUE_3_ARGS
     1086;bad;        %1      T1_16, A1_16
     1087;bad;        jz      .unchanged_dst
     1088;bad;        mov     [A0], T1_16
     1089;bad;        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     1090;bad;        EPILOGUE_3_ARGS
     1091;bad;.unchanged_dst:
     1092;bad;%if %4 != 0
     1093;bad;        mov     [A0], T1_16
     1094;bad;%endif
     1095;bad;        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     1096;bad;        EPILOGUE_3_ARGS
     1097;bad;ENDPROC iemAImpl_ %+ %1 %+ _u16_intel
     1098;bad;
     1099;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _amd, 12
     1100;bad;        PROLOGUE_3_ARGS
     1101;bad;        %1      T0_16, A1_16
     1102;bad;%if %4 != 0
     1103;bad;        jz      .unchanged_dst
     1104;bad;%endif
     1105;bad;        mov     [A0], T0_16
     1106;bad;.unchanged_dst:
     1107;bad;        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     1108;bad;        EPILOGUE_3_ARGS
     1109;bad;ENDPROC iemAImpl_ %+ %1 %+ _u16_amd
     1110
     1111;   32-bit
    9961112
    9971113BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
    9981114        PROLOGUE_3_ARGS
    999         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1115        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3, %3 ; Must load undefined flags since AMD passes them thru
    10001116        %1      T0_32, A1_32
    10011117%if %4 != 0
     
    10041120        mov     [A0], T0_32
    10051121.unchanged_dst:
    1006         IEM_SAVE_FLAGS                 A2, %2, %3
     1122        IEM_SAVE_FLAGS                 A2, %2, %3, 0
    10071123        EPILOGUE_3_ARGS
    10081124ENDPROC iemAImpl_ %+ %1 %+ _u32
    10091125
    1010 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _intel, 12
    1011         PROLOGUE_3_ARGS
    1012         %1      T1_32, A1_32
    1013 %if %4 != 0
    1014         jz      .unchanged_dst
    1015 %endif
    1016         mov     [A0], T1_32
    1017         IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
    1018         EPILOGUE_3_ARGS
    1019 .unchanged_dst:
    1020         IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
    1021         EPILOGUE_3_ARGS
    1022 ENDPROC iemAImpl_ %+ %1 %+ _u32_intel
    1023 
    1024 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _amd, 12
    1025         PROLOGUE_3_ARGS
    1026         %1      T0_32, A1_32
    1027 %if %4 != 0
    1028         jz      .unchanged_dst
    1029 %endif
    1030         mov     [A0], T0_32
    1031 .unchanged_dst:
    1032         IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
    1033         EPILOGUE_3_ARGS
    1034 ENDPROC iemAImpl_ %+ %1 %+ _u32_amd
     1126;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _intel, 12
     1127;bad;        PROLOGUE_3_ARGS
     1128;bad;        %1      T1_32, A1_32
     1129;bad;%if %4 != 0
     1130;bad;        jz      .unchanged_dst
     1131;bad;%endif
     1132;bad;        mov     [A0], T1_32
     1133;bad;        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     1134;bad;        EPILOGUE_3_ARGS
     1135;bad;.unchanged_dst:
     1136;bad;        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     1137;bad;        EPILOGUE_3_ARGS
     1138;bad;ENDPROC iemAImpl_ %+ %1 %+ _u32_intel
     1139;bad;
     1140;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _amd, 12
     1141;bad;        PROLOGUE_3_ARGS
     1142;bad;        %1      T0_32, A1_32
     1143;bad;%if %4 != 0
     1144;bad;        jz      .unchanged_dst
     1145;bad;%endif
     1146;bad;        mov     [A0], T0_32
     1147;bad;.unchanged_dst:
     1148;bad;        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     1149;bad;        EPILOGUE_3_ARGS
     1150;bad;ENDPROC iemAImpl_ %+ %1 %+ _u32_amd
    10351151
    10361152
    10371153 %ifdef RT_ARCH_AMD64
     1154;   64-bit
    10381155
    10391156BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
    10401157        PROLOGUE_3_ARGS
    1041         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1158        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3, %3 ; Must load undefined flags since AMD passes them thru
    10421159        %1      T0, A1
    10431160%if %4 != 0
     
    10461163        mov     [A0], T0
    10471164.unchanged_dst:
    1048         IEM_SAVE_FLAGS                 A2, %2, %3
     1165        IEM_SAVE_FLAGS                 A2, %2, %3, 0
    10491166        EPILOGUE_3_ARGS_EX 8
    10501167ENDPROC iemAImpl_ %+ %1 %+ _u64
    10511168
    1052 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _intel, 16
    1053         PROLOGUE_3_ARGS
    1054         IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
    1055         %1      T1, A1
    1056 %if %4 != 0
    1057         jz      .unchanged_dst
    1058 %endif
    1059         mov     [A0], T1
    1060         IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
    1061         EPILOGUE_3_ARGS
    1062 .unchanged_dst:
    1063         IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
    1064         EPILOGUE_3_ARGS
    1065 ENDPROC iemAImpl_ %+ %1 %+ _u64_intel
    1066 
    1067 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _amd, 16
    1068         PROLOGUE_3_ARGS
    1069         %1      T0, A1
    1070 %if %4 != 0
    1071         jz      .unchanged_dst
    1072 %endif
    1073         mov     [A0], T0
    1074 .unchanged_dst:
    1075         IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
    1076         EPILOGUE_3_ARGS_EX 8
    1077 ENDPROC iemAImpl_ %+ %1 %+ _u64_amd
     1169;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _intel, 16
     1170;bad;        PROLOGUE_3_ARGS
     1171;bad;        %1      T1, A1
     1172;bad;%if %4 != 0
     1173;bad;        jz      .unchanged_dst
     1174;bad;%endif
     1175;bad;        mov     [A0], T1
     1176;bad;        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     1177;bad;        EPILOGUE_3_ARGS
     1178;bad;.unchanged_dst:
     1179;bad;        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     1180;bad;        EPILOGUE_3_ARGS
     1181;bad;ENDPROC iemAImpl_ %+ %1 %+ _u64_intel
     1182;bad;
     1183;bad;BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _amd, 16
     1184;bad;        PROLOGUE_3_ARGS
     1185;bad;        %1      T0, A1
     1186;bad;%if %4 != 0
     1187;bad;        jz      .unchanged_dst
     1188;bad;%endif
     1189;bad;        mov     [A0], T0
     1190;bad;.unchanged_dst:
     1191;bad;        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     1192;bad;        EPILOGUE_3_ARGS_EX 8
     1193;bad;ENDPROC iemAImpl_ %+ %1 %+ _u64_amd
    10781194
    10791195 %endif ; RT_ARCH_AMD64
     
    11021218; @param        2       The modified flags.
    11031219; @param        3       The undefined flags.
    1104 ;
    1105 %macro IEMIMPL_BIT_OP3 3
     1220; @param        4       The zeroed flags.
     1221;
     1222%macro IEMIMPL_BIT_OP3 4
    11061223BEGINCODE
    11071224BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
     
    11101227        %1      T0_16, A1_16
    11111228        mov     [A0], T0_16
    1112         IEM_SAVE_FLAGS                 A2, %2, %3
     1229        IEM_SAVE_FLAGS                 A2, %2, %3, %4
    11131230        EPILOGUE_3_ARGS
    11141231ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    11191236        %1      T0_32, A1_32
    11201237        mov     [A0], T0_32
    1121         IEM_SAVE_FLAGS                 A2, %2, %3
     1238        IEM_SAVE_FLAGS                 A2, %2, %3, %4
    11221239        EPILOGUE_3_ARGS
    11231240ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    11291246        %1      T0, A1
    11301247        mov     [A0], T0
    1131         IEM_SAVE_FLAGS                 A2, %2, %3
     1248        IEM_SAVE_FLAGS                 A2, %2, %3, %4
    11321249        EPILOGUE_3_ARGS_EX 8
    11331250ENDPROC iemAImpl_ %+ %1 %+ _u64
    11341251 %endif ; RT_ARCH_AMD64
    11351252%endmacro
    1136 IEMIMPL_BIT_OP3 popcnt, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF), 0
     1253IEMIMPL_BIT_OP3 popcnt, X86_EFL_ZF, 0, X86_EFL_CF | X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF
    11371254
    11381255
     
    11451262; @param        2       Undefined EFLAGS.
    11461263; @param        3       Function suffix.
    1147 ; @param        4       EFLAGS variation: 0 for native, 1 for intel (ignored),
     1264; @param        4       EFLAGS variation: 0 for native, 1 for intel,
    11481265;                       2 for AMD (set AF, clear PF, ZF and SF).
    11491266%macro IEMIMPL_IMUL_TWO 4
    11501267BEGINPROC_FASTCALL iemAImpl_imul_two_u16 %+ %3, 12
    11511268        PROLOGUE_3_ARGS
    1152         IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2
     1269        IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2, %2 ; Undefined flags may be passed thru (AMD)
    11531270        imul    A1_16, word [A0]
    11541271        mov     [A0], A1_16
    11551272 %if %4 != 1
    1156         IEM_SAVE_FLAGS                          A2, %1, %2
     1273        IEM_SAVE_FLAGS                          A2, %1, %2, 0
    11571274 %else
    1158         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1_16, 16, A1
     1275        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1_16, 16, A1 ; intel
    11591276 %endif
    11601277        EPILOGUE_3_ARGS
     
    11631280BEGINPROC_FASTCALL iemAImpl_imul_two_u32 %+ %3, 12
    11641281        PROLOGUE_3_ARGS
    1165         IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2
     1282        IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2, %2 ; Undefined flags may be passed thru (AMD)
    11661283        imul    A1_32, dword [A0]
    11671284        mov     [A0], A1_32
    11681285 %if %4 != 1
    1169         IEM_SAVE_FLAGS                          A2, %1, %2
     1286        IEM_SAVE_FLAGS                          A2, %1, %2, 0
    11701287 %else
    1171         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1_32, 32, A1
     1288        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1_32, 32, A1 ; intel
    11721289 %endif
    11731290        EPILOGUE_3_ARGS
     
    11771294BEGINPROC_FASTCALL iemAImpl_imul_two_u64 %+ %3, 16
    11781295        PROLOGUE_3_ARGS
    1179         IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2
     1296        IEM_MAYBE_LOAD_FLAGS                    A2, %1, %2, %2 ; Undefined flags may be passed thru (AMD)
    11801297        imul    A1, qword [A0]
    11811298        mov     [A0], A1
    11821299 %if %4 != 1
    1183         IEM_SAVE_FLAGS                          A2, %1, %2
     1300        IEM_SAVE_FLAGS                          A2, %1, %2, 0
    11841301 %else
    1185         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1, 64, A1
     1302        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF    A2, %1, X86_EFL_AF | X86_EFL_ZF, A1, 64, A1 ; intel
    11861303 %endif
    11871304        EPILOGUE_3_ARGS_EX 8
     
    11891306 %endif ; RT_ARCH_AMD64
    11901307%endmacro
     1308; The SF, ZF, AF and PF flags are "undefined". AMD (3990x) leaves these
     1309; flags as is.  Whereas Intel skylake (6700K and 10980XE (Cascade Lake)) always
     1310; clear AF and ZF and calculates SF and PF as per the lower half of the result.
    11911311IEMIMPL_IMUL_TWO X86_EFL_OF | X86_EFL_CF, X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF,       , 0
    11921312IEMIMPL_IMUL_TWO X86_EFL_OF | X86_EFL_CF, 0,                                                 _intel, 1
     
    12901410        xadd    [A0], T0_8
    12911411        mov     [A1], T0_8
    1292         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1412        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    12931413        EPILOGUE_3_ARGS
    12941414ENDPROC iemAImpl_xadd_u8
     
    13001420        xadd    [A0], T0_16
    13011421        mov     [A1], T0_16
    1302         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1422        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13031423        EPILOGUE_3_ARGS
    13041424ENDPROC iemAImpl_xadd_u16
     
    13101430        xadd    [A0], T0_32
    13111431        mov     [A1], T0_32
    1312         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1432        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13131433        EPILOGUE_3_ARGS
    13141434ENDPROC iemAImpl_xadd_u32
     
    13211441        xadd    [A0], T0
    13221442        mov     [A1], T0
    1323         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1443        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13241444        EPILOGUE_3_ARGS
    13251445ENDPROC iemAImpl_xadd_u64
     
    13321452        lock xadd [A0], T0_8
    13331453        mov     [A1], T0_8
    1334         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1454        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13351455        EPILOGUE_3_ARGS
    13361456ENDPROC iemAImpl_xadd_u8_locked
     
    13421462        lock xadd [A0], T0_16
    13431463        mov     [A1], T0_16
    1344         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1464        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13451465        EPILOGUE_3_ARGS
    13461466ENDPROC iemAImpl_xadd_u16_locked
     
    13521472        lock xadd [A0], T0_32
    13531473        mov     [A1], T0_32
    1354         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1474        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13551475        EPILOGUE_3_ARGS
    13561476ENDPROC iemAImpl_xadd_u32_locked
     
    13631483        lock xadd [A0], T0
    13641484        mov     [A1], T0
    1365         IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
     1485        IEM_SAVE_FLAGS       A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0, 0
    13661486        EPILOGUE_3_ARGS
    13671487ENDPROC iemAImpl_xadd_u64_locked
     
    14021522        mov     [r11], eax
    14031523        mov     [r11 + 4], edx
    1404         IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1524        IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    14051525
    14061526        pop     rbx
     
    14221542        mov     [rsi], eax
    14231543        mov     [rsi + 4], edx
    1424         IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1544        IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    14251545
    14261546        pop     rbx
     
    14491569        mov     [esi], eax
    14501570        mov     [esi + 4], edx
    1451         IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, edi)
     1571        IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, edi)
    14521572
    14531573        pop     ebp
     
    14771597        mov     [r11], eax
    14781598        mov     [r11 + 4], edx
    1479         IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1599        IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    14801600
    14811601        pop     rbx
     
    14971617        mov     [rsi], eax
    14981618        mov     [rsi + 4], edx
    1499         IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1619        IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    15001620
    15011621        pop     rbx
     
    15241644        mov     [esi], eax
    15251645        mov     [esi + 4], edx
    1526         IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, edi)
     1646        IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, edi)
    15271647
    15281648        pop     ebp
     
    15681688        mov     [r11], rax
    15691689        mov     [r11 + 8], rdx
    1570         IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1690        IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    15711691
    15721692        pop     rbx
     
    15881708        mov     [rsi], rax
    15891709        mov     [rsi + 8], rdx
    1590         IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1710        IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    15911711
    15921712        pop     rbx
     
    16131733        mov     [r11], rax
    16141734        mov     [r11 + 8], rdx
    1615         IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1735        IEM_SAVE_FLAGS       r9, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    16161736
    16171737        pop     rbx
     
    16331753        mov     [rsi], rax
    16341754        mov     [rsi + 8], rdx
    1635         IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0 ; clobbers T0+T1 (eax, r11)
     1755        IEM_SAVE_FLAGS       r10, (X86_EFL_ZF), 0, 0 ; clobbers T0+T1 (eax, r11)
    16361756
    16371757        pop     rbx
     
    16601780        %1 cmpxchg [A0], A2_8
    16611781        mov     [A1], al
    1662         IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0 ; clobbers T0+T1 (eax, r11/edi)
     1782        IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0, 0 ; clobbers T0+T1 (eax, r11/edi)
    16631783        EPILOGUE_4_ARGS
    16641784ENDPROC iemAImpl_cmpxchg_u8 %+ %2
     
    16701790        %1 cmpxchg [A0], A2_16
    16711791        mov     [A1], ax
    1672         IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0 ; clobbers T0+T1 (eax, r11/edi)
     1792        IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0, 0 ; clobbers T0+T1 (eax, r11/edi)
    16731793        EPILOGUE_4_ARGS
    16741794ENDPROC iemAImpl_cmpxchg_u16 %+ %2
     
    16801800        %1 cmpxchg [A0], A2_32
    16811801        mov     [A1], eax
    1682         IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0 ; clobbers T0+T1 (eax, r11/edi)
     1802        IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0, 0 ; clobbers T0+T1 (eax, r11/edi)
    16831803        EPILOGUE_4_ARGS
    16841804ENDPROC iemAImpl_cmpxchg_u32 %+ %2
     
    16911811        %1 cmpxchg [A0], A2
    16921812        mov     [A1], rax
    1693         IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0 ; clobbers T0+T1 (eax, r11/edi)
     1813        IEM_SAVE_FLAGS       A3, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0, 0 ; clobbers T0+T1 (eax, r11/edi)
    16941814        EPILOGUE_4_ARGS
    16951815%else
     
    17221842        mov     [esi], eax
    17231843        mov     [esi + 4], edx
    1724         IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0 ; clobbers T0+T1 (eax, edi)
     1844        IEM_SAVE_FLAGS       ebp, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF), 0, 0 ; clobbers T0+T1 (eax, edi)
    17251845
    17261846        pop     ebp
     
    17421862IEMIMPL_CMPXCHG , ,
    17431863IEMIMPL_CMPXCHG lock, _locked
     1864
     1865
    17441866
    17451867;;
     
    17631885        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    17641886        %1      byte [A0]
    1765         IEM_SAVE_FLAGS       A1, %2, %3
     1887        IEM_SAVE_FLAGS       A1, %2, %3, 0
    17661888        EPILOGUE_2_ARGS
    17671889ENDPROC iemAImpl_ %+ %1 %+ _u8
     
    17711893        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    17721894        lock %1 byte [A0]
    1773         IEM_SAVE_FLAGS       A1, %2, %3
     1895        IEM_SAVE_FLAGS       A1, %2, %3, 0
    17741896        EPILOGUE_2_ARGS
    17751897ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
     
    17791901        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    17801902        %1      word [A0]
    1781         IEM_SAVE_FLAGS       A1, %2, %3
     1903        IEM_SAVE_FLAGS       A1, %2, %3, 0
    17821904        EPILOGUE_2_ARGS
    17831905ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    17871909        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    17881910        lock %1 word [A0]
    1789         IEM_SAVE_FLAGS       A1, %2, %3
     1911        IEM_SAVE_FLAGS       A1, %2, %3, 0
    17901912        EPILOGUE_2_ARGS
    17911913ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
     
    17951917        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    17961918        %1      dword [A0]
    1797         IEM_SAVE_FLAGS       A1, %2, %3
     1919        IEM_SAVE_FLAGS       A1, %2, %3, 0
    17981920        EPILOGUE_2_ARGS
    17991921ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    18031925        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    18041926        lock %1 dword [A0]
    1805         IEM_SAVE_FLAGS       A1, %2, %3
     1927        IEM_SAVE_FLAGS       A1, %2, %3, 0
    18061928        EPILOGUE_2_ARGS
    18071929ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
     
    18121934        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    18131935        %1      qword [A0]
    1814         IEM_SAVE_FLAGS       A1, %2, %3
     1936        IEM_SAVE_FLAGS       A1, %2, %3, 0
    18151937        EPILOGUE_2_ARGS
    18161938ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    18201942        IEM_MAYBE_LOAD_FLAGS A1, %2, %3, 0
    18211943        lock %1 qword [A0]
    1822         IEM_SAVE_FLAGS       A1, %2, %3
     1944        IEM_SAVE_FLAGS       A1, %2, %3, 0
    18231945        EPILOGUE_2_ARGS
    18241946ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
     
    19062028        %1      byte [A1], cl
    19072029 %endif
    1908         IEM_SAVE_FLAGS       A2, %2, %3
     2030        IEM_SAVE_FLAGS       A2, %2, %3, 0
     2031.zero_shift:
    19092032        EPILOGUE_3_ARGS
    19102033ENDPROC iemAImpl_ %+ %1 %+ _u8
     
    19202043        %1      word [A1], cl
    19212044 %endif
    1922         IEM_SAVE_FLAGS       A2, %2, %3
     2045        IEM_SAVE_FLAGS       A2, %2, %3, 0
    19232046        EPILOGUE_3_ARGS
    19242047ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    19342057        %1      dword [A1], cl
    19352058 %endif
    1936         IEM_SAVE_FLAGS       A2, %2, %3
     2059        IEM_SAVE_FLAGS       A2, %2, %3, 0
    19372060        EPILOGUE_3_ARGS
    19382061ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    19492072        %1      qword [A1], cl
    19502073  %endif
    1951         IEM_SAVE_FLAGS       A2, %2, %3
     2074        IEM_SAVE_FLAGS       A2, %2, %3, 0
    19522075        EPILOGUE_3_ARGS
    19532076ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    19562079%endmacro
    19572080
    1958 ;; @todo some questions wrt flags when the shift count is high according to intel docs...
    1959 IEMIMPL_SHIFT_OP rol, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF
    1960 IEMIMPL_SHIFT_OP ror, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF
    1961 IEMIMPL_SHIFT_OP rcl, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF
    1962 IEMIMPL_SHIFT_OP rcr, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF
    1963 IEMIMPL_SHIFT_OP shl, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), 0
    1964 IEMIMPL_SHIFT_OP shr, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), 0
    1965 IEMIMPL_SHIFT_OP sar, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), 0
     2081; These instructions will NOT modify flags if the masked shift count is zero
     2082; (the mask is 0x3f for 64-bit instructions and 0x1f for the others).  Thus,
     2083; we have to force load all modified and undefined.
     2084IEMIMPL_SHIFT_OP rol, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF | X86_EFL_OF
     2085IEMIMPL_SHIFT_OP ror, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF | X86_EFL_OF
     2086IEMIMPL_SHIFT_OP rcl, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF | X86_EFL_OF
     2087IEMIMPL_SHIFT_OP rcr, (X86_EFL_OF | X86_EFL_CF), 0,                                                   X86_EFL_CF | X86_EFL_OF
     2088IEMIMPL_SHIFT_OP shl, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), X86_EFL_STATUS_BITS
     2089IEMIMPL_SHIFT_OP shr, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), X86_EFL_STATUS_BITS
     2090IEMIMPL_SHIFT_OP sar, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), X86_EFL_STATUS_BITS
    19662091
    19672092
     
    19782103; @param        2       The modified flags.
    19792104; @param        3       The undefined flags.
     2105; @param        4       The force loaded flags.
    19802106;
    19812107; Makes ASSUMPTIONS about A0, A1, A2 and A3 assignments.
     
    19832109; @note the _intel and _amd variants are implemented in C.
    19842110;
    1985 %macro IEMIMPL_SHIFT_DBL_OP 3
     2111%macro IEMIMPL_SHIFT_DBL_OP 4
    19862112BEGINCODE
    19872113BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
    19882114        PROLOGUE_4_ARGS
    1989         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2115        ;IEM_LOAD_FLAGS      A3, %4, %3
     2116        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %4
    19902117 %ifdef ASM_CALL64_GCC
    19912118        xchg    A3, A2
     
    19962123        %1      [A2], A1_16, cl
    19972124 %endif
    1998         IEM_SAVE_FLAGS       A3, %2, %3
     2125        IEM_SAVE_FLAGS      A3, %2, %3, 0
    19992126        EPILOGUE_4_ARGS
    20002127ENDPROC iemAImpl_ %+ %1 %+ _u16
     
    20022129BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    20032130        PROLOGUE_4_ARGS
    2004         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2131        ;IEM_LOAD_FLAGS      A3, %4, %3
     2132        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %4
    20052133 %ifdef ASM_CALL64_GCC
    20062134        xchg    A3, A2
     
    20112139        %1      [A2], A1_32, cl
    20122140 %endif
    2013         IEM_SAVE_FLAGS       A3, %2, %3
     2141        IEM_SAVE_FLAGS      A3, %2, %3, 0
    20142142        EPILOGUE_4_ARGS
    20152143ENDPROC iemAImpl_ %+ %1 %+ _u32
     
    20182146BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
    20192147        PROLOGUE_4_ARGS
    2020         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2148        ;IEM_LOAD_FLAGS      A3, %4, %3
     2149        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %4
    20212150 %ifdef ASM_CALL64_GCC
    20222151        xchg    A3, A2
     
    20272156        %1      [A2], A1, cl
    20282157 %endif
    2029         IEM_SAVE_FLAGS       A3, %2, %3
     2158        IEM_SAVE_FLAGS      A3, %2, %3, 0
    20302159        EPILOGUE_4_ARGS_EX 12
    20312160ENDPROC iemAImpl_ %+ %1 %+ _u64
     
    20342163%endmacro
    20352164
    2036 IEMIMPL_SHIFT_DBL_OP shld, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
    2037 IEMIMPL_SHIFT_DBL_OP shrd, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
     2165; These instructions will NOT modify flags if the masked shift count is zero
     2166; (the mask is 0x3f for 64-bit instructions and 0x1f for the others).  Thus,
     2167; we have to force load all modified and undefined.
     2168IEMIMPL_SHIFT_DBL_OP shld, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), X86_EFL_STATUS_BITS
     2169IEMIMPL_SHIFT_DBL_OP shrd, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF), X86_EFL_STATUS_BITS
    20382170
    20392171
     
    20632195BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8 %+ %4, 12
    20642196        PROLOGUE_3_ARGS
    2065         IEM_MAYBE_LOAD_FLAGS                     A2, %2, %3
     2197        IEM_MAYBE_LOAD_FLAGS                     A2, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    20662198        mov     al, [A0]
    20672199        %1      A1_8
    20682200        mov     [A0], ax
    20692201 %if %5 != 1
    2070         IEM_SAVE_FLAGS                           A2, %2, %3
     2202        IEM_SAVE_FLAGS                           A2, %2, %3, 0
    20712203 %else
    2072         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A2, %2, X86_EFL_AF | X86_EFL_ZF, ax, 8, xAX
     2204        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A2, %2, X86_EFL_AF | X86_EFL_ZF, ax, 8, xAX ; intel
    20732205 %endif
    20742206        xor     eax, eax
     
    20782210BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ %4, 16
    20792211        PROLOGUE_4_ARGS
    2080         IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
     2212        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    20812213        mov     ax, [A0]
    20822214 %ifdef ASM_CALL64_GCC
     
    20912223 %endif
    20922224 %if %5 != 1
    2093         IEM_SAVE_FLAGS                           A3, %2, %3
     2225        IEM_SAVE_FLAGS                           A3, %2, %3, 0
    20942226 %else
    2095         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, ax, 16, xAX
     2227        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, ax, 16, xAX ; intel
    20962228 %endif
    20972229        xor     eax, eax
     
    21012233BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ %4, 16
    21022234        PROLOGUE_4_ARGS
    2103         IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
     2235        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    21042236        mov     eax, [A0]
    21052237 %ifdef ASM_CALL64_GCC
     
    21142246 %endif
    21152247 %if %5 != 1
    2116         IEM_SAVE_FLAGS                           A3, %2, %3
     2248        IEM_SAVE_FLAGS                           A3, %2, %3, 0
    21172249 %else
    2118         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, eax, 32, xAX
     2250        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, eax, 32, xAX ; intel
    21192251 %endif
    21202252        xor     eax, eax
     
    21252257BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ %4, 20
    21262258        PROLOGUE_4_ARGS
    2127         IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3
     2259        IEM_MAYBE_LOAD_FLAGS                     A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    21282260        mov     rax, [A0]
    21292261  %ifdef ASM_CALL64_GCC
     
    21382270  %endif
    21392271  %if %5 != 1
    2140         IEM_SAVE_FLAGS                           A3, %2, %3
     2272        IEM_SAVE_FLAGS                           A3, %2, %3, 0
    21412273  %else
    2142         IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, rax, 64, xAX
     2274        IEM_SAVE_FLAGS_ADJUST_AND_CALC_SF_PF     A3, %2, X86_EFL_AF | X86_EFL_ZF, rax, 64, xAX ; intel
    21432275  %endif
    21442276        xor     eax, eax
     
    22592391 %endif
    22602392
    2261         IEM_MAYBE_LOAD_FLAGS A2, %2, %3
     2393        IEM_MAYBE_LOAD_FLAGS A2, %2, %3, %3 ; Undefined flags may be passed thru (Intel)
    22622394        mov     ax, [A0]
    22632395        %1      A1_8
     
    22662398        IEM_ADJUST_FLAGS    A2, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    22672399 %else
    2268         IEM_SAVE_FLAGS      A2, %2, %3
     2400        IEM_SAVE_FLAGS      A2, %2, %3, 0
    22692401 %endif
    22702402        xor     eax, eax
     
    23252457 %endif
    23262458
    2327         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2459        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    23282460 %ifdef ASM_CALL64_GCC
    23292461        mov     T1, A2
     
    23442476        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    23452477 %else
    2346         IEM_SAVE_FLAGS      A3, %2, %3
     2478        IEM_SAVE_FLAGS      A3, %2, %3, 0
    23472479 %endif
    23482480        xor     eax, eax
     
    24112543 %endif
    24122544
    2413         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2545        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    24142546        mov     eax, [A0]
    24152547 %ifdef ASM_CALL64_GCC
     
    24312563        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    24322564 %else
    2433         IEM_SAVE_FLAGS      A3, %2, %3
     2565        IEM_SAVE_FLAGS      A3, %2, %3, 0
    24342566 %endif
    24352567        xor     eax, eax
     
    24992631  %endif
    25002632
    2501         IEM_MAYBE_LOAD_FLAGS A3, %2, %3
     2633        IEM_MAYBE_LOAD_FLAGS A3, %2, %3, %3 ; Undefined flags may be passed thru (AMD)
    25022634        mov     rax, [A0]
    25032635  %ifdef ASM_CALL64_GCC
     
    25192651        IEM_ADJUST_FLAGS    A3, X86_EFL_PF | X86_EFL_ZF | X86_EFL_SF, X86_EFL_AF
    25202652  %else
    2521         IEM_SAVE_FLAGS      A3, %2, %3
     2653        IEM_SAVE_FLAGS      A3, %2, %3, 0
    25222654  %endif
    25232655        xor     eax, eax
     
    45934725        movdqu  xmm1, [A1]
    45944726        ptest   xmm0, xmm1
    4595         IEM_SAVE_FLAGS A2, X86_EFL_STATUS_BITS, 0
     4727        IEM_SAVE_FLAGS A2, X86_EFL_ZF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_AF | X86_EFL_PF | X86_EFL_SF
    45964728
    45974729        IEMIMPL_SSE_EPILOGUE
     
    46064738        vmovdqu ymm1, [A1]
    46074739        vptest  ymm0, ymm1
    4608         IEM_SAVE_FLAGS A2, X86_EFL_STATUS_BITS, 0
     4740        IEM_SAVE_FLAGS A2, X86_EFL_ZF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_AF | X86_EFL_PF | X86_EFL_SF
    46094741
    46104742        IEMIMPL_SSE_EPILOGUE
     
    56405772        call    T1
    56415773
    5642         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     5774        IEM_SAVE_FLAGS A1, X86_EFL_CF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF, 0, X86_EFL_AF | X86_EFL_PF
    56435775        mov    [T2], ecx
    56445776
     
    56875819
    56885820        pop     xDX
    5689         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     5821        IEM_SAVE_FLAGS A1, X86_EFL_CF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF, 0, X86_EFL_AF | X86_EFL_PF
    56905822        mov    [T2], ecx
    56915823
     
    57295861        call    T1
    57305862
    5731         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     5863        IEM_SAVE_FLAGS A1, X86_EFL_CF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF, 0, X86_EFL_AF | X86_EFL_PF
    57325864        movdqu  [A0], xmm0
    57335865
     
    57755907
    57765908        pop     xDX
    5777         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     5909        IEM_SAVE_FLAGS A1, X86_EFL_CF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF, 0, X86_EFL_AF | X86_EFL_PF
    57785910        movdqu  [A0], xmm0
    57795911
     
    62956427        movdqu  xmm1, [A3]
    62966428        ucomiss xmm0, xmm1
    6297         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6429        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    62986430
    62996431        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    63106442        movdqu  xmm1, [A3]
    63116443        vucomiss xmm0, xmm1
    6312         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6444        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    63136445
    63146446        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    63346466        movdqu  xmm1, [A3]
    63356467        ucomisd xmm0, xmm1
    6336         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6468        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    63376469
    63386470        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    63496481        movdqu  xmm1, [A3]
    63506482        vucomisd xmm0, xmm1
    6351         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6483        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    63526484
    63536485        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    63726504        movdqu  xmm1, [A3]
    63736505        comiss xmm0, xmm1
    6374         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6506        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    63756507
    63766508        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    63876519        movdqu  xmm1, [A3]
    63886520        vcomiss xmm0, xmm1
    6389         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6521        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    63906522
    63916523        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    64116543        movdqu  xmm1, [A3]
    64126544        comisd xmm0, xmm1
    6413         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6545        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    64146546
    64156547        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    64266558        movdqu  xmm1, [A3]
    64276559        vcomisd xmm0, xmm1
    6428         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6560        IEM_SAVE_FLAGS A1, X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF
    64296561
    64306562        SSE_ST_FXSTATE_MXCSR_ONLY_NO_FXSTATE A0
     
    66966828        %1      %2
    66976829        mov     [A0], %2
    6698         IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
     6830        IEM_SAVE_FLAGS A1, X86_EFL_CF, 0, X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF
    66996831
    67006832        EPILOGUE_2_ARGS
     
    67896921        %1      A1_32, [A0]
    67906922        mov     [A0], A1_32
    6791         IEM_SAVE_FLAGS A2, %2, 0
     6923        IEM_SAVE_FLAGS A2, %2, 0, 0
    67926924
    67936925        EPILOGUE_4_ARGS
     
    68096941        %1      A1, [A0]
    68106942        mov     [A0], A1
    6811         IEM_SAVE_FLAGS A2, %2, 0
     6943        IEM_SAVE_FLAGS A2, %2, 0, 0
    68126944
    68136945        EPILOGUE_4_ARGS
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r103909 r104051  
    13981398# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    13991399
     1400#endif /* !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) */
    14001401
    14011402/*
     
    14301431    } while (0)
    14311432
    1432 
    14331433/*
    14341434 * BSF - first (least significant) bit set
    14351435 */
     1436#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    14361437IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    14371438{
    14381439    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU64(uSrc));
    14391440}
     1441#endif
    14401442
    14411443IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    14491451}
    14501452
    1451 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1452 
     1453#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    14531454IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    14541455{
    14551456    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU32(uSrc));
    14561457}
     1458#endif
    14571459
    14581460IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     
    14671469
    14681470
     1471#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    14691472IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    14701473{
    14711474    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU16(uSrc));
    14721475}
     1476#endif
    14731477
    14741478IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     
    14821486}
    14831487
    1484 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    14851488
    14861489
     
    14881491 * BSR - last (most significant) bit set
    14891492 */
     1493#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    14901494IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    14911495{
    14921496    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU64(uSrc));
    14931497}
     1498#endif
    14941499
    14951500IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    15031508}
    15041509
    1505 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1506 
     1510
     1511#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    15071512IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    15081513{
    15091514    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU32(uSrc));
    15101515}
     1516#endif
    15111517
    15121518IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     
    15211527
    15221528
     1529#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    15231530IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    15241531{
    15251532    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU16(uSrc));
    15261533}
     1534#endif
    15271535
    15281536IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     
    15351543    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitLastSetU16(uSrc));
    15361544}
    1537 
    1538 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    15391545
    15401546
     
    15691575 * LZCNT - count leading zero bits.
    15701576 */
     1577#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    15711578IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    15721579{
    15731580    iemAImpl_lzcnt_u64_intel(puDst, uSrc, pfEFlags);
    15741581}
     1582#endif
    15751583
    15761584IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    15841592}
    15851593
    1586 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1587 
     1594
     1595#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    15881596IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    15891597{
    15901598    iemAImpl_lzcnt_u32_intel(puDst, uSrc, pfEFlags);
    15911599}
     1600#endif
    15921601
    15931602IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     
    16021611
    16031612
     1613#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    16041614IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    16051615{
    16061616    iemAImpl_lzcnt_u16_intel(puDst, uSrc, pfEFlags);
    16071617}
     1618#endif
    16081619
    16091620IEM_DECL_IMPL_DEF(void, iemAImpl_lzcnt_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     
    16161627    SET_BIT_CNT_SEARCH_RESULT_AMD(puDst, uSrc, pfEFlags, ASMCountLeadingZerosU16(uSrc));
    16171628}
    1618 
    1619 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    16201629
    16211630
     
    16231632 * TZCNT - count leading zero bits.
    16241633 */
     1634#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    16251635IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    16261636{
    16271637    iemAImpl_tzcnt_u64_intel(puDst, uSrc, pfEFlags);
    16281638}
     1639#endif
    16291640
    16301641IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    16381649}
    16391650
    1640 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1641 
     1651
     1652#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    16421653IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    16431654{
    16441655    iemAImpl_tzcnt_u32_intel(puDst, uSrc, pfEFlags);
    16451656}
     1657#endif
    16461658
    16471659IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     
    16561668
    16571669
     1670#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    16581671IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    16591672{
    16601673    iemAImpl_tzcnt_u16_intel(puDst, uSrc, pfEFlags);
    16611674}
     1675#endif
    16621676
    16631677IEM_DECL_IMPL_DEF(void, iemAImpl_tzcnt_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     
    16711685}
    16721686
    1673 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    1674 #endif /* !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) */
     1687
    16751688
    16761689/*
  • trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp

    r103100 r104051  
    22502250}
    22512251
     2252
     2253typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHG8B,(uint64_t *, PRTUINT64U, PRTUINT64U, uint32_t *));
     2254
     2255static uint64_t CmpXchg8bBench(uint32_t cIterations, FNIEMAIMPLCMPXCHG8B *pfn, uint64_t const uDstValue,
     2256                               uint64_t const uOldValue, uint64_t const uNewValue, uint32_t const fEflIn)
     2257{
     2258    cIterations /= 4;
     2259    RTThreadYield();
     2260    uint64_t const nsStart = RTTimeNanoTS();
     2261    for (uint32_t i = 0; i < cIterations; i++)
     2262    {
     2263        RTUINT64U uA, uB;
     2264        uint32_t fEfl    = fEflIn;
     2265        uint64_t uDst    = uDstValue;
     2266        uB.u             = uNewValue;
     2267        uA.u             = uOldValue;
     2268        pfn(&uDst, &uA, &uB, &fEfl);
     2269
     2270        fEfl = fEflIn;
     2271        uDst = uDstValue;
     2272        uB.u = uNewValue;
     2273        uA.u = uOldValue;
     2274        pfn(&uDst, &uA, &uB, &fEfl);
     2275
     2276        fEfl = fEflIn;
     2277        uDst = uDstValue;
     2278        uB.u = uNewValue;
     2279        uA.u = uOldValue;
     2280        pfn(&uDst, &uA, &uB, &fEfl);
     2281
     2282        fEfl = fEflIn;
     2283        uDst = uDstValue;
     2284        uB.u = uNewValue;
     2285        uA.u = uOldValue;
     2286        pfn(&uDst, &uA, &uB, &fEfl);
     2287    }
     2288    return RTTimeNanoTS() - nsStart;
     2289}
     2290
    22522291static void CmpXchg8bTest(void)
    22532292{
    2254     typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHG8B,(uint64_t *, PRTUINT64U, PRTUINT64U, uint32_t *));
    22552293    static struct
    22562294    {
     
    23032341                             (fEflIn & ~X86_EFL_ZF), uExpect, uExpect, EFlagsDiff(fEfl, fEflIn & ~X86_EFL_ZF));
    23042342            RTTEST_CHECK(g_hTest, uB.u == uNewValue);
     2343
     2344            if (iTest == 2 && g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0)
     2345            {
     2346                uint32_t cIterations = EstimateIterations(_64K, CmpXchg8bBench(_64K, s_aFuncs[iFn].pfn,
     2347                                                                               uOldValue, uOldValue, uNewValue, fEflIn));
     2348                uint64_t cNsRealRun  = CmpXchg8bBench(cIterations, s_aFuncs[iFn].pfn, uOldValue, uOldValue, uNewValue, fEflIn);
     2349                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL,
     2350                             "%s-positive", s_aFuncs[iFn].pszName);
     2351
     2352                cIterations = EstimateIterations(_64K, CmpXchg8bBench(_64K, s_aFuncs[iFn].pfn,
     2353                                                                      ~uOldValue, uOldValue, uNewValue, fEflIn));
     2354                cNsRealRun  = CmpXchg8bBench(cIterations, s_aFuncs[iFn].pfn, ~uOldValue, uOldValue, uNewValue, fEflIn);
     2355                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL,
     2356                             "%s-negative", s_aFuncs[iFn].pszName);
     2357            }
    23052358        }
    23062359    }
     
    24232476#endif
    24242477
    2425 #define TEST_SHIFT_DBL(a_cBits, a_Type, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
     2478#define TEST_SHIFT_DBL(a_cBits, a_uType, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
    24262479TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLSHIFTDBLU ## a_cBits); \
    24272480\
     
    24352488\
    24362489GEN_SHIFT_DBL(a_cBits, a_Fmt, a_TestType, a_aSubTests) \
     2490\
     2491static uint64_t ShiftDblU ## a_cBits ## Bench(uint32_t cIterations, PFNIEMAIMPLSHIFTDBLU ## a_cBits pfn, a_TestType const *pEntry) \
     2492{ \
     2493    uint32_t const fEflIn = pEntry->fEflIn; \
     2494    a_uType  const uDstIn = pEntry->uDstIn; \
     2495    a_uType  const uSrcIn = pEntry->uSrcIn; \
     2496    a_uType  const cShift = pEntry->uMisc; \
     2497    cIterations /= 4; \
     2498    RTThreadYield(); \
     2499    uint64_t const nsStart     = RTTimeNanoTS(); \
     2500    for (uint32_t i = 0; i < cIterations; i++) \
     2501    { \
     2502        uint32_t fBenchEfl = fEflIn; \
     2503        a_uType  uBenchDst = uDstIn;  \
     2504        pfn(&uBenchDst, uSrcIn, cShift, &fBenchEfl); \
     2505        \
     2506        fBenchEfl = fEflIn; \
     2507        uBenchDst = uDstIn;  \
     2508        pfn(&uBenchDst, uSrcIn, cShift, &fBenchEfl); \
     2509        \
     2510        fBenchEfl = fEflIn; \
     2511        uBenchDst = uDstIn;  \
     2512        pfn(&uBenchDst, uSrcIn, cShift, &fBenchEfl); \
     2513        \
     2514        fBenchEfl = fEflIn; \
     2515        uBenchDst = uDstIn;  \
     2516        pfn(&uBenchDst, uSrcIn, cShift, &fBenchEfl); \
     2517    } \
     2518    return RTTimeNanoTS() - nsStart; \
     2519} \
    24372520\
    24382521static void ShiftDblU ## a_cBits ## Test(void) \
     
    24522535            { \
    24532536                uint32_t fEfl = paTests[iTest].fEflIn; \
    2454                 a_Type   uDst = paTests[iTest].uDstIn; \
     2537                a_uType  uDst = paTests[iTest].uDstIn; \
    24552538                pfn(&uDst, paTests[iTest].uSrcIn, paTests[iTest].uMisc, &fEfl); \
    24562539                if (   uDst != paTests[iTest].uDstOut \
     
    24702553                } \
    24712554            } \
     2555            \
     2556            /* Benchmark if all succeeded. */ \
     2557            if (g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0) \
     2558            { \
     2559                uint32_t const iTest       = cTests / 2; \
     2560                uint32_t const cIterations = EstimateIterations(_64K, ShiftDblU ## a_cBits ## Bench(_64K, pfn, &paTests[iTest])); \
     2561                uint64_t const cNsRealRun  = ShiftDblU ## a_cBits ## Bench(cIterations, pfn, &paTests[iTest]); \
     2562                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL, \
     2563                             "%s%s", a_aSubTests[iFn].pszName, iVar ? "-native" : ""); \
     2564            } \
     2565            \
     2566            /* Next variation is native. */ \
    24722567            pfn = a_aSubTests[iFn].pfnNative; \
    24732568        } \
     
    25432638#endif
    25442639
    2545 #define TEST_UNARY(a_cBits, a_Type, a_Fmt, a_TestType, a_SubTestType) \
     2640#define TEST_UNARY(a_cBits, a_uType, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
    25462641TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLUNARYU ## a_cBits); \
    2547 static a_SubTestType g_aUnaryU ## a_cBits [] = \
     2642static a_SubTestType a_aSubTests[] = \
    25482643{ \
    25492644    ENTRY_BIN(inc_u ## a_cBits), \
     
    25572652}; \
    25582653\
    2559 GEN_UNARY(a_cBits, a_Type, a_Fmt, a_TestType, a_SubTestType) \
     2654GEN_UNARY(a_cBits, a_uType, a_Fmt, a_TestType, a_SubTestType) \
     2655\
     2656static uint64_t UnaryU ## a_cBits ## Bench(uint32_t cIterations, PFNIEMAIMPLUNARYU ## a_cBits pfn, a_TestType const *pEntry) \
     2657{ \
     2658    uint32_t const fEflIn  = pEntry->fEflIn; \
     2659    a_uType  const uDstIn  = pEntry->uDstIn; \
     2660    cIterations /= 4; \
     2661    RTThreadYield(); \
     2662    uint64_t const nsStart     = RTTimeNanoTS(); \
     2663    for (uint32_t i = 0; i < cIterations; i++) \
     2664    { \
     2665        uint32_t fBenchEfl = fEflIn; \
     2666        a_uType  uBenchDst = uDstIn;  \
     2667        pfn(&uBenchDst, &fBenchEfl); \
     2668        \
     2669        fBenchEfl = fEflIn; \
     2670        uBenchDst = uDstIn;  \
     2671        pfn(&uBenchDst, &fBenchEfl); \
     2672        \
     2673        fBenchEfl = fEflIn; \
     2674        uBenchDst = uDstIn;  \
     2675        pfn(&uBenchDst, &fBenchEfl); \
     2676        \
     2677        fBenchEfl = fEflIn; \
     2678        uBenchDst = uDstIn;  \
     2679        pfn(&uBenchDst, &fBenchEfl); \
     2680    } \
     2681    return RTTimeNanoTS() - nsStart; \
     2682} \
    25602683\
    25612684static void UnaryU ## a_cBits ## Test(void) \
    25622685{ \
    2563     for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aUnaryU ## a_cBits); iFn++) \
     2686    for (size_t iFn = 0; iFn < RT_ELEMENTS(a_aSubTests); iFn++) \
    25642687    { \
    2565         if (!SUBTEST_CHECK_IF_ENABLED_AND_DECOMPRESS(g_aUnaryU ## a_cBits[iFn])) \
     2688        if (!SUBTEST_CHECK_IF_ENABLED_AND_DECOMPRESS(a_aSubTests[iFn])) \
    25662689            continue; \
    2567         a_TestType const * const paTests = g_aUnaryU ## a_cBits[iFn].paTests; \
    2568         uint32_t const           cTests  = g_aUnaryU ## a_cBits[iFn].cTests; \
     2690        PFNIEMAIMPLUNARYU ## a_cBits const pfn     = a_aSubTests[iFn].pfn; \
     2691        a_TestType const * const           paTests = a_aSubTests[iFn].paTests; \
     2692        uint32_t const                     cTests  = a_aSubTests[iFn].cTests; \
    25692693        if (!cTests) RTTestSkipped(g_hTest, "no tests"); \
    25702694        for (uint32_t iTest = 0; iTest < cTests; iTest++ ) \
    25712695        { \
    25722696            uint32_t fEfl = paTests[iTest].fEflIn; \
    2573             a_Type   uDst = paTests[iTest].uDstIn; \
    2574             g_aUnaryU ## a_cBits[iFn].pfn(&uDst, &fEfl); \
     2697            a_uType  uDst = paTests[iTest].uDstIn; \
     2698            pfn(&uDst, &fEfl); \
    25752699            if (   uDst != paTests[iTest].uDstOut \
    25762700                || fEfl != paTests[iTest].fEflOut) \
     
    25832707                 *g_pu ## a_cBits  = paTests[iTest].uDstIn; \
    25842708                 *g_pfEfl          = paTests[iTest].fEflIn; \
    2585                  g_aUnaryU ## a_cBits[iFn].pfn(g_pu ## a_cBits, g_pfEfl); \
     2709                 pfn(g_pu ## a_cBits, g_pfEfl); \
    25862710                 RTTEST_CHECK(g_hTest, *g_pu ## a_cBits == paTests[iTest].uDstOut); \
    25872711                 RTTEST_CHECK(g_hTest, *g_pfEfl == paTests[iTest].fEflOut); \
    25882712            } \
    25892713        } \
    2590         FREE_DECOMPRESSED_TESTS(g_aUnaryU ## a_cBits[iFn]); \
     2714        \
     2715        if (g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0) \
     2716        { \
     2717            uint32_t const iTest       = cTests / 2; \
     2718            uint32_t const cIterations = EstimateIterations(_64K, UnaryU ## a_cBits ## Bench(_64K, pfn, &paTests[iTest])); \
     2719            uint64_t const cNsRealRun  = UnaryU ## a_cBits ## Bench(cIterations, pfn, &paTests[iTest]); \
     2720            RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL, "%s", a_aSubTests[iFn].pszName); \
     2721        } \
     2722        \
     2723        FREE_DECOMPRESSED_TESTS(a_aSubTests[iFn]); \
    25912724    } \
    25922725}
    2593 TEST_UNARY(8,  uint8_t,  "%#04RX8",   BINU8_TEST_T,  INT_UNARY_U8_T)
    2594 TEST_UNARY(16, uint16_t, "%#06RX16",  BINU16_TEST_T, INT_UNARY_U16_T)
    2595 TEST_UNARY(32, uint32_t, "%#010RX32", BINU32_TEST_T, INT_UNARY_U32_T)
    2596 TEST_UNARY(64, uint64_t, "%#018RX64", BINU64_TEST_T, INT_UNARY_U64_T)
     2726TEST_UNARY(8,  uint8_t,  "%#04RX8",   BINU8_TEST_T,  INT_UNARY_U8_T,  g_aUnaryU8)
     2727TEST_UNARY(16, uint16_t, "%#06RX16",  BINU16_TEST_T, INT_UNARY_U16_T, g_aUnaryU16)
     2728TEST_UNARY(32, uint32_t, "%#010RX32", BINU32_TEST_T, INT_UNARY_U32_T, g_aUnaryU32)
     2729TEST_UNARY(64, uint64_t, "%#018RX64", BINU64_TEST_T, INT_UNARY_U64_T, g_aUnaryU64)
    25972730
    25982731#ifdef TSTIEMAIMPL_WITH_GENERATOR
     
    26742807#endif
    26752808
    2676 #define TEST_SHIFT(a_cBits, a_Type, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
     2809#define TEST_SHIFT(a_cBits, a_uType, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
    26772810TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLSHIFTU ## a_cBits); \
    26782811static a_SubTestType a_aSubTests[] = \
     
    26852818    ENTRY_BIN_INTEL(rcl_u ## a_cBits, X86_EFL_OF), \
    26862819    ENTRY_BIN_AMD(  rcr_u ## a_cBits, X86_EFL_OF), \
    2687     ENTRY_BIN_INTEL(rcr_u ## a_cBits, X86_EFL_OF), \
     2820    ENTRY_BIN_INTEL(rcr_u ## a_cBits, X86_EFL_OF),  \
    26882821    ENTRY_BIN_AMD(  shl_u ## a_cBits, X86_EFL_OF | X86_EFL_AF), \
    26892822    ENTRY_BIN_INTEL(shl_u ## a_cBits, X86_EFL_OF | X86_EFL_AF), \
     
    26952828\
    26962829GEN_SHIFT(a_cBits, a_Fmt, a_TestType, a_aSubTests) \
     2830\
     2831static uint64_t ShiftU ## a_cBits ## Bench(uint32_t cIterations, PFNIEMAIMPLSHIFTU ## a_cBits pfn, a_TestType const *pEntry) \
     2832{ \
     2833    uint32_t const fEflIn = pEntry->fEflIn; \
     2834    a_uType  const uDstIn = pEntry->uDstIn; \
     2835    a_uType  const cShift = pEntry->uMisc; \
     2836    cIterations /= 4; \
     2837    RTThreadYield(); \
     2838    uint64_t const nsStart     = RTTimeNanoTS(); \
     2839    for (uint32_t i = 0; i < cIterations; i++) \
     2840    { \
     2841        uint32_t fBenchEfl = fEflIn; \
     2842        a_uType  uBenchDst = uDstIn;  \
     2843        pfn(&uBenchDst, cShift, &fBenchEfl); \
     2844        \
     2845        fBenchEfl = fEflIn; \
     2846        uBenchDst = uDstIn;  \
     2847        pfn(&uBenchDst, cShift, &fBenchEfl); \
     2848        \
     2849        fBenchEfl = fEflIn; \
     2850        uBenchDst = uDstIn;  \
     2851        pfn(&uBenchDst, cShift, &fBenchEfl); \
     2852        \
     2853        fBenchEfl = fEflIn; \
     2854        uBenchDst = uDstIn;  \
     2855        pfn(&uBenchDst, cShift, &fBenchEfl); \
     2856    } \
     2857    return RTTimeNanoTS() - nsStart; \
     2858} \
    26972859\
    26982860static void ShiftU ## a_cBits ## Test(void) \
     
    27122874            { \
    27132875                uint32_t fEfl = paTests[iTest].fEflIn; \
    2714                 a_Type   uDst = paTests[iTest].uDstIn; \
     2876                a_uType  uDst = paTests[iTest].uDstIn; \
    27152877                pfn(&uDst, paTests[iTest].uMisc, &fEfl); \
    27162878                if (   uDst != paTests[iTest].uDstOut \
     
    27302892                } \
    27312893            } \
     2894            \
     2895            /* Benchmark if all succeeded. */ \
     2896            if (g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0) \
     2897            { \
     2898                uint32_t const iTest       = cTests / 2; \
     2899                uint32_t const cIterations = EstimateIterations(_64K, ShiftU ## a_cBits ## Bench(_64K, pfn, &paTests[iTest])); \
     2900                uint64_t const cNsRealRun  = ShiftU ## a_cBits ## Bench(cIterations, pfn, &paTests[iTest]); \
     2901                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL, \
     2902                             "%s%s", a_aSubTests[iFn].pszName, iVar ? "-native" : ""); \
     2903            } \
     2904            \
     2905            /* Next variation is native. */ \
    27322906            pfn = a_aSubTests[iFn].pfnNative; \
    27332907        } \
     
    28533027#endif
    28543028
     3029static uint64_t MulDivU8Bench(uint32_t cIterations, PFNIEMAIMPLMULDIVU8 pfn, MULDIVU8_TEST_T const *pEntry)
     3030{
     3031    uint32_t const fEflIn = pEntry->fEflIn;
     3032    uint16_t const uDstIn = pEntry->uDstIn;
     3033    uint8_t  const uSrcIn  = pEntry->uSrcIn;
     3034    cIterations /= 4;
     3035    RTThreadYield();
     3036    uint64_t const nsStart     = RTTimeNanoTS();
     3037    for (uint32_t i = 0; i < cIterations; i++)
     3038    {
     3039        uint32_t fBenchEfl  = fEflIn;
     3040        uint16_t uBenchDst = uDstIn;
     3041        pfn(&uBenchDst, uSrcIn, &fBenchEfl);
     3042
     3043        fBenchEfl = fEflIn;
     3044        uBenchDst = uDstIn;
     3045        pfn(&uBenchDst, uSrcIn, &fBenchEfl);
     3046
     3047        fBenchEfl = fEflIn;
     3048        uBenchDst = uDstIn;
     3049        pfn(&uBenchDst, uSrcIn, &fBenchEfl);
     3050
     3051        fBenchEfl = fEflIn;
     3052        uBenchDst = uDstIn;
     3053        pfn(&uBenchDst, uSrcIn, &fBenchEfl);
     3054    }
     3055    return RTTimeNanoTS() - nsStart;
     3056}
     3057
    28553058static void MulDivU8Test(void)
    28563059{
    28573060    for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aMulDivU8); iFn++)
    28583061    {
    2859         if (!SUBTEST_CHECK_IF_ENABLED_AND_DECOMPRESS(g_aMulDivU8[iFn])) \
    2860             continue; \
     3062        if (!SUBTEST_CHECK_IF_ENABLED_AND_DECOMPRESS(g_aMulDivU8[iFn]))
     3063            continue;
    28613064        MULDIVU8_TEST_T const * const paTests = g_aMulDivU8[iFn].paTests;
    28623065        uint32_t const                cTests  = g_aMulDivU8[iFn].cTests;
    28633066        uint32_t const                fEflIgn = g_aMulDivU8[iFn].uExtra;
    28643067        PFNIEMAIMPLMULDIVU8           pfn     = g_aMulDivU8[iFn].pfn;
    2865         uint32_t const                cVars   = COUNT_VARIATIONS(g_aMulDivU8[iFn]); \
     3068        uint32_t const                cVars   = COUNT_VARIATIONS(g_aMulDivU8[iFn]);
    28663069        if (!cTests) RTTestSkipped(g_hTest, "no tests");
    28673070        for (uint32_t iVar = 0; iVar < cVars; iVar++)
     
    28923095                }
    28933096            }
     3097
     3098            /* Benchmark if all succeeded. */
     3099            if (g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0)
     3100            {
     3101                uint32_t const iTest       = cTests / 2;
     3102                uint32_t const cIterations = EstimateIterations(_64K, MulDivU8Bench(_64K, pfn, &paTests[iTest]));
     3103                uint64_t const cNsRealRun  = MulDivU8Bench(cIterations, pfn, &paTests[iTest]);
     3104                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL,
     3105                             "%s%s", g_aMulDivU8[iFn].pszName, iVar ? "-native" : "");
     3106            }
     3107
     3108            /* Next variation is native. */
    28943109            pfn = g_aMulDivU8[iFn].pfnNative;
    28953110        }
    2896         FREE_DECOMPRESSED_TESTS(g_aMulDivU8[iFn]); \
     3111        FREE_DECOMPRESSED_TESTS(g_aMulDivU8[iFn]);
    28973112    }
    28983113}
     
    29863201#endif
    29873202
    2988 #define TEST_MULDIV(a_cBits, a_Type, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
     3203#define TEST_MULDIV(a_cBits, a_uType, a_Fmt, a_TestType, a_SubTestType, a_aSubTests) \
    29893204TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLMULDIVU ## a_cBits); \
    29903205static a_SubTestType a_aSubTests [] = \
     
    30013216\
    30023217GEN_MULDIV(a_cBits, a_Fmt, a_TestType, a_aSubTests) \
     3218\
     3219static uint64_t MulDivU ## a_cBits ## Bench(uint32_t cIterations, PFNIEMAIMPLMULDIVU ## a_cBits pfn, a_TestType const *pEntry) \
     3220{ \
     3221    uint32_t const fEflIn  = pEntry->fEflIn; \
     3222    a_uType  const uDst1In = pEntry->uDst1In; \
     3223    a_uType  const uDst2In = pEntry->uDst2In; \
     3224    a_uType  const uSrcIn  = pEntry->uSrcIn; \
     3225    cIterations /= 4; \
     3226    RTThreadYield(); \
     3227    uint64_t const nsStart     = RTTimeNanoTS(); \
     3228    for (uint32_t i = 0; i < cIterations; i++) \
     3229    { \
     3230        uint32_t fBenchEfl  = fEflIn; \
     3231        a_uType  uBenchDst1 = uDst1In;  \
     3232        a_uType  uBenchDst2 = uDst2In;  \
     3233        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3234        \
     3235        fBenchEfl  = fEflIn; \
     3236        uBenchDst1 = uDst1In; \
     3237        uBenchDst2 = uDst2In; \
     3238        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3239        \
     3240        fBenchEfl  = fEflIn; \
     3241        uBenchDst1 = uDst1In; \
     3242        uBenchDst2 = uDst2In; \
     3243        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3244        \
     3245        fBenchEfl  = fEflIn; \
     3246        uBenchDst1 = uDst1In; \
     3247        uBenchDst2 = uDst2In; \
     3248        pfn(&uBenchDst1, &uBenchDst2, uSrcIn, &fBenchEfl); \
     3249    } \
     3250    return RTTimeNanoTS() - nsStart; \
     3251} \
    30033252\
    30043253static void MulDivU ## a_cBits ## Test(void) \
     
    30193268            { \
    30203269                uint32_t fEfl  = paTests[iTest].fEflIn; \
    3021                 a_Type   uDst1 = paTests[iTest].uDst1In; \
    3022                 a_Type   uDst2 = paTests[iTest].uDst2In; \
     3270                a_uType  uDst1 = paTests[iTest].uDst1In; \
     3271                a_uType  uDst2 = paTests[iTest].uDst2In; \
    30233272                int rc = pfn(&uDst1, &uDst2, paTests[iTest].uSrcIn, &fEfl); \
    30243273                if (   uDst1 != paTests[iTest].uDst1Out \
     
    30483297                } \
    30493298            } \
     3299            \
     3300            /* Benchmark if all succeeded. */ \
     3301            if (g_cPicoSecBenchmark && RTTestSubErrorCount(g_hTest) == 0) \
     3302            { \
     3303                uint32_t const iTest       = cTests / 2; \
     3304                uint32_t const cIterations = EstimateIterations(_64K, MulDivU ## a_cBits ## Bench(_64K, pfn, &paTests[iTest])); \
     3305                uint64_t const cNsRealRun  = MulDivU ## a_cBits ## Bench(cIterations, pfn, &paTests[iTest]); \
     3306                RTTestValueF(g_hTest, cNsRealRun * 1000 / cIterations, RTTESTUNIT_PS_PER_CALL, \
     3307                             "%s%s", a_aSubTests[iFn].pszName, iVar ? "-native" : ""); \
     3308            } \
     3309            \
     3310            /* Next variation is native. */ \
    30503311            pfn = a_aSubTests[iFn].pfnNative; \
    30513312        } \
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