VirtualBox

Changeset 95360 in vbox


Ignore:
Timestamp:
Jun 23, 2022 9:45:55 PM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented the POPCNT instruction. bugref:9898

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

Legend:

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

    r95347 r95360  
    10451045IEMIMPL_BIT_OP2 tzcnt, (X86_EFL_ZF | X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF), 0
    10461046IEMIMPL_BIT_OP2 lzcnt, (X86_EFL_ZF | X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF), 0
     1047
     1048
     1049;;
     1050; Macro for implementing POPCNT.
     1051;
     1052; This will generate code for the 16, 32 and 64 bit accesses, except on 32-bit
     1053; system where the 64-bit accesses requires hand coding.
     1054;
     1055; All the functions takes a pointer to the destination memory operand in A0,
     1056; the source register operand in A1 and a pointer to eflags in A2.
     1057;
     1058; ASSUMES Intel and AMD set EFLAGS the same way.
     1059;
     1060; ASSUMES the instruction does not support memory destination.
     1061;
     1062; @param        1       The instruction mnemonic.
     1063; @param        2       The modified flags.
     1064; @param        3       The undefined flags.
     1065;
     1066%macro IEMIMPL_BIT_OP3 3
     1067BEGINCODE
     1068BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
     1069        PROLOGUE_3_ARGS
     1070        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1071        %1      T0_16, A1_16
     1072        mov     [A0], T0_16
     1073        IEM_SAVE_FLAGS                 A2, %2, %3
     1074        EPILOGUE_3_ARGS
     1075ENDPROC iemAImpl_ %+ %1 %+ _u16
     1076
     1077BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
     1078        PROLOGUE_3_ARGS
     1079        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1080        %1      T0_32, A1_32
     1081        mov     [A0], T0_32
     1082        IEM_SAVE_FLAGS                 A2, %2, %3
     1083        EPILOGUE_3_ARGS
     1084ENDPROC iemAImpl_ %+ %1 %+ _u32
     1085
     1086 %ifdef RT_ARCH_AMD64
     1087BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
     1088        PROLOGUE_3_ARGS
     1089        IEM_MAYBE_LOAD_FLAGS           A2, %2, %3
     1090        %1      T0, A1
     1091        mov     [A0], T0
     1092        IEM_SAVE_FLAGS                 A2, %2, %3
     1093        EPILOGUE_3_ARGS_EX 8
     1094ENDPROC iemAImpl_ %+ %1 %+ _u64
     1095 %endif ; RT_ARCH_AMD64
     1096%endmacro
     1097IEMIMPL_BIT_OP3 popcnt, (X86_EFL_ZF | X86_EFL_CF | X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF), 0
    10471098
    10481099
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r95347 r95360  
    17731773                                                                      a_Type uSrc2, uint32_t *pfEFlags)) \
    17741774{ \
    1775     /* uSrc1 is considered virtually zero extended to 512 bits width. */ \
    17761775    uint32_t      fEfl      = *pfEFlags & ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF); \
    17771776    a_Type        uResult; \
     
    17981797EMIT_BZHI(32, uint32_t, RT_NOTHING)
    17991798#endif
     1799
     1800/*
     1801 * POPCNT
     1802 */
     1803RT_ALIGNAS_VAR(64) static uint8_t const g_abBitCounts6[64] =
     1804{
     1805    0, 1, 1, 2,  1, 2, 2, 3,  1, 2, 2, 3,  2, 3, 3, 4,
     1806    1, 2, 2, 3,  2, 3, 3, 4,  2, 3, 3, 4,  3, 4, 4, 5,
     1807    1, 2, 2, 3,  2, 3, 3, 4,  2, 3, 3, 4,  3, 4, 4, 5,
     1808    2, 3, 3, 4,  3, 4, 4, 5,  3, 4, 4, 5,  4, 5, 5, 6,
     1809};
     1810
     1811/** @todo Use native popcount where possible and employ some more efficient
     1812 *        algorithm here (or in asm.h fallback)! */
     1813
     1814DECLINLINE(uint8_t) iemPopCountU16(uint16_t u16)
     1815{
     1816    return g_abBitCounts6[ u16        & 0x3f]
     1817        +  g_abBitCounts6[(u16 >> 6)  & 0x3f]
     1818        +  g_abBitCounts6[(u16 >> 12) & 0x3f];
     1819}
     1820
     1821DECLINLINE(uint8_t) iemPopCountU32(uint32_t u32)
     1822{
     1823    return g_abBitCounts6[ u32        & 0x3f]
     1824        +  g_abBitCounts6[(u32 >> 6)  & 0x3f]
     1825        +  g_abBitCounts6[(u32 >> 12) & 0x3f]
     1826        +  g_abBitCounts6[(u32 >> 18) & 0x3f]
     1827        +  g_abBitCounts6[(u32 >> 24) & 0x3f]
     1828        +  g_abBitCounts6[(u32 >> 30) & 0x3f];
     1829}
     1830
     1831DECLINLINE(uint8_t) iemPopCountU64(uint64_t u64)
     1832{
     1833    return g_abBitCounts6[ u64        & 0x3f]
     1834        +  g_abBitCounts6[(u64 >> 6)  & 0x3f]
     1835        +  g_abBitCounts6[(u64 >> 12) & 0x3f]
     1836        +  g_abBitCounts6[(u64 >> 18) & 0x3f]
     1837        +  g_abBitCounts6[(u64 >> 24) & 0x3f]
     1838        +  g_abBitCounts6[(u64 >> 30) & 0x3f]
     1839        +  g_abBitCounts6[(u64 >> 36) & 0x3f]
     1840        +  g_abBitCounts6[(u64 >> 42) & 0x3f]
     1841        +  g_abBitCounts6[(u64 >> 48) & 0x3f]
     1842        +  g_abBitCounts6[(u64 >> 54) & 0x3f]
     1843        +  g_abBitCounts6[(u64 >> 60) & 0x3f];
     1844}
     1845
     1846#define EMIT_POPCNT(a_cBits, a_Type, a_Suffix) \
     1847IEM_DECL_IMPL_DEF(void, RT_CONCAT3(iemAImpl_popcnt_u,a_cBits,a_Suffix),(a_Type *puDst, a_Type uSrc, uint32_t *pfEFlags)) \
     1848{ \
     1849    uint32_t    fEfl = *pfEFlags & ~(X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF); \
     1850    a_Type      uResult; \
     1851    if (uSrc) \
     1852        uResult = iemPopCountU ## a_cBits(uSrc); \
     1853    else \
     1854    { \
     1855        fEfl |= X86_EFL_ZF; \
     1856        uResult = 0; \
     1857    } \
     1858    *puDst    = uResult; \
     1859    *pfEFlags = fEfl; \
     1860}
     1861
     1862EMIT_POPCNT(64, uint64_t, _fallback)
     1863EMIT_POPCNT(32, uint32_t, _fallback)
     1864EMIT_POPCNT(16, uint16_t, _fallback)
     1865#if defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1866EMIT_POPCNT(64, uint64_t, RT_NOTHING)
     1867#endif
     1868#if (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)) || defined(IEM_WITHOUT_ASSEMBLY)
     1869EMIT_POPCNT(32, uint32_t, RT_NOTHING)
     1870EMIT_POPCNT(16, uint16_t, RT_NOTHING)
     1871#endif
     1872
    18001873
    18011874#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r95308 r95360  
    78017801/** Opcode      0x0f 0xb8 - JMPE (reserved for emulator on IPF) */
    78027802FNIEMOP_UD_STUB(iemOp_jmpe);
     7803
     7804
    78037805/** Opcode 0xf3 0x0f 0xb8 - POPCNT Gv, Ev */
    7804 FNIEMOP_STUB(iemOp_popcnt_Gv_Ev);
     7806FNIEMOP_DEF(iemOp_popcnt_Gv_Ev)
     7807{
     7808    IEMOP_MNEMONIC2(RM, POPCNT, popcnt, Gv, Ev, DISOPTYPE_HARMLESS, 0);
     7809    if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fPopCnt)
     7810        return iemOp_InvalidNeedRM(pVCpu);
     7811#ifndef TST_IEM_CHECK_MC
     7812# if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
     7813    static const IEMOPBINSIZES s_Native =
     7814    {   NULL, NULL, iemAImpl_popcnt_u16, NULL, iemAImpl_popcnt_u32, NULL, iemAImpl_popcnt_u64, NULL };
     7815# endif
     7816    static const IEMOPBINSIZES s_Fallback =
     7817    {   NULL, NULL, iemAImpl_popcnt_u16_fallback, NULL, iemAImpl_popcnt_u32_fallback, NULL, iemAImpl_popcnt_u64_fallback, NULL };
     7818#endif
     7819    return FNIEMOP_CALL_1(iemOpHlpBinaryOperator_rv_rm, IEM_SELECT_HOST_OR_FALLBACK(fPopCnt, &s_Native, &s_Fallback));
     7820}
    78057821
    78067822
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r95347 r95360  
    13941394FNIEMAIMPLBINU32 iemAImpl_tzcnt_u32, iemAImpl_tzcnt_u32_amd, iemAImpl_tzcnt_u32_intel;
    13951395FNIEMAIMPLBINU64 iemAImpl_tzcnt_u64, iemAImpl_tzcnt_u64_amd, iemAImpl_tzcnt_u64_intel;
     1396FNIEMAIMPLBINU16 iemAImpl_popcnt_u16, iemAImpl_popcnt_u16_fallback;
     1397FNIEMAIMPLBINU32 iemAImpl_popcnt_u32, iemAImpl_popcnt_u32_fallback;
     1398FNIEMAIMPLBINU64 iemAImpl_popcnt_u64, iemAImpl_popcnt_u64_fallback;
    13961399/** @}  */
    13971400
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r95347 r95360  
    238238#undef  IEMTARGETCPU_EFL_BEHAVIOR_SELECT_EX
    239239#define IEMTARGETCPU_EFL_BEHAVIOR_SELECT_EX(a_aaArray, a_fNative)   NULL
     240
     241#undef  IEM_SELECT_HOST_OR_FALLBACK
     242#define IEM_SELECT_HOST_OR_FALLBACK(a_fCpumFeatureMember, a_pfnNative, a_pfnFallback)   NULL
    240243
    241244#define iemAImpl_fpu_r32_to_r80         NULL
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