VirtualBox

Changeset 66342 in vbox


Ignore:
Timestamp:
Mar 29, 2017 4:22:31 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
114278
Message:

IEM: Converted grp 9 to tables and fixed cmpxchg16b/8b prefix handling.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

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

    r66336 r66342  
    73727372}
    73737373
     7374FNIEMOP_DEF_1(iemOp_Grp9_cmpxchg8bOr16b, uint8_t, bRm)
     7375{
     7376    if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
     7377        return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg16b_Mdq, bRm);
     7378    return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg8b_Mq, bRm);
     7379}
    73747380
    73757381/** Opcode 0x0f 0xc7 11/6. */
     
    73887394FNIEMOP_UD_STUB_1(iemOp_Grp9_vmptrst_Mq, uint8_t, bRm);
    73897395
     7396/** Opcode 0x0f 0xc7 11/7. */
     7397FNIEMOP_UD_STUB_1(iemOp_Grp9_rdseed_Rv, uint8_t, bRm);
     7398
     7399
     7400/**
     7401 * Group 9 jump table for register variant.
     7402 */
     7403IEM_STATIC const PFNIEMOPRM g_apfnGroup9RegReg[] =
     7404{   /* pfx:  none,                          066h,                           0f3h,                           0f2h */
     7405    /* /0 */ IEMOP_X4(iemOp_InvalidWithRM),
     7406    /* /1 */ IEMOP_X4(iemOp_InvalidWithRM),
     7407    /* /2 */ IEMOP_X4(iemOp_InvalidWithRM),
     7408    /* /3 */ IEMOP_X4(iemOp_InvalidWithRM),
     7409    /* /4 */ IEMOP_X4(iemOp_InvalidWithRM),
     7410    /* /5 */ IEMOP_X4(iemOp_InvalidWithRM),
     7411    /* /6 */ iemOp_Grp9_rdrand_Rv,          iemOp_Grp9_rdrand_Rv,           iemOp_InvalidWithRM,            iemOp_InvalidWithRM,
     7412    /* /7 */ iemOp_Grp9_rdseed_Rv,          iemOp_Grp9_rdseed_Rv,           iemOp_InvalidWithRM,            iemOp_InvalidWithRM,
     7413};
     7414AssertCompile(RT_ELEMENTS(g_apfnGroup9RegReg) == 8*4);
     7415
     7416
     7417/**
     7418 * Group 9 jump table for memory variant.
     7419 */
     7420IEM_STATIC const PFNIEMOPRM g_apfnGroup9MemReg[] =
     7421{   /* pfx:  none,                          066h,                           0f3h,                           0f2h */
     7422    /* /0 */ IEMOP_X4(iemOp_InvalidWithRM),
     7423    /* /1 */ iemOp_Grp9_cmpxchg8bOr16b,     iemOp_Grp9_cmpxchg8bOr16b,      iemOp_Grp9_cmpxchg8bOr16b,      iemOp_Grp9_cmpxchg8bOr16b, /* see bs3-cpu-decoding-1 */
     7424    /* /2 */ IEMOP_X4(iemOp_InvalidWithRM),
     7425    /* /3 */ IEMOP_X4(iemOp_InvalidWithRM),
     7426    /* /4 */ IEMOP_X4(iemOp_InvalidWithRM),
     7427    /* /5 */ IEMOP_X4(iemOp_InvalidWithRM),
     7428    /* /6 */ iemOp_Grp9_vmptrld_Mq,         iemOp_Grp9_vmclear_Mq,          iemOp_Grp9_vmxon_Mq,            iemOp_InvalidWithRM,
     7429    /* /7 */ iemOp_Grp9_vmptrst_Mq,         iemOp_InvalidWithRM,            iemOp_InvalidWithRM,            iemOp_InvalidWithRM,
     7430};
     7431AssertCompile(RT_ELEMENTS(g_apfnGroup9MemReg) == 8*4);
     7432
    73907433
    73917434/** Opcode 0x0f 0xc7. */
    73927435FNIEMOP_DEF(iemOp_Grp9)
    73937436{
    7394     /** @todo Testcase: Check mixing 0x66 and 0xf3. Check the effect of 0xf2. */
    7395     uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
    7396     switch ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK)
    7397     {
    7398         case 0: case 2: case 3: case 4: case 5:
    7399             return IEMOP_RAISE_INVALID_OPCODE();
    7400         case 1:
    7401             /** @todo Testcase: Check prefix effects on cmpxchg8b/16b. */
    7402             if (   (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)
    7403                 || (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ))) /** @todo Testcase: AMD seems to express a different idea here wrt prefixes. */
    7404                 return IEMOP_RAISE_INVALID_OPCODE();
    7405             if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_REX_W)
    7406                 return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg16b_Mdq, bRm);
    7407             return FNIEMOP_CALL_1(iemOp_Grp9_cmpxchg8b_Mq, bRm);
    7408         case 6:
    7409             if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
    7410                 return FNIEMOP_CALL_1(iemOp_Grp9_rdrand_Rv, bRm);
    7411             switch (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ))
    7412             {
    7413                 case 0:
    7414                     return FNIEMOP_CALL_1(iemOp_Grp9_vmptrld_Mq, bRm);
    7415                 case IEM_OP_PRF_SIZE_OP:
    7416                     return FNIEMOP_CALL_1(iemOp_Grp9_vmclear_Mq, bRm);
    7417                 case IEM_OP_PRF_REPZ:
    7418                     return FNIEMOP_CALL_1(iemOp_Grp9_vmxon_Mq, bRm);
    7419                 default:
    7420                     return IEMOP_RAISE_INVALID_OPCODE();
    7421             }
    7422         case 7:
    7423             switch (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ))
    7424             {
    7425                 case 0:
    7426                 case IEM_OP_PRF_REPZ:
    7427                     return FNIEMOP_CALL_1(iemOp_Grp9_vmptrst_Mq, bRm);
    7428                 default:
    7429                     return IEMOP_RAISE_INVALID_OPCODE();
    7430             }
    7431         IEM_NOT_REACHED_DEFAULT_CASE_RET();
    7432     }
     7437    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     7438    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
     7439        /* register, register */
     7440        return FNIEMOP_CALL_1(g_apfnGroup9RegReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
     7441                                                 + pVCpu->iem.s.idxPrefix], bRm);
     7442    /* memory, register */
     7443    return FNIEMOP_CALL_1(g_apfnGroup9MemReg[ ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) * 4
     7444                                             + pVCpu->iem.s.idxPrefix], bRm);
    74337445}
    74347446
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-decoding-1.c32

    r66341 r66342  
    406406CPUDECODE1UDTST const g_aUdTest2Byte_0f[] =
    407407{
    408 #if 1
     408#if 0
    409409    {  UD_T_EXACT, 2, { 0x0f, 0x04 }, UD_F_ANY_PFX },
    410410    {  UD_T_EXACT, 2, { 0x0f, 0x0a }, UD_F_ANY_PFX },
     
    536536    {  UD_T_MODRM_MR0, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    537537    {  UD_T_MODRM_RR0, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    538     //{  UD_T_MODRM_MR1, 2, { 0x0f, 0xc7 }, xxxx }, - cmpxchg8b/16b is weird, needs special testcase.
     538    //{  UD_T_MODRM_MR1, 2, { 0x0f, 0xc7 }, UD_F_NOT_NO_PFX | UD_F_NOT_OZ_PFX | UD_F_NOT_RN_PFX | UD_F_NOT_RZ_PFX | UD_F_NOT_LK_PFX }, - cmpxchg8b ignores everything. @
    539539    {  UD_T_MODRM_RR1, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    540540    {  UD_T_MODRM_MR2, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
     
    546546    {  UD_T_MODRM_MR5, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    547547    {  UD_T_MODRM_RR5, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    548     //{  UD_T_MODRM_MR0, 2, { 0x0f, 0xc7 }, UD_F_NOT_OZ_PFX | UD_F_NOT_RN_PFX |  },
    549     {  UD_T_MODRM_RR0, 2, { 0x0f, 0xc7 }, UD_F_ANY_PFX },
    550 #if 1
     548    {  UD_T_MODRM_MR6, 2, { 0x0f, 0xc7 }, UD_F_NOT_NO_PFX | UD_F_NOT_OZ_PFX | UD_F_NOT_RZ_PFX }, /* f2? */
     549    {  UD_T_MODRM_RR6, 2, { 0x0f, 0xc7 }, UD_F_NOT_NO_PFX | UD_F_NOT_OZ_PFX }, /* (rdrand Rv) */
     550    {  UD_T_MODRM_MR7, 2, { 0x0f, 0xc7 }, UD_F_NOT_NO_PFX }, /* vmptrst Mq (f2?); */
     551    {  UD_T_MODRM_RR7, 2, { 0x0f, 0xc7 }, UD_F_NOT_NO_PFX | UD_F_NOT_OZ_PFX | UD_F_NOT_RZ_PFX }, /* rdrand Rv; rdpid Rd/q (f2,66??); */
     552#if 0
    551553    {  UD_T_MODRM, 2, { 0x0f, 0xd0 }, UD_F_NOT_OZ_PFX | UD_F_NOT_RN_PFX },
    552554    {  UD_T_MODRM, 2, { 0x0f, 0xd1 }, UD_F_NOT_NO_PFX | UD_F_NOT_OZ_PFX },
     
    12901292
    12911293
     1294#if 0
     1295/**
     1296 * Checks how prefixes affects cmpxchg8b and cmpxchg16b
     1297 *
     1298 * The thing here is that the intel opcode tables indicates that the 66 and f3
     1299 * prefixes encodings are reserved and causes \#UD, where AMD doesn't.  Seems
     1300 * though that the f2, f3 and 66 prefixes are ignored on skylake intel.  Need to
     1301 * make sure this is the case, also in 64-bit mode and for the 16b version.
     1302 */
     1303static void DecodeCmpXchg8bVs16b(void)
     1304{
     1305    uint8_t BS3_FAR *pbPages;
     1306
     1307    /* Check that the instructions are supported. */
     1308    if (   !(g_uBs3CpuDetected & BS3CPU_F_CPUID)
     1309        || !(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_CX8))
     1310    {
     1311        Bs3TestSkipped("not supported");
     1312        return;
     1313    }
     1314
     1315    /* Setup a guarded page. */
     1316    pbPages = Bs3MemGuardedTestPageAlloc(BS3MEMKIND_FLAT32);
     1317    if (pbPages)
     1318    {
     1319
     1320        Bs3MemGuardedTestPageFree(pbPages);
     1321    }
     1322    else
     1323        Bs3TestFailed("Failed to allocate two pages!\n");
     1324}
     1325#endif
     1326
     1327
    12921328/**
    12931329 * Checks various prefix encodings with the MOVBE and CRC32 instructions to try
     
    16611697    Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    16621698
    1663 #if 1
     1699#if 0
    16641700    Bs3TestSub("CMPPS, CMPPD, CMPSS, CMPSD");
    16651701    DecodeCmppsCmppdCmpssCmpsd();
     
    16681704    DecodeMovbeVsCrc32();
    16691705#endif
     1706
     1707    //Bs3TestSub("CMPXCHG8B/16B");
     1708    //DecodeCmpXchg8bVs16b();
    16701709
    16711710#if 1
     
    16731712    DecodeUdEdgeTest(g_aUdTest2Byte_0f, RT_ELEMENTS(g_aUdTest2Byte_0f));
    16741713#endif
    1675 #if 1
     1714#if 0
    16761715    Bs3TestSub("3 byte undefined opcodes 0f 38");
    16771716    DecodeUdEdgeTest(g_aUdTest3Byte_0f_38, RT_ELEMENTS(g_aUdTest3Byte_0f_38));
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2-template.c

    r65507 r66342  
    5454extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_cmpxchg16b_rdi_ud2);
    5555extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_lock_cmpxchg16b_rdi_ud2);
     56extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_o16_cmpxchg16b_rdi_ud2);
     57extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_lock_o16_cmpxchg16b_rdi_ud2);
     58extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_repz_cmpxchg16b_rdi_ud2);
     59extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_lock_repz_cmpxchg16b_rdi_ud2);
     60extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_repnz_cmpxchg16b_rdi_ud2);
     61extern FNBS3FAR     BS3_CMN_NM(bs3CpuInstr2_lock_repnz_cmpxchg16b_rdi_ud2);
    5662# endif
    5763#endif
     
    550556    PRTUINT128U     pau128       = RT_ALIGN_PT(&au128[0], sizeof(RTUINT128U), PRTUINT128U);
    551557    bool const      fSupportCX16 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16);
    552     unsigned        iLocked;
    553558    unsigned        iFlags;
    554559    unsigned        offBuf;
    555560    unsigned        iMatch;
     561    unsigned        iWorker;
     562    static struct
     563    {
     564        bool        fLocked;
     565        uint8_t     offUd2;
     566        FNBS3FAR   *pfnWorker;
     567    } const s_aWorkers[] =
     568    {
     569        {   false,  4,  BS3_CMN_NM(bs3CpuInstr2_cmpxchg16b_rdi_ud2) },
     570        {   false,  5,  BS3_CMN_NM(bs3CpuInstr2_o16_cmpxchg16b_rdi_ud2) },
     571        {   false,  5,  BS3_CMN_NM(bs3CpuInstr2_repz_cmpxchg16b_rdi_ud2) },
     572        {   false,  5,  BS3_CMN_NM(bs3CpuInstr2_repnz_cmpxchg16b_rdi_ud2) },
     573        {   true, 1+4,  BS3_CMN_NM(bs3CpuInstr2_lock_cmpxchg16b_rdi_ud2) },
     574        {   true, 1+5,  BS3_CMN_NM(bs3CpuInstr2_lock_o16_cmpxchg16b_rdi_ud2) },
     575        {   true, 1+5,  BS3_CMN_NM(bs3CpuInstr2_lock_repz_cmpxchg16b_rdi_ud2) },
     576        {   true, 1+5,  BS3_CMN_NM(bs3CpuInstr2_lock_repnz_cmpxchg16b_rdi_ud2) },
     577    };
    556578
    557579    /* Ensure the structures are allocated before we sample the stack pointer. */
     
    572594     */
    573595    g_usBs3TestStep = 0;
    574     Bs3RegCtxSetRipCsFromCurPtr(&Ctx, BS3_CMN_NM(bs3CpuInstr2_cmpxchg16b_rdi_ud2));
    575     for (iLocked = 0; iLocked < 2; iLocked++)
    576     {
     596    for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++)
     597    {
     598        Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker);
     599
    577600        /*
    578601         * One loop with all status flags set, and one with them clear.
     
    604627                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
    605628                    g_usBs3TestStep++;
    606                     //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u\n", iFlags, offBuf, iMatch);
     629                    //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker);
    607630                    bExpectXcpt = X86_XCPT_UD;
    608631                    if (fSupportCX16)
     
    622645                            else
    623646                                ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;
    624                             ExpectCtx.rip.u = Ctx.rip.u + 4 + (iLocked & 1);
     647                            ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offUd2;
    625648                        }
    626649                        ExpectCtx.rflags.u32 |= X86_EFL_RF;
     
    632655                        if (TrapFrame.bXcpt != bExpectXcpt)
    633656                            Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd);
    634                         Bs3TestFailedF("^^^ iLocked=%d iFlags=%d offBuf=%d iMatch=%u\n", iLocked, iFlags, offBuf, iMatch);
     657                        Bs3TestFailedF("^^^ iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", iWorker, iFlags, offBuf, iMatch);
    635658                        ASMHalt();
    636659                    }
     
    642665            Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
    643666        }
    644         Bs3RegCtxSetRipCsFromCurPtr(&Ctx, BS3_CMN_NM(bs3CpuInstr2_lock_cmpxchg16b_rdi_ud2));
    645667    }
    646668
    647669    return 0;
    648 
    649670}
    650671# endif /* ARCH_BITS == 64 */
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2-template.mac

    r65507 r66342  
    101101AssertCompile(.again - BS3_LAST_LABEL == 5)
    102102BS3_PROC_END_CMN   bs3CpuInstr2_lock_cmpxchg16b_rdi_ud2
     103
     104
     105BS3_PROC_BEGIN_CMN bs3CpuInstr2_o16_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     106        o16 cmpxchg16b [rdi]
     107.again:
     108        ud2
     109        jmp     .again
     110AssertCompile(.again - BS3_LAST_LABEL == 5)
     111BS3_PROC_END_CMN   bs3CpuInstr2_o16_cmpxchg16b_rdi_ud2
     112
     113
     114BS3_PROC_BEGIN_CMN bs3CpuInstr2_lock_o16_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     115        db 0f0h, 066h
     116        cmpxchg16b [rdi]
     117.again:
     118        ud2
     119        jmp     .again
     120AssertCompile(.again - BS3_LAST_LABEL == 6)
     121BS3_PROC_END_CMN   bs3CpuInstr2_lock_o16_cmpxchg16b_rdi_ud2
     122
     123
     124BS3_PROC_BEGIN_CMN bs3CpuInstr2_repz_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     125        repz cmpxchg16b [rdi]
     126.again:
     127        ud2
     128        jmp     .again
     129AssertCompile(.again - BS3_LAST_LABEL == 5)
     130BS3_PROC_END_CMN   bs3CpuInstr2_repz_cmpxchg16b_rdi_ud2
     131
     132
     133BS3_PROC_BEGIN_CMN bs3CpuInstr2_lock_repz_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     134        db 0f0h, 0f3h
     135        cmpxchg16b [rdi]
     136.again:
     137        ud2
     138        jmp     .again
     139AssertCompile(.again - BS3_LAST_LABEL == 6)
     140BS3_PROC_END_CMN   bs3CpuInstr2_lock_repz_cmpxchg16b_rdi_ud2
     141
     142BS3_PROC_BEGIN_CMN bs3CpuInstr2_repnz_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     143        repnz cmpxchg16b [rdi]
     144.again:
     145        ud2
     146        jmp     .again
     147AssertCompile(.again - BS3_LAST_LABEL == 5)
     148BS3_PROC_END_CMN   bs3CpuInstr2_repnz_cmpxchg16b_rdi_ud2
     149
     150
     151BS3_PROC_BEGIN_CMN bs3CpuInstr2_lock_repnz_cmpxchg16b_rdi_ud2, BS3_PBC_NEAR
     152        db 0f0h, 0f2h
     153        cmpxchg16b [rdi]
     154.again:
     155        ud2
     156        jmp     .again
     157AssertCompile(.again - BS3_LAST_LABEL == 6)
     158BS3_PROC_END_CMN   bs3CpuInstr2_lock_repnz_cmpxchg16b_rdi_ud2
     159
     160;; @todo figure out this fudge. sigh.
     161times (348) db 0cch ; fudge to avoid 'rderr' during boot.
     162
    103163 %endif ; TMPL_BITS == 64
    104164
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