VirtualBox

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


Ignore:
Timestamp:
Mar 10, 2022 1:59:24 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Try deal with basic Intel/AMD EFLAGS difference for binary and div/mul operations (intel side). bugref:9898

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

Legend:

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

    r93964 r94156  
    711711};
    712712
     713/** Function table for the BSF instruction, AMD EFLAGS variant. */
     714IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsf_amd =
     715{
     716    NULL,  NULL,
     717    iemAImpl_bsf_u16_amd, NULL,
     718    iemAImpl_bsf_u32_amd, NULL,
     719    iemAImpl_bsf_u64_amd, NULL
     720};
     721
     722/** Function table for the BSF instruction, Intel EFLAGS variant. */
     723IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsf_intel =
     724{
     725    NULL,  NULL,
     726    iemAImpl_bsf_u16_intel, NULL,
     727    iemAImpl_bsf_u32_intel, NULL,
     728    iemAImpl_bsf_u64_intel, NULL
     729};
     730
     731/** EFLAGS variation selection table for the BSF instruction. */
     732IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_bsf_eflags[] =
     733{
     734    &g_iemAImpl_bsf,
     735    &g_iemAImpl_bsf_intel,
     736    &g_iemAImpl_bsf_amd,
     737    &g_iemAImpl_bsf,
     738};
     739
    713740/** Function table for the BSR instruction. */
    714741IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr =
     
    720747};
    721748
     749/** Function table for the BSR instruction, AMD EFLAGS variant. */
     750IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr_amd =
     751{
     752    NULL,  NULL,
     753    iemAImpl_bsr_u16_amd, NULL,
     754    iemAImpl_bsr_u32_amd, NULL,
     755    iemAImpl_bsr_u64_amd, NULL
     756};
     757
     758/** Function table for the BSR instruction, Intel EFLAGS variant. */
     759IEM_STATIC const IEMOPBINSIZES g_iemAImpl_bsr_intel =
     760{
     761    NULL,  NULL,
     762    iemAImpl_bsr_u16_intel, NULL,
     763    iemAImpl_bsr_u32_intel, NULL,
     764    iemAImpl_bsr_u64_intel, NULL
     765};
     766
     767/** EFLAGS variation selection table for the BSR instruction. */
     768IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_bsr_eflags[] =
     769{
     770    &g_iemAImpl_bsr,
     771    &g_iemAImpl_bsr_intel,
     772    &g_iemAImpl_bsr_amd,
     773    &g_iemAImpl_bsr,
     774};
     775
    722776/** Function table for the IMUL instruction. */
    723777IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two =
     
    727781    iemAImpl_imul_two_u32, NULL,
    728782    iemAImpl_imul_two_u64, NULL
     783};
     784
     785/** Function table for the IMUL instruction, AMD EFLAGS variant. */
     786IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two_amd =
     787{
     788    NULL,  NULL,
     789    iemAImpl_imul_two_u16_amd, NULL,
     790    iemAImpl_imul_two_u32_amd, NULL,
     791    iemAImpl_imul_two_u64_amd, NULL
     792};
     793
     794/** Function table for the IMUL instruction, Intel EFLAGS variant. */
     795IEM_STATIC const IEMOPBINSIZES g_iemAImpl_imul_two_intel =
     796{
     797    NULL,  NULL,
     798    iemAImpl_imul_two_u16_intel, NULL,
     799    iemAImpl_imul_two_u32_intel, NULL,
     800    iemAImpl_imul_two_u64_intel, NULL
     801};
     802
     803/** EFLAGS variation selection table for the IMUL instruction. */
     804IEM_STATIC const IEMOPBINSIZES * const g_iemAImpl_imul_two_eflags[] =
     805{
     806    &g_iemAImpl_imul_two,
     807    &g_iemAImpl_imul_two_intel,
     808    &g_iemAImpl_imul_two_amd,
     809    &g_iemAImpl_imul_two,
     810};
     811
     812/** EFLAGS variation selection table for the 16-bit IMUL instruction. */
     813IEM_STATIC PFNIEMAIMPLBINU16 const g_iemAImpl_imul_two_u16_eflags[] =
     814{
     815    iemAImpl_imul_two_u16,
     816    iemAImpl_imul_two_u16_intel,
     817    iemAImpl_imul_two_u16_amd,
     818    iemAImpl_imul_two_u16,
     819};
     820
     821/** EFLAGS variation selection table for the 32-bit IMUL instruction. */
     822IEM_STATIC PFNIEMAIMPLBINU32 const g_iemAImpl_imul_two_u32_eflags[] =
     823{
     824    iemAImpl_imul_two_u32,
     825    iemAImpl_imul_two_u32_intel,
     826    iemAImpl_imul_two_u32_amd,
     827    iemAImpl_imul_two_u32,
     828};
     829
     830/** EFLAGS variation selection table for the 64-bit IMUL instruction. */
     831IEM_STATIC PFNIEMAIMPLBINU64 const g_iemAImpl_imul_two_u64_eflags[] =
     832{
     833    iemAImpl_imul_two_u64,
     834    iemAImpl_imul_two_u64_intel,
     835    iemAImpl_imul_two_u64_amd,
     836    iemAImpl_imul_two_u64,
    729837};
    730838
     
    852960};
    853961
     962/** Function table for the MUL instruction, AMD EFLAGS variation. */
     963IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_mul_amd =
     964{
     965    iemAImpl_mul_u8_amd,
     966    iemAImpl_mul_u16_amd,
     967    iemAImpl_mul_u32_amd,
     968    iemAImpl_mul_u64_amd
     969};
     970
     971/** Function table for the MUL instruction, Intel EFLAGS variation. */
     972IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_mul_intel =
     973{
     974    iemAImpl_mul_u8_intel,
     975    iemAImpl_mul_u16_intel,
     976    iemAImpl_mul_u32_intel,
     977    iemAImpl_mul_u64_intel
     978};
     979
     980/** EFLAGS variation selection table for the MUL instruction. */
     981IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_mul_eflags[] =
     982{
     983    &g_iemAImpl_mul,
     984    &g_iemAImpl_mul_intel,
     985    &g_iemAImpl_mul_amd,
     986    &g_iemAImpl_mul,
     987};
     988
     989/** EFLAGS variation selection table for the 8-bit MUL instruction. */
     990IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_mul_u8_eflags[] =
     991{
     992    iemAImpl_mul_u8,
     993    iemAImpl_mul_u8_intel,
     994    iemAImpl_mul_u8_amd,
     995    iemAImpl_mul_u8
     996};
     997
     998
    854999/** Function table for the IMUL instruction working implicitly on rAX. */
    8551000IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul =
     
    8611006};
    8621007
     1008/** Function table for the IMUL instruction working implicitly on rAX, AMD EFLAGS variation. */
     1009IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul_amd =
     1010{
     1011    iemAImpl_imul_u8_amd,
     1012    iemAImpl_imul_u16_amd,
     1013    iemAImpl_imul_u32_amd,
     1014    iemAImpl_imul_u64_amd
     1015};
     1016
     1017/** Function table for the IMUL instruction working implicitly on rAX, Intel EFLAGS variation. */
     1018IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_imul_intel =
     1019{
     1020    iemAImpl_imul_u8_intel,
     1021    iemAImpl_imul_u16_intel,
     1022    iemAImpl_imul_u32_intel,
     1023    iemAImpl_imul_u64_intel
     1024};
     1025
     1026/** EFLAGS variation selection table for the IMUL instruction. */
     1027IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_imul_eflags[] =
     1028{
     1029    &g_iemAImpl_imul,
     1030    &g_iemAImpl_imul_intel,
     1031    &g_iemAImpl_imul_amd,
     1032    &g_iemAImpl_imul,
     1033};
     1034
     1035/** EFLAGS variation selection table for the 8-bit IMUL instruction. */
     1036IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_imul_u8_eflags[] =
     1037{
     1038    iemAImpl_imul_u8,
     1039    iemAImpl_imul_u8_intel,
     1040    iemAImpl_imul_u8_amd,
     1041    iemAImpl_imul_u8
     1042};
     1043
     1044
    8631045/** Function table for the DIV instruction. */
    8641046IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div =
     
    8701052};
    8711053
    872 /** Function table for the MUL instruction. */
     1054/** Function table for the DIV instruction, AMD EFLAGS variation. */
     1055IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div_amd =
     1056{
     1057    iemAImpl_div_u8_amd,
     1058    iemAImpl_div_u16_amd,
     1059    iemAImpl_div_u32_amd,
     1060    iemAImpl_div_u64_amd
     1061};
     1062
     1063/** Function table for the DIV instruction, Intel EFLAGS variation. */
     1064IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_div_intel =
     1065{
     1066    iemAImpl_div_u8_intel,
     1067    iemAImpl_div_u16_intel,
     1068    iemAImpl_div_u32_intel,
     1069    iemAImpl_div_u64_intel
     1070};
     1071
     1072/** EFLAGS variation selection table for the DIV instruction. */
     1073IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_div_eflags[] =
     1074{
     1075    &g_iemAImpl_div,
     1076    &g_iemAImpl_div_intel,
     1077    &g_iemAImpl_div_amd,
     1078    &g_iemAImpl_div,
     1079};
     1080
     1081/** EFLAGS variation selection table for the 8-bit DIV instruction. */
     1082IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_div_u8_eflags[] =
     1083{
     1084    iemAImpl_div_u8,
     1085    iemAImpl_div_u8_intel,
     1086    iemAImpl_div_u8_amd,
     1087    iemAImpl_div_u8
     1088};
     1089
     1090
     1091/** Function table for the IDIV instruction. */
    8731092IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv =
    8741093{
     
    8781097    iemAImpl_idiv_u64
    8791098};
     1099
     1100/** Function table for the IDIV instruction, AMD EFLAGS variation. */
     1101IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv_amd =
     1102{
     1103    iemAImpl_idiv_u8_amd,
     1104    iemAImpl_idiv_u16_amd,
     1105    iemAImpl_idiv_u32_amd,
     1106    iemAImpl_idiv_u64_amd
     1107};
     1108
     1109/** Function table for the IDIV instruction, Intel EFLAGS variation. */
     1110IEM_STATIC const IEMOPMULDIVSIZES g_iemAImpl_idiv_intel =
     1111{
     1112    iemAImpl_idiv_u8_intel,
     1113    iemAImpl_idiv_u16_intel,
     1114    iemAImpl_idiv_u32_intel,
     1115    iemAImpl_idiv_u64_intel
     1116};
     1117
     1118/** EFLAGS variation selection table for the IDIV instruction. */
     1119IEM_STATIC const IEMOPMULDIVSIZES * const g_iemAImpl_idiv_eflags[] =
     1120{
     1121    &g_iemAImpl_idiv,
     1122    &g_iemAImpl_idiv_intel,
     1123    &g_iemAImpl_idiv_amd,
     1124    &g_iemAImpl_idiv,
     1125};
     1126
     1127/** EFLAGS variation selection table for the 8-bit IDIV instruction. */
     1128IEM_STATIC PFNIEMAIMPLMULDIVU8 const g_iemAImpl_idiv_u8_eflags[] =
     1129{
     1130    iemAImpl_idiv_u8,
     1131    iemAImpl_idiv_u8_intel,
     1132    iemAImpl_idiv_u8_amd,
     1133    iemAImpl_idiv_u8
     1134};
     1135
    8801136
    8811137/** Function table for the SHLD instruction */
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r93906 r94156  
    1717
    1818
    19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    20 ;   Header Files                                                               ;
    21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     19;*********************************************************************************************************************************
     20;*  Header Files                                                                                                                 *
     21;*********************************************************************************************************************************
    2222%include "VBox/asmdefs.mac"
    2323%include "VBox/err.mac"
     
    2525
    2626
    27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    28 ;   Defined Constants And Macros                                               ;
    29 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     27;*********************************************************************************************************************************
     28;*  Defined Constants And Macros                                                                                                 *
     29;*********************************************************************************************************************************
    3030
    3131;;
     
    172172 %define T1_16      r11w
    173173 %define T1_8       r11b
     174
     175 %define T2         r10                 ; only AMD64
     176 %define T2_32      r10d
     177 %define T2_16      r10w
     178 %define T2_8       r10b
    174179
    175180%else
     
    306311%endmacro
    307312
     313;;
     314; Calculates the new EFLAGS based on the CPU EFLAGS and fixed clear and set bit masks.
     315;
     316; @remarks  Clobbers T0, T1, stack.
     317; @param        1       The register pointing to the EFLAGS.
     318; @param        2       The mask of modified flags to save.
     319; @param        3       Mask of additional flags to always clear
     320; @param        4       Mask of additional flags to always set.
     321;
     322%macro IEM_SAVE_AND_ADJUST_FLAGS 4
     323 %if (%2 | %3 | %4) != 0
     324        pushf
     325        pop     T1
     326        mov     T0_32, [%1]             ; load flags.
     327        and     T0_32, ~(%2 | %3)       ; clear the modified and always cleared flags.
     328        and     T1_32, (%2)             ; select the modified flags.
     329        or      T0_32, T1_32            ; combine the flags.
     330  %if (%4) != 0
     331        or      T0_32, %4               ; add the always set flags.
     332  %endif
     333        mov     [%1], T0_32             ; save the result.
     334 %endif
     335%endmacro
     336
     337;;
     338; Calculates the new EFLAGS using fixed clear and set bit masks.
     339;
     340; @remarks  Clobbers T0.
     341; @param        1       The register pointing to the EFLAGS.
     342; @param        2       Mask of additional flags to always clear
     343; @param        3       Mask of additional flags to always set.
     344;
     345%macro IEM_ADJUST_FLAGS 3
     346 %if (%2 | %3) != 0
     347        mov     T0_32, [%1]             ; Load flags.
     348  %if (%2) != 0
     349        and     T0_32, ~(%2)            ; Remove the always cleared flags.
     350  %endif
     351  %if (%3) != 0
     352        or      T0_32, %3               ; Add the always set flags.
     353  %endif
     354        mov     [%1], T0_32             ; Save the result.
     355 %endif
     356%endmacro
     357
     358;;
     359; Calculates the new EFLAGS using fixed clear and set bit masks.
     360;
     361; @remarks  Clobbers T0, %4.
     362; @param        1       The register pointing to the EFLAGS.
     363; @param        2       Mask of additional flags to always clear
     364; @param        3       Mask of additional flags to always set.
     365; @param        4       The (full) register containing the parity table index. Will be modified!
     366;
     367%macro IEM_ADJUST_FLAGS_WITH_PARITY 4
     368        mov     T0_32, [%1]                 ; Load flags.
     369        and     T0_32, ~(%2 | X86_EFL_PF)   ; Remove PF and the always cleared flags.
     370 %if (%3) != 0
     371        or      T0_32, %3                   ; Add the always set flags.
     372 %endif
     373        and     %4, 0xff
     374 %ifdef RT_ARCH_AMD64
     375        lea     T2, [NAME(g_afParity) xWrtRIP]
     376        or      T0_8, [T2 + %4]
     377 %else
     378        or      T0_8, [NAME(g_afParity) + %4]
     379 %endif
     380        mov     [%1], T0_32             ; Save the result.
     381%endmacro
     382
     383
     384;*********************************************************************************************************************************
     385;*  External Symbols                                                                                                             *
     386;*********************************************************************************************************************************
     387extern NAME(g_afParity)
     388
    308389
    309390;;
     
    494575; the source register operand in A1 and a pointer to eflags in A2.
    495576;
     577; In the ZF case the destination register is 'undefined', however it seems that
     578; both AMD and Intel just leaves it as is.  The undefined EFLAGS differs between
     579; AMD and Intel and accoridng to https://www.sandpile.org/x86/flags.htm between
     580; Intel microarchitectures.  We only implement 'intel' and 'amd' variation with
     581; the behaviour of more recent CPUs (Intel 10980X and AMD 3990X).
     582;
    496583; @param        1       The instruction mnemonic.
    497584; @param        2       The modified flags.
     
    511598ENDPROC iemAImpl_ %+ %1 %+ _u16
    512599
     600BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _intel, 12
     601        PROLOGUE_3_ARGS
     602        %1      T1_16, A1_16
     603        jz      .unchanged_dst
     604        mov     [A0], T1_16
     605        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     606        EPILOGUE_3_ARGS
     607.unchanged_dst:
     608        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     609        EPILOGUE_3_ARGS
     610ENDPROC iemAImpl_ %+ %1 %+ _u16_intel
     611
     612BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16 %+ _amd, 12
     613        PROLOGUE_3_ARGS
     614        %1      T0_16, A1_16
     615        jz      .unchanged_dst
     616        mov     [A0], T0_16
     617.unchanged_dst:
     618        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     619        EPILOGUE_3_ARGS
     620ENDPROC iemAImpl_ %+ %1 %+ _u16_amd
     621
     622
    513623BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
    514624        PROLOGUE_3_ARGS
     
    522632ENDPROC iemAImpl_ %+ %1 %+ _u32
    523633
     634BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _intel, 12
     635        PROLOGUE_3_ARGS
     636        %1      T1_32, A1_32
     637        jz      .unchanged_dst
     638        mov     [A0], T1_32
     639        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     640        EPILOGUE_3_ARGS
     641.unchanged_dst:
     642        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     643        EPILOGUE_3_ARGS
     644ENDPROC iemAImpl_ %+ %1 %+ _u32_intel
     645
     646BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32 %+ _amd, 12
     647        PROLOGUE_3_ARGS
     648        %1      T0_32, A1_32
     649        jz      .unchanged_dst
     650        mov     [A0], T0_32
     651.unchanged_dst:
     652        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     653        EPILOGUE_3_ARGS
     654ENDPROC iemAImpl_ %+ %1 %+ _u32_amd
     655
     656
    524657 %ifdef RT_ARCH_AMD64
     658
    525659BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
    526660        PROLOGUE_3_ARGS
     
    533667        EPILOGUE_3_ARGS_EX 8
    534668ENDPROC iemAImpl_ %+ %1 %+ _u64
     669
     670BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _intel, 16
     671        PROLOGUE_3_ARGS
     672        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     673        %1      T1, A1
     674        jz      .unchanged_dst
     675        mov     [A0], T1
     676        IEM_ADJUST_FLAGS_WITH_PARITY    A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF | X86_EFL_ZF, 0, T1
     677        EPILOGUE_3_ARGS
     678.unchanged_dst:
     679        IEM_ADJUST_FLAGS                A2, X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_CF, X86_EFL_ZF | X86_EFL_PF
     680        EPILOGUE_3_ARGS
     681ENDPROC iemAImpl_ %+ %1 %+ _u64_intel
     682
     683BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64 %+ _amd, 16
     684        PROLOGUE_3_ARGS
     685        %1      T0, A1
     686        jz      .unchanged_dst
     687        mov     [A0], T0
     688.unchanged_dst:
     689        IEM_SAVE_AND_ADJUST_FLAGS       A2, %2, 0, 0    ; Only the ZF flag is modified on AMD Zen 2.
     690        EPILOGUE_3_ARGS_EX 8
     691ENDPROC iemAImpl_ %+ %1 %+ _u64_amd
     692
    535693 %endif ; RT_ARCH_AMD64
    536694%endmacro
     695
    537696IEMIMPL_BIT_OP bsf, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
    538697IEMIMPL_BIT_OP bsr, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
     
    544703;
    545704BEGINCODE
     705BEGINPROC_FASTCALL iemAImpl_imul_two_u16_intel, 12
     706BEGINPROC_FASTCALL iemAImpl_imul_two_u16_amd, 12
    546707BEGINPROC_FASTCALL iemAImpl_imul_two_u16, 12
    547708        PROLOGUE_3_ARGS
     
    553714ENDPROC iemAImpl_imul_two_u16
    554715
     716BEGINPROC_FASTCALL iemAImpl_imul_two_u32_intel, 12
     717BEGINPROC_FASTCALL iemAImpl_imul_two_u32_amd, 12
    555718BEGINPROC_FASTCALL iemAImpl_imul_two_u32, 12
    556719        PROLOGUE_3_ARGS
     
    563726
    564727%ifdef RT_ARCH_AMD64
     728BEGINPROC_FASTCALL iemAImpl_imul_two_u64_intel, 16
     729BEGINPROC_FASTCALL iemAImpl_imul_two_u64_amd, 16
    565730BEGINPROC_FASTCALL iemAImpl_imul_two_u64, 16
    566731        PROLOGUE_3_ARGS
     
    13221487%macro IEMIMPL_MUL_OP 3
    13231488BEGINCODE
     1489BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_intel, 12
     1490BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_amd, 12
    13241491BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
    13251492        PROLOGUE_3_ARGS
     
    13331500ENDPROC iemAImpl_ %+ %1 %+ _u8
    13341501
     1502BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_intel, 16
     1503BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_amd, 16
    13351504BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
    13361505        PROLOGUE_4_ARGS
     
    13521521ENDPROC iemAImpl_ %+ %1 %+ _u16
    13531522
     1523BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_intel, 16
     1524BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_amd, 16
    13541525BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    13551526        PROLOGUE_4_ARGS
     
    13721543
    13731544 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp.
     1545BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_intel, 20
     1546BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_amd, 20
    13741547BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
    13751548        PROLOGUE_4_ARGS
     
    14521625%macro IEMIMPL_DIV_OP 4
    14531626BEGINCODE
     1627BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_intel, 12
     1628BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_amd, 12
    14541629BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
    14551630        PROLOGUE_3_ARGS
     
    15131688ENDPROC iemAImpl_ %+ %1 %+ _u8
    15141689
     1690BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_intel, 16
     1691BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_amd, 16
    15151692BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
    15161693        PROLOGUE_4_ARGS
     
    15871764ENDPROC iemAImpl_ %+ %1 %+ _u16
    15881765
     1766BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_intel, 16
     1767BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_amd, 16
    15891768BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    15901769        PROLOGUE_4_ARGS
     
    16701849
    16711850 %ifdef RT_ARCH_AMD64 ; The 32-bit host version lives in IEMAllAImplC.cpp.
     1851BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_intel, 20
     1852BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_amd, 20
    16721853BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
    16731854        PROLOGUE_4_ARGS
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r93942 r94156  
    143143*   Global Variables                                                                                                             *
    144144*********************************************************************************************************************************/
    145 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    146145/**
    147146 * Parity calculation table.
     147 *
     148 * This is also used by iemAllAImpl.asm.
    148149 *
    149150 * The generator code:
     
    180181 * @endcode
    181182 */
    182 static uint8_t const g_afParity[256] =
     183uint8_t const g_afParity[256] =
    183184{
    184185    /* 0000 = 00000000b */ X86_EFL_PF,
     
    439440    /* 0xff = 11111111b */ X86_EFL_PF,
    440441};
    441 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */
    442 
    443442
    444443
     
    11641163
    11651164/*
     1165 * Helpers for BSR and BSF.
     1166 *
     1167 * Note! "undefined" flags: OF, SF, AF, PF, CF.
     1168 *       Intel behavior modelled on 10980xe, AMD on 3990X.  Other marchs may
     1169 *       produce different result (see https://www.sandpile.org/x86/flags.htm),
     1170 *       but we restrict ourselves to emulating these recent marchs.
     1171 */
     1172#define SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlag, a_iBit) do { \
     1173        unsigned iBit = (a_iBit); \
     1174        uint32_t fEfl = *pfEFlags & ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF); \
     1175        if (iBit) \
     1176        { \
     1177            *puDst    = --iBit; \
     1178            fEfl     |= g_afParity[iBit]; \
     1179        } \
     1180        else \
     1181            fEfl     |= X86_EFL_ZF | X86_EFL_PF; \
     1182        *pfEFlags = fEfl; \
     1183    } while (0)
     1184#define SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlag, a_iBit) do { \
     1185        unsigned const iBit = (a_iBit); \
     1186        if (iBit) \
     1187        { \
     1188            *puDst     = iBit - 1; \
     1189            *pfEFlags &= ~X86_EFL_ZF; \
     1190        } \
     1191        else \
     1192            *pfEFlags |= X86_EFL_ZF; \
     1193    } while (0)
     1194
     1195
     1196/*
    11661197 * BSF - first (least significant) bit set
    11671198 */
    1168 
    11691199IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    11701200{
    1171     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1172     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1173     unsigned iBit = ASMBitFirstSetU64(uSrc);
    1174     if (iBit)
    1175     {
    1176         *puDst     = iBit - 1;
    1177         *pfEFlags &= ~X86_EFL_ZF;
    1178     }
    1179     else
    1180         *pfEFlags |= X86_EFL_ZF;
     1201    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU64(uSrc));
     1202}
     1203
     1204IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     1205{
     1206    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU64(uSrc));
     1207}
     1208
     1209IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u64_amd,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     1210{
     1211    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitFirstSetU64(uSrc));
    11811212}
    11821213
     
    11851216IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    11861217{
    1187     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1188     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1189     unsigned iBit = ASMBitFirstSetU32(uSrc);
    1190     if (iBit)
    1191     {
    1192         *puDst     = iBit - 1;
    1193         *pfEFlags &= ~X86_EFL_ZF;
    1194     }
    1195     else
    1196         *pfEFlags |= X86_EFL_ZF;
     1218    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU32(uSrc));
     1219}
     1220
     1221IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1222{
     1223    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU32(uSrc));
     1224}
     1225
     1226IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u32_amd,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1227{
     1228    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitFirstSetU32(uSrc));
    11971229}
    11981230
     
    12001232IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    12011233{
    1202     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1203     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1204     unsigned iBit = ASMBitFirstSetU16(uSrc);
    1205     if (iBit)
    1206     {
    1207         *puDst     = iBit - 1;
    1208         *pfEFlags &= ~X86_EFL_ZF;
    1209     }
    1210     else
    1211         *pfEFlags |= X86_EFL_ZF;
     1234    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU16(uSrc));
     1235}
     1236
     1237IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1238{
     1239    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitFirstSetU16(uSrc));
     1240}
     1241
     1242IEM_DECL_IMPL_DEF(void, iemAImpl_bsf_u16_amd,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1243{
     1244    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitFirstSetU16(uSrc));
    12121245}
    12131246
    12141247# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    12151248
     1249
    12161250/*
    12171251 * BSR - last (most significant) bit set
    12181252 */
    1219 
    12201253IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    12211254{
    1222     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1223     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1224     unsigned iBit = ASMBitLastSetU64(uSrc);
    1225     if (uSrc)
    1226     {
    1227         *puDst     = iBit - 1;
    1228         *pfEFlags &= ~X86_EFL_ZF;
    1229     }
    1230     else
    1231         *pfEFlags |= X86_EFL_ZF;
     1255    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU64(uSrc));
     1256}
     1257
     1258IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64_intel,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     1259{
     1260    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU64(uSrc));
     1261}
     1262
     1263IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u64_amd,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     1264{
     1265    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitLastSetU64(uSrc));
    12321266}
    12331267
     
    12361270IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    12371271{
    1238     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1239     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1240     unsigned iBit = ASMBitLastSetU32(uSrc);
    1241     if (uSrc)
    1242     {
    1243         *puDst     = iBit - 1;
    1244         *pfEFlags &= ~X86_EFL_ZF;
    1245     }
    1246     else
    1247         *pfEFlags |= X86_EFL_ZF;
     1272    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU32(uSrc));
     1273}
     1274
     1275IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32_intel,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1276{
     1277    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU32(uSrc));
     1278}
     1279
     1280IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u32_amd,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1281{
     1282    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitLastSetU32(uSrc));
    12481283}
    12491284
     
    12511286IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    12521287{
    1253     /* Note! "undefined" flags: OF, SF, AF, PF, CF. */
    1254     /* Intel & AMD differs here. This is is the AMD behaviour. */
    1255     unsigned iBit = ASMBitLastSetU16(uSrc);
    1256     if (uSrc)
    1257     {
    1258         *puDst     = iBit - 1;
    1259         *pfEFlags &= ~X86_EFL_ZF;
    1260     }
    1261     else
    1262         *pfEFlags |= X86_EFL_ZF;
     1288    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU16(uSrc));
     1289}
     1290
     1291IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16_intel,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1292{
     1293    SET_BIT_SEARCH_RESULT_INTEL(puDst, pfEFlags, ASMBitLastSetU16(uSrc));
     1294}
     1295
     1296IEM_DECL_IMPL_DEF(void, iemAImpl_bsr_u16_amd,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1297{
     1298    SET_BIT_SEARCH_RESULT_AMD(puDst, pfEFlags, ASMBitLastSetU16(uSrc));
    12631299}
    12641300
     
    15951631 * MUL
    15961632 */
    1597 # define EMIT_MUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_fnLoadF1, a_fnStore, a_fnMul) \
     1633# define EMIT_MUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnMul) \
    15981634IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth, a_Args) \
     1635{ \
     1636    RTUINT ## a_cBitsWidth2x ## U Result; \
     1637    a_fnMul(Result, a_fnLoadF1(), uFactor, a_cBitsWidth2x); \
     1638    a_fnStore(Result); \
     1639    \
     1640    /* MUL EFLAGS according to Skylake (similar to IMUL). */ \
     1641    uint32_t fEfl = *pfEFlags & ~(X86_EFL_SF | X86_EFL_CF | X86_EFL_OF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_PF); \
     1642    if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
     1643        fEfl |= X86_EFL_SF; \
     1644    fEfl |= g_afParity[Result.s.Lo & 0xff]; \
     1645    if (Result.s.Hi != 0) \
     1646        fEfl |= X86_EFL_CF | X86_EFL_OF; \
     1647    *pfEFlags = fEfl; \
     1648    return 0; \
     1649} \
     1650IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth ## _intel, a_Args) \
     1651{ \
     1652    return iemAImpl_mul_u ## a_cBitsWidth a_CallArgs; \
     1653} \
     1654IEM_DECL_IMPL_DEF(int, iemAImpl_mul_u ## a_cBitsWidth ## _amd, a_Args) \
    15991655{ \
    16001656    RTUINT ## a_cBitsWidth2x ## U Result; \
     
    16121668    return 0; \
    16131669}
    1614 EMIT_MUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_MUL_U128)
    1615 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1616 EMIT_MUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
    1617 EMIT_MUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
    1618 EMIT_MUL(8, 16, (uint16_t *puAX, uint8_t uFactor, uint32_t *pfEFlags), MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_MUL)
     1670
     1671EMIT_MUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor, uint32_t *pfEFlags), (puA, puD, uFactor, pfEFlags),
     1672         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL_U128)
     1673# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1674EMIT_MUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor, uint32_t *pfEFlags),  (puA, puD, uFactor, pfEFlags),
     1675         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
     1676EMIT_MUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor, uint32_t *pfEFlags),  (puA, puD, uFactor, pfEFlags),
     1677         MUL_LOAD_F1, MUL_STORE, MULDIV_MUL)
     1678EMIT_MUL(8, 16, (uint16_t *puAX, uint8_t uFactor, uint32_t *pfEFlags),                  (puAX,     uFactor, pfEFlags),
     1679         MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_MUL)
    16191680# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    16201681
     
    16221683/*
    16231684 * IMUL
    1624  */
    1625 # define EMIT_IMUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul) \
     1685 *
     1686 * The SF, ZF, AF and PF flags are "undefined". AMD (3990x) leaves these
     1687 * flags as is - at least for the two op version. Whereas Intel skylake (6700K
     1688 * and 10980X (Cascade Lake)) always clear AF and ZF and calculates SF and PF
     1689 * as per the lower half of the result.
     1690 */
     1691# define EMIT_IMUL(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoadF1, a_fnStore, a_fnNeg, a_fnMul) \
    16261692IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth,a_Args) \
     1693{ \
     1694    RTUINT ## a_cBitsWidth2x ## U Result; \
     1695    uint32_t fEfl = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF); \
     1696    \
     1697    uint ## a_cBitsWidth ## _t const uFactor1 = a_fnLoadF1(); \
     1698    if (!(uFactor1 & RT_BIT_64(a_cBitsWidth - 1))) \
     1699    { \
     1700        if (!(uFactor2 & RT_BIT_64(a_cBitsWidth - 1))) \
     1701        { \
     1702            a_fnMul(Result, uFactor1, uFactor2, a_cBitsWidth2x); \
     1703            if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \
     1704                fEfl |= X86_EFL_CF | X86_EFL_OF; \
     1705        } \
     1706        else \
     1707        { \
     1708            uint ## a_cBitsWidth ## _t const uPositiveFactor2 = UINT ## a_cBitsWidth ## _C(0) - uFactor2; \
     1709            a_fnMul(Result, uFactor1, uPositiveFactor2, a_cBitsWidth2x); \
     1710            if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \
     1711                fEfl |= X86_EFL_CF | X86_EFL_OF; \
     1712            a_fnNeg(Result, a_cBitsWidth2x); \
     1713        } \
     1714    } \
     1715    else \
     1716    { \
     1717        if (!(uFactor2 & RT_BIT_64(a_cBitsWidth - 1))) \
     1718        { \
     1719            uint ## a_cBitsWidth ## _t const uPositiveFactor1 = UINT ## a_cBitsWidth ## _C(0) - uFactor1; \
     1720            a_fnMul(Result, uPositiveFactor1, uFactor2, a_cBitsWidth2x); \
     1721            if (Result.s.Hi != 0 || Result.s.Lo > RT_BIT_64(a_cBitsWidth - 1)) \
     1722                fEfl |= X86_EFL_CF | X86_EFL_OF; \
     1723            a_fnNeg(Result, a_cBitsWidth2x); \
     1724        } \
     1725        else \
     1726        { \
     1727            uint ## a_cBitsWidth ## _t const uPositiveFactor1 = UINT ## a_cBitsWidth ## _C(0) - uFactor1; \
     1728            uint ## a_cBitsWidth ## _t const uPositiveFactor2 = UINT ## a_cBitsWidth ## _C(0) - uFactor2; \
     1729            a_fnMul(Result, uPositiveFactor1, uPositiveFactor2, a_cBitsWidth2x); \
     1730            if (Result.s.Hi != 0 || Result.s.Lo >= RT_BIT_64(a_cBitsWidth - 1)) \
     1731                fEfl |= X86_EFL_CF | X86_EFL_OF; \
     1732        } \
     1733    } \
     1734    a_fnStore(Result); \
     1735    \
     1736    fEfl &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \
     1737    if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
     1738        fEfl |= X86_EFL_SF;  \
     1739    fEfl |= g_afParity[Result.s.Lo & 0xff]; \
     1740    *pfEFlags = fEfl; \
     1741    return 0; \
     1742} \
     1743\
     1744IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth ## _intel,a_Args) \
     1745{ \
     1746    return iemAImpl_imul_u ## a_cBitsWidth a_CallArgs; \
     1747} \
     1748\
     1749IEM_DECL_IMPL_DEF(int, iemAImpl_imul_u ## a_cBitsWidth ## _amd,a_Args) \
    16271750{ \
    16281751    RTUINT ## a_cBitsWidth2x ## U Result; \
     
    16711794    } \
    16721795    a_fnStore(Result); \
    1673     if (false) \
    1674     {   /* Intel (skylake) flags "undefined" behaviour: */  \
    1675         fEfl &= ~(X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_PF); \
    1676         if (Result.s.Lo & RT_BIT_64(a_cBitsWidth - 1)) \
    1677             fEfl |= X86_EFL_SF;  \
    1678         fEfl |= g_afParity[Result.s.Lo & 0xff]; \
    1679     } \
    16801796    *pfEFlags = fEfl; \
    16811797    return 0; \
    16821798}
    1683 /** @todo Testcase: IMUL 2 and 3 operands. */
    1684 EMIT_IMUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor2, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_NEG_U128, MULDIV_MUL_U128)
    1685 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1686 EMIT_IMUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor2, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
    1687 EMIT_IMUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor2, uint32_t *pfEFlags), MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
    1688 EMIT_IMUL(8, 16, (uint16_t *puAX, uint8_t uFactor2, uint32_t *pfEFlags), MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_NEG, MULDIV_MUL)
     1799EMIT_IMUL(64, 128, (uint64_t *puA, uint64_t *puD, uint64_t uFactor2, uint32_t *pfEFlags), (puA, puD, uFactor2, pfEFlags),
     1800          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG_U128, MULDIV_MUL_U128)
     1801# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1802EMIT_IMUL(32, 64, (uint32_t *puA, uint32_t *puD, uint32_t uFactor2, uint32_t *pfEFlags),  (puA, puD, uFactor2, pfEFlags),
     1803          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
     1804EMIT_IMUL(16, 32, (uint16_t *puA, uint16_t *puD, uint16_t uFactor2, uint32_t *pfEFlags),  (puA, puD, uFactor2, pfEFlags),
     1805          MUL_LOAD_F1, MUL_STORE, MULDIV_NEG, MULDIV_MUL)
     1806EMIT_IMUL(8, 16, (uint16_t *puAX, uint8_t uFactor2, uint32_t *pfEFlags),                  (puAX,     uFactor2, pfEFlags),
     1807          MUL_LOAD_F1_U8, MUL_STORE_U8, MULDIV_NEG, MULDIV_MUL)
    16891808# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    16901809
    16911810
    1692 IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    1693 {
    1694     uint64_t uIgn;
    1695     iemAImpl_imul_u64(puDst, &uIgn, uSrc, pfEFlags);
    1696 }
    1697 
    1698 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1699 
    1700 IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
    1701 {
    1702     uint32_t uIgn;
    1703     iemAImpl_imul_u32(puDst, &uIgn, uSrc, pfEFlags);
    1704 }
    1705 
    1706 
    1707 IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
    1708 {
    1709     uint16_t uIgn;
    1710     iemAImpl_imul_u16(puDst, &uIgn, uSrc, pfEFlags);
    1711 }
    1712 
    1713 #endif
     1811# define EMIT_IMUL_TWO(a_cBits, a_uType) \
     1812IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u ## a_cBits,(a_uType *puDst, a_uType uSrc, uint32_t *pfEFlags)) \
     1813{ \
     1814    a_uType uIgn; \
     1815    iemAImpl_imul_u ## a_cBits(puDst, &uIgn, uSrc, pfEFlags); \
     1816} \
     1817\
     1818IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u ## a_cBits ## _intel,(a_uType *puDst, a_uType uSrc, uint32_t *pfEFlags)) \
     1819{ \
     1820    a_uType uIgn; \
     1821    iemAImpl_imul_u ## a_cBits(puDst, &uIgn, uSrc, pfEFlags); \
     1822} \
     1823\
     1824IEM_DECL_IMPL_DEF(void, iemAImpl_imul_two_u ## a_cBits ## _amd,(a_uType *puDst, a_uType uSrc, uint32_t *pfEFlags)) \
     1825{ \
     1826    a_uType uIgn; \
     1827    iemAImpl_imul_u ## a_cBits(puDst, &uIgn, uSrc, pfEFlags); \
     1828}
     1829
     1830EMIT_IMUL_TWO(64, uint64_t)
     1831# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1832EMIT_IMUL_TWO(32, uint32_t)
     1833EMIT_IMUL_TWO(16, uint16_t)
     1834# endif
    17141835
    17151836/*
    17161837 * DIV
    17171838 */
    1718 # define EMIT_DIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_fnLoad, a_fnStore, a_fnDivRem) \
     1839# define EMIT_DIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnDivRem) \
    17191840IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth,a_Args) \
    17201841{ \
     
    17351856    /* #DE */ \
    17361857    return -1; \
    1737 }
    1738 EMIT_DIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_MODDIV_U128)
    1739 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1740 EMIT_DIV(32,64, (uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
    1741 EMIT_DIV(16,32, (uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
    1742 EMIT_DIV(8,16,  (uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags), DIV_LOAD_U8, DIV_STORE_U8, MULDIV_MODDIV)
     1858} \
     1859\
     1860IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth ## _intel,a_Args) \
     1861{ \
     1862    return iemAImpl_div_u ## a_cBitsWidth a_CallArgs; \
     1863} \
     1864\
     1865IEM_DECL_IMPL_DEF(int, iemAImpl_div_u ## a_cBitsWidth ## _amd,a_Args) \
     1866{ \
     1867    /* Note! Skylake leaves all flags alone. */ \
     1868    RT_NOREF_PV(pfEFlags); \
     1869    \
     1870    RTUINT ## a_cBitsWidth2x ## U Dividend; \
     1871    a_fnLoad(Dividend); \
     1872    if (   uDivisor != 0 \
     1873        && Dividend.s.Hi < uDivisor) \
     1874    { \
     1875        RTUINT ## a_cBitsWidth2x ## U Remainder, Quotient; \
     1876        a_fnDivRem(Quotient, Remainder, Dividend, uDivisor); \
     1877        a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \
     1878        /** @todo research the undefined DIV flags. */ \
     1879        return 0; \
     1880    } \
     1881    /* #DE */ \
     1882    return -1; \
     1883}
     1884EMIT_DIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     1885         DIV_LOAD, DIV_STORE, MULDIV_MODDIV_U128)
     1886# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1887EMIT_DIV(32,64, (uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     1888         DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
     1889EMIT_DIV(16,32, (uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     1890         DIV_LOAD, DIV_STORE, MULDIV_MODDIV)
     1891EMIT_DIV(8,16,  (uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags),                (puAX,     uDivisor, pfEFlags),
     1892         DIV_LOAD_U8, DIV_STORE_U8, MULDIV_MODDIV)
    17431893# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    17441894
     
    17471897 * IDIV
    17481898 */
    1749 # define EMIT_IDIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem) \
     1899# define EMIT_IDIV(a_cBitsWidth, a_cBitsWidth2x, a_Args, a_CallArgs, a_fnLoad, a_fnStore, a_fnNeg, a_fnDivRem) \
    17501900IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth,a_Args) \
    17511901{ \
     
    18221972    /* #DE */ \
    18231973    return -1; \
    1824 }
    1825 EMIT_IDIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_NEG_U128, MULDIV_MODDIV_U128)
    1826 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    1827 EMIT_IDIV(32,64,(uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
    1828 EMIT_IDIV(16,32,(uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags), DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
    1829 EMIT_IDIV(8,16,(uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags),           DIV_LOAD_U8, DIV_STORE_U8, MULDIV_NEG, MULDIV_MODDIV)
     1974} \
     1975\
     1976IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth ## _intel,a_Args) \
     1977{ \
     1978    return iemAImpl_idiv_u ## a_cBitsWidth a_CallArgs; \
     1979} \
     1980\
     1981IEM_DECL_IMPL_DEF(int, iemAImpl_idiv_u ## a_cBitsWidth ## _amd,a_Args) \
     1982{ \
     1983    /* Note! Skylake leaves all flags alone. */ \
     1984    RT_NOREF_PV(pfEFlags); \
     1985    \
     1986    /** @todo overflow checks */ \
     1987    if (uDivisor != 0) \
     1988    { \
     1989        /* \
     1990         * Convert to unsigned division. \
     1991         */ \
     1992        RTUINT ## a_cBitsWidth2x ## U Dividend; \
     1993        a_fnLoad(Dividend); \
     1994        bool const fSignedDividend = RT_BOOL(Dividend.s.Hi & RT_BIT_64(a_cBitsWidth - 1)); \
     1995        if (fSignedDividend) \
     1996            a_fnNeg(Dividend, a_cBitsWidth2x); \
     1997        \
     1998        uint ## a_cBitsWidth ## _t uDivisorPositive; \
     1999        if (!(uDivisor & RT_BIT_64(a_cBitsWidth - 1))) \
     2000            uDivisorPositive = uDivisor; \
     2001        else \
     2002            uDivisorPositive = UINT ## a_cBitsWidth ## _C(0) - uDivisor; \
     2003        \
     2004        RTUINT ## a_cBitsWidth2x ## U Remainder, Quotient; \
     2005        a_fnDivRem(Quotient, Remainder, Dividend, uDivisorPositive); \
     2006        \
     2007        /* \
     2008         * Setup the result, checking for overflows. \
     2009         */ \
     2010        if (!(uDivisor & RT_BIT_64(a_cBitsWidth - 1))) \
     2011        { \
     2012            if (!fSignedDividend) \
     2013            { \
     2014                /* Positive divisor, positive dividend => result positive. */ \
     2015                if (Quotient.s.Hi == 0 && Quotient.s.Lo <= (uint ## a_cBitsWidth ## _t)INT ## a_cBitsWidth ## _MAX) \
     2016                { \
     2017                    a_fnStore(Quotient.s.Lo, Remainder.s.Lo); \
     2018                    return 0; \
     2019                } \
     2020            } \
     2021            else \
     2022            { \
     2023                /* Positive divisor, negative dividend => result negative. */ \
     2024                if (Quotient.s.Hi == 0 && Quotient.s.Lo <= RT_BIT_64(a_cBitsWidth - 1)) \
     2025                { \
     2026                    a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \
     2027                    return 0; \
     2028                } \
     2029            } \
     2030        } \
     2031        else \
     2032        { \
     2033            if (!fSignedDividend) \
     2034            { \
     2035                /* Negative divisor, positive dividend => negative quotient, positive remainder. */ \
     2036                if (Quotient.s.Hi == 0 && Quotient.s.Lo <= RT_BIT_64(a_cBitsWidth - 1)) \
     2037                { \
     2038                    a_fnStore(UINT ## a_cBitsWidth ## _C(0) - Quotient.s.Lo, Remainder.s.Lo); \
     2039                    return 0; \
     2040                } \
     2041            } \
     2042            else \
     2043            { \
     2044                /* Negative divisor, negative dividend => positive quotient, negative remainder. */ \
     2045                if (Quotient.s.Hi == 0 && Quotient.s.Lo <= (uint ## a_cBitsWidth ## _t)INT ## a_cBitsWidth ## _MAX) \
     2046                { \
     2047                    a_fnStore(Quotient.s.Lo, UINT ## a_cBitsWidth ## _C(0) - Remainder.s.Lo); \
     2048                    return 0; \
     2049                } \
     2050            } \
     2051        } \
     2052    } \
     2053    /* #DE */ \
     2054    return -1; \
     2055}
     2056
     2057EMIT_IDIV(64,128,(uint64_t *puA, uint64_t *puD, uint64_t uDivisor, uint32_t *pfEFlags), (puA, puD, uDivisor, pfEFlags),
     2058          DIV_LOAD, DIV_STORE, MULDIV_NEG_U128, MULDIV_MODDIV_U128)
     2059# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2060EMIT_IDIV(32,64,(uint32_t *puA, uint32_t *puD, uint32_t uDivisor, uint32_t *pfEFlags),  (puA, puD, uDivisor, pfEFlags),
     2061          DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
     2062EMIT_IDIV(16,32,(uint16_t *puA, uint16_t *puD, uint16_t uDivisor, uint32_t *pfEFlags),  (puA, puD, uDivisor, pfEFlags),
     2063          DIV_LOAD, DIV_STORE, MULDIV_NEG, MULDIV_MODDIV)
     2064EMIT_IDIV(8,16,(uint16_t *puAX, uint8_t uDivisor, uint32_t *pfEFlags),                  (puAX,     uDivisor, pfEFlags),
     2065          DIV_LOAD_U8, DIV_STORE_U8, MULDIV_NEG, MULDIV_MODDIV)
    18302066# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    18312067
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h

    r93906 r94156  
    22512251                IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
    22522252                IEM_MC_REF_EFLAGS(pEFlags);
    2253                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
     2253                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags),
     2254                                         pu16Dst, u16Src, pEFlags);
    22542255                IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
    22552256
     
    22742275                IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
    22752276                IEM_MC_REF_EFLAGS(pEFlags);
    2276                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
     2277                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags),
     2278                                         pu16Dst, u16Src, pEFlags);
    22772279                IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
    22782280
     
    23002302                IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
    23012303                IEM_MC_REF_EFLAGS(pEFlags);
    2302                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
     2304                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags),
     2305                                         pu32Dst, u32Src, pEFlags);
    23032306                IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
    23042307
     
    23232326                IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
    23242327                IEM_MC_REF_EFLAGS(pEFlags);
    2325                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
     2328                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags),
     2329                                         pu32Dst, u32Src, pEFlags);
    23262330                IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
    23272331
     
    23492353                IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
    23502354                IEM_MC_REF_EFLAGS(pEFlags);
    2351                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
     2355                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags),
     2356                                         pu64Dst, u64Src, pEFlags);
    23522357                IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
    23532358
     
    23722377                IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
    23732378                IEM_MC_REF_EFLAGS(pEFlags);
    2374                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
     2379                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags),
     2380                                         pu64Dst, u64Src, pEFlags);
    23752381                IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
    23762382
     
    24432449                IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
    24442450                IEM_MC_REF_EFLAGS(pEFlags);
    2445                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
     2451                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags),
     2452                                         pu16Dst, u16Src, pEFlags);
    24462453                IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
    24472454
     
    24662473                IEM_MC_REF_LOCAL(pu16Dst, u16Tmp);
    24672474                IEM_MC_REF_EFLAGS(pEFlags);
    2468                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u16, pu16Dst, u16Src, pEFlags);
     2475                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u16_eflags),
     2476                                         pu16Dst, u16Src, pEFlags);
    24692477                IEM_MC_STORE_GREG_U16(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u16Tmp);
    24702478
     
    24902498                IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
    24912499                IEM_MC_REF_EFLAGS(pEFlags);
    2492                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
     2500                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags),
     2501                                         pu32Dst, u32Src, pEFlags);
    24932502                IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
    24942503
     
    25132522                IEM_MC_REF_LOCAL(pu32Dst, u32Tmp);
    25142523                IEM_MC_REF_EFLAGS(pEFlags);
    2515                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u32, pu32Dst, u32Src, pEFlags);
     2524                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u32_eflags),
     2525                                         pu32Dst, u32Src, pEFlags);
    25162526                IEM_MC_STORE_GREG_U32(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u32Tmp);
    25172527
     
    25372547                IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
    25382548                IEM_MC_REF_EFLAGS(pEFlags);
    2539                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
     2549                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags),
     2550                                         pu64Dst, u64Src, pEFlags);
    25402551                IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
    25412552
     
    25602571                IEM_MC_REF_LOCAL(pu64Dst, u64Tmp);
    25612572                IEM_MC_REF_EFLAGS(pEFlags);
    2562                 IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_imul_two_u64, pu64Dst, u64Src, pEFlags);
     2573                IEM_MC_CALL_VOID_AIMPL_3(IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_u64_eflags),
     2574                                         pu64Dst, u64Src, pEFlags);
    25632575                IEM_MC_STORE_GREG_U64(((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg, u64Tmp);
    25642576
     
    1129611308            IEMOP_MNEMONIC(mul_Eb, "mul Eb");
    1129711309            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
    11298             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_mul_u8);
     11310            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_mul_u8_eflags));
    1129911311        case 5:
    1130011312            IEMOP_MNEMONIC(imul_Eb, "imul Eb");
    1130111313            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
    11302             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_imul_u8);
     11314            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_u8_eflags));
    1130311315        case 6:
    1130411316            IEMOP_MNEMONIC(div_Eb, "div Eb");
    1130511317            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
    11306             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_div_u8);
     11318            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_div_u8_eflags));
    1130711319        case 7:
    1130811320            IEMOP_MNEMONIC(idiv_Eb, "idiv Eb");
    1130911321            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
    11310             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, iemAImpl_idiv_u8);
     11322            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEb, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_idiv_u8_eflags));
    1131111323        IEM_NOT_REACHED_DEFAULT_CASE_RET();
    1131211324    }
     
    1133611348            IEMOP_MNEMONIC(mul_Ev, "mul Ev");
    1133711349            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
    11338             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_mul);
     11350            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_mul_eflags));
    1133911351        case 5:
    1134011352            IEMOP_MNEMONIC(imul_Ev, "imul Ev");
    1134111353            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
    11342             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_imul);
     11354            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_eflags));
    1134311355        case 6:
    1134411356            IEMOP_MNEMONIC(div_Ev, "div Ev");
    1134511357            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
    11346             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_div);
     11358            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_div_eflags));
    1134711359        case 7:
    1134811360            IEMOP_MNEMONIC(idiv_Ev, "idiv Ev");
    1134911361            IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_OF | X86_EFL_CF);
    11350             return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, &g_iemAImpl_idiv);
     11362            return FNIEMOP_CALL_2(iemOpCommonGrp3MulDivEv, bRm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_idiv_eflags));
    1135111363        IEM_NOT_REACHED_DEFAULT_CASE_RET();
    1135211364    }
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r93847 r94156  
    72687268    IEMOP_HLP_MIN_386();
    72697269    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
    7270     return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_imul_two);
     7270    return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_imul_two_eflags));
    72717271}
    72727272
     
    80108010    IEMOP_HLP_MIN_386();
    80118011    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
    8012     return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsf);
     8012    return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_bsf_eflags));
    80138013}
    80148014
     
    80248024    IEMOP_HLP_MIN_386();
    80258025    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
    8026     return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, &g_iemAImpl_bsr);
     8026    return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, IEMTARGETCPU_EFL_BEHAVIOR_SELECT(g_iemAImpl_bsr_eflags));
    80278027}
    80288028
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