VirtualBox

Changeset 94178 in vbox


Ignore:
Timestamp:
Mar 11, 2022 4:09:47 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150434
Message:

VMM/IEM: Use the C implementation for the SHLD/SHRD Intel and AMD EFLAGS variants. bugref:9898

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

Legend:

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

    r94176 r94178  
    14891489; Makes ASSUMPTIONS about A0, A1, A2 and A3 assignments.
    14901490;
     1491; @note the _intel and _amd variants are implemented in C.
     1492;
    14911493%macro IEMIMPL_SHIFT_DBL_OP 3
    14921494BEGINCODE
    1493 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_intel, 16
    1494 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_amd, 16
    14951495BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
    14961496        PROLOGUE_4_ARGS
     
    15081508ENDPROC iemAImpl_ %+ %1 %+ _u16
    15091509
    1510 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_intel, 16
    1511 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_amd, 16
    15121510BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
    15131511        PROLOGUE_4_ARGS
     
    15261524
    15271525 %ifdef RT_ARCH_AMD64
    1528 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_intel, 20
    1529 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_amd, 20
    15301526BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
    15311527        PROLOGUE_4_ARGS
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r94176 r94178  
    25462546# endif
    25472547
     2548#endif /* !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) */
     2549
    25482550
    25492551/*
     
    25572559 *  - ZF, SF and PF are calculated according to the result by both vendors.
    25582560 */
    2559 #define EMIT_SHLD(a_cBitsWidth) \
    2560 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, \
    2561                                                          uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, uint32_t *pfEFlags)) \
     2561#define EMIT_SHLD(a_cBitsWidth, a_uType, a_Suffix, a_fIntelFlags) \
     2562IEM_DECL_IMPL_DEF(void, RT_CONCAT3(iemAImpl_shld_u,a_cBitsWidth,a_Suffix),(a_uType *puDst, a_uType uSrc, uint8_t cShift, \
     2563                                                                           uint32_t *pfEFlags)) \
    25622564{ \
    25632565    /** @todo this ain't right for 16-bit. Apparently it should use 0x1f instead \
     
    25662568    if (cShift) \
    25672569    { \
    2568         uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
    2569         uint ## a_cBitsWidth ## _t       uResult = uDst << cShift; \
     2570        a_uType const uDst    = *puDst; \
     2571        a_uType       uResult = uDst << cShift; \
    25702572        uResult |= uSrc >> (a_cBitsWidth - cShift); \
    25712573        *puDst = uResult; \
    25722574        \
     2575        /* CALC EFLAGS: */ \
    25732576        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
    2574         AssertCompile(X86_EFL_CF_BIT == 0); \
    2575         fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ (uDst << 1)); /* Set according to the first shift. */ \
    2576         fEfl |= (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; /* CF = last bit shifted out */ \
    2577         fEfl |= g_afParity[uResult & 0xff]; \
    2578         fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    2579         fEfl |= X86_EFL_CALC_ZF(uResult); \
    2580         *pfEFlags = fEfl; \
    2581     } \
    2582 }\
    2583 \
    2584 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u ## a_cBitsWidth ## _intel,(uint ## a_cBitsWidth ## _t *puDst, \
    2585                                                                    uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, \
    2586                                                                    uint32_t *pfEFlags)) \
    2587 { \
    2588     iemAImpl_shld_u ## a_cBitsWidth(puDst, uSrc, cShift, pfEFlags); \
    2589 } \
    2590 \
    2591 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u ## a_cBitsWidth ## _amd,(uint ## a_cBitsWidth ## _t *puDst, \
    2592                                                                  uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, \
    2593                                                                  uint32_t *pfEFlags)) \
    2594 { \
    2595     cShift &= a_cBitsWidth - 1; \
    2596     if (cShift) \
    2597     { \
    2598         uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
    2599         uint ## a_cBitsWidth ## _t       uResult = uDst << cShift; \
    2600         uResult |= uSrc >> (a_cBitsWidth - cShift); \
    2601         *puDst = uResult; \
    2602         \
    2603         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
    2604         fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth((uDst << (cShift - 1)) ^ uResult); /* Set according to last shift. */ \
    2605         fEfl |= X86_EFL_AF; \
     2577        if (a_fIntelFlags) \
     2578            /* Intel 6700K & 10980XE: Set according to the first shift. AF always cleared. */ \
     2579            fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ (uDst << 1));  \
     2580        else \
     2581        {   /* AMD 3990X: Set according to last shift. AF always set. */ \
     2582            fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth((uDst << (cShift - 1)) ^ uResult); \
     2583            fEfl |= X86_EFL_AF; \
     2584        } \
    26062585        AssertCompile(X86_EFL_CF_BIT == 0); \
    26072586        fEfl |= (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; /* CF = last bit shifted out */ \
     
    26122591    } \
    26132592}
    2614 
    2615 EMIT_SHLD(64)
    2616 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2617 EMIT_SHLD(32)
    2618 EMIT_SHLD(16)
    2619 # endif
     2593#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     2594EMIT_SHLD(64, uint64_t, RT_NOTHING, 1)
     2595#endif /* !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) */
     2596EMIT_SHLD(64, uint64_t, _intel,     1)
     2597EMIT_SHLD(64, uint64_t, _amd,       0)
     2598#if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     2599EMIT_SHLD(32, uint32_t, RT_NOTHING, 1)
     2600#endif
     2601EMIT_SHLD(32, uint32_t, _intel,     1)
     2602EMIT_SHLD(32, uint32_t, _amd,       0)
     2603#if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     2604EMIT_SHLD(16, uint16_t, RT_NOTHING, 1)
     2605#endif
     2606EMIT_SHLD(16, uint16_t, _intel,     1)
     2607EMIT_SHLD(16, uint16_t, _amd,       0)
    26202608
    26212609
     
    26312619 *  - ZF, SF and PF are calculated according to the result by both vendors.
    26322620 */
    2633 #define EMIT_SHRD(a_cBitsWidth) \
    2634 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, \
    2635                                                          uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, uint32_t *pfEFlags)) \
     2621#define EMIT_SHRD(a_cBitsWidth, a_uType, a_Suffix, a_fIntelFlags) \
     2622IEM_DECL_IMPL_DEF(void, RT_CONCAT3(iemAImpl_shrd_u,a_cBitsWidth,a_Suffix),(a_uType *puDst, a_uType uSrc, uint8_t cShift, uint32_t *pfEFlags)) \
    26362623{ \
    26372624    /** @todo this is wrong for 16-bit, where it should be 0x1f not 0xf and \
     
    26402627    if (cShift) \
    26412628    { \
    2642         uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
    2643         uint ## a_cBitsWidth ## _t       uResult = uDst >> cShift; \
     2629        a_uType const uDst    = *puDst; \
     2630        a_uType       uResult = uDst >> cShift; \
    26442631        uResult |= uSrc << (a_cBitsWidth - cShift); \
    26452632        *puDst = uResult; \
    26462633        \
    26472634        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
    2648         fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ (uSrc << (a_cBitsWidth - 1))); \
     2635        if (a_fIntelFlags) \
     2636            /* Intel 6700K & 10980XE: Set according to the first shift. AF always cleared. */ \
     2637            fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ (uSrc << (a_cBitsWidth - 1))); \
     2638        else \
     2639        {   /* AMD 3990X: Set according to last shift. AF always set. */ \
     2640            if (cShift > 1) /* Set according to last shift. */ \
     2641                fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth((uSrc << (a_cBitsWidth - cShift + 1)) ^ uResult); \
     2642            else \
     2643                fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ uResult); \
     2644            fEfl |= X86_EFL_AF; \
     2645        } \
    26492646        AssertCompile(X86_EFL_CF_BIT == 0); \
    26502647        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; \
     
    26542651        *pfEFlags = fEfl; \
    26552652    } \
    2656 } \
    2657 \
    2658 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u ## a_cBitsWidth ## _intel,(uint ## a_cBitsWidth ## _t *puDst, \
    2659                                                                    uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, \
    2660                                                                    uint32_t *pfEFlags)) \
    2661 { \
    2662     iemAImpl_shrd_u ## a_cBitsWidth(puDst, uSrc, cShift, pfEFlags); \
    2663 } \
    2664 \
    2665 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u ## a_cBitsWidth ## _amd,(uint ## a_cBitsWidth ## _t *puDst, \
    2666                                                                  uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, \
    2667                                                                  uint32_t *pfEFlags)) \
    2668 { \
    2669     cShift &= a_cBitsWidth - 1; \
    2670     if (cShift) \
    2671     { \
    2672         uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
    2673         uint ## a_cBitsWidth ## _t       uResult = uDst >> cShift; \
    2674         uResult |= uSrc << (a_cBitsWidth - cShift); \
    2675         *puDst = uResult; \
    2676         \
    2677         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
    2678         if (cShift > 1) /* Set according to last shift. */ \
    2679             fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth((uSrc << (a_cBitsWidth - cShift + 1)) ^ uResult); \
    2680         else \
    2681             fEfl |= X86_EFL_GET_OF_ ## a_cBitsWidth(uDst ^ uResult); \
    2682         fEfl |= X86_EFL_AF; \
    2683         AssertCompile(X86_EFL_CF_BIT == 0); \
    2684         fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; \
    2685         fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
    2686         fEfl |= X86_EFL_CALC_ZF(uResult); \
    2687         fEfl |= g_afParity[uResult & 0xff]; \
    2688         *pfEFlags = fEfl; \
    2689     } \
    2690 }
    2691 EMIT_SHRD(64)
    2692 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
    2693 EMIT_SHRD(32)
    2694 EMIT_SHRD(16)
    2695 # endif
    2696 
     2653}
     2654#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
     2655EMIT_SHRD(64, uint64_t, RT_NOTHING, 1)
     2656#endif /* !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) */
     2657EMIT_SHRD(64, uint64_t, _intel,     1)
     2658EMIT_SHRD(64, uint64_t, _amd,       0)
     2659#if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     2660EMIT_SHRD(32, uint32_t, RT_NOTHING, 1)
     2661#endif
     2662EMIT_SHRD(32, uint32_t, _intel,     1)
     2663EMIT_SHRD(32, uint32_t, _amd,       0)
     2664#if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     2665EMIT_SHRD(16, uint16_t, RT_NOTHING, 1)
     2666#endif
     2667EMIT_SHRD(16, uint16_t, _intel,     1)
     2668EMIT_SHRD(16, uint16_t, _amd,       0)
     2669
     2670
     2671#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    26972672
    26982673# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
Note: See TracChangeset for help on using the changeset viewer.

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