VirtualBox

Ignore:
Timestamp:
Mar 18, 2024 2:59:49 PM (11 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162268
Message:

ValKit/bs3-cpu-instr-3: Extended the test worker with checking #PF priority. bugref:10370

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3.c32

    r103887 r103896  
    145145/** Buffer of g_cbBuf size. */
    146146static uint8_t BS3_FAR *g_pbBuf;
     147/** RW alias for the buffer memory at g_pbBuf. Set up by bs3CpuInstr3BufSetup. */
     148static uint8_t BS3_FAR *g_pbBufAlias;
     149/** RW alias for the memory at g_pbBuf. */
     150static uint8_t BS3_FAR *g_pbBufAliasAlloc;
    147151
    148152/** Exception type \#1 test configurations, 16 & 32 bytes strictly aligned. */
     
    480484    if (BS3_MODE_IS_PAGED(bMode))
    481485    {
     486        int      rc;
    482487        uint32_t cbBuf = *pcbBuf;
    483488        Bs3PagingProtectPtr(&pbBuf[0], X86_PAGE_SIZE, 0, X86_PTE_P);
     
    486491        cbBuf  -= X86_PAGE_SIZE * 2;
    487492        *pcbBuf = cbBuf;
     493
     494        g_pbBufAlias = g_pbBufAliasAlloc;
     495        rc = Bs3PagingAlias((uintptr_t)g_pbBufAlias, (uintptr_t)pbBuf, cbBuf + X86_PAGE_SIZE, /* must include the tail guard pg */
     496                            X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);
     497        if (RT_FAILURE(rc))
     498            Bs3TestFailedF("Bs3PagingAlias failed on %p/%p LB %#x: %d", g_pbBufAlias, pbBuf, cbBuf, rc);
    488499    }
     500    else
     501        g_pbBufAlias = pbBuf;
    489502    return pbBuf;
    490503}
     
    518531 * @param   cbAlign     The operand alignment restriction.
    519532 * @param   pConfig     The configuration.
     533 * @param   fPageFault  The \#PF test setting.
    520534 */
    521535DECLINLINE(PRTUINT256U) bs3CpuInstr3BufForOperand(uint8_t BS3_FAR *pbBuf, uint32_t cbBuf, uint8_t cbMemOp, uint8_t cbAlign,
    522                                                   PCBS3CPUINSTR3_CONFIG_T pConfig)
    523 {
     536                                                  PCBS3CPUINSTR3_CONFIG_T pConfig, unsigned fPageFault)
     537{
     538    /* All allocations are at the tail end of the buffer, so that we've got a
     539       guard page following the operand.   When asked to consistenly trigger
     540       a #PF, we slide the buffer into that guard page. */
     541    if (fPageFault)
     542        cbBuf += X86_PAGE_SIZE;
     543
    524544    if (pConfig->fAligned)
    525545    {
     
    714734    for (;;)
    715735    {
    716         unsigned iCfg;
    717         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     736        unsigned fPf = 0;
     737        do
    718738        {
    719             unsigned                    iTest;
    720             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    721             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    722                 continue; /* unsupported config */
    723 
    724             /*
    725              * Iterate the tests.
    726              */
    727             for (iTest = 0; iTest < cTests; iTest++)
     739            unsigned iCfg;
     740            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    728741            {
    729                 BS3CPUINSTR3_TEST1_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    730                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    731                 unsigned const  cValues     = paTests[iTest].cValues;
    732                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    733                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    734                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    735                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    736                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    737                 uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
    738                 uint8_t const   cbAlign     = cbMemOp;
    739                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    740                 uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
    741                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    742                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    743                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    744                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    745                 unsigned        cRecompRuns = 0;
    746                 unsigned        iVal;
    747 
    748                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    749                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    750                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    751                     continue;
    752 
    753                 /* #AC is only raised in ring-3.: */
    754                 if (bXcptExpect == X86_XCPT_AC)
     742                unsigned                    iTest;
     743                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     744                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     745                    continue; /* unsupported config */
     746
     747                /*
     748                 * Iterate the tests.
     749                 */
     750                for (iTest = 0; iTest < cTests; iTest++)
    755751                {
    756                     if (bRing != 3)
    757                         bXcptExpect = X86_XCPT_DB;
    758                     else if (fAvxInstr)
    759                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     752                    BS3CPUINSTR3_TEST1_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     753                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     754                    unsigned const  cValues     = paTests[iTest].cValues;
     755                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     756                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     757                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     758                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     759                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     760                    uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
     761                    uint8_t const   cbAlign     = cbMemOp;
     762                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     763                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     764                    uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     765                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     766                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     767                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     768                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     769                    unsigned        cRecompRuns = 0;
     770                    unsigned        iVal;
     771
     772                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
     773                       allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     774                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     775                        continue;
     776
     777                    /* #AC is only raised in ring-3.: */
     778                    if (bXcptExpect == X86_XCPT_AC)
     779                    {
     780                        if (bRing != 3)
     781                            bXcptExpect = X86_XCPT_DB;
     782                        else if (fAvxInstr)
     783                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     784                    }
     785
     786                    if (fPf && bXcptExpect == X86_XCPT_DB)
     787                        bXcptExpect = X86_XCPT_PF;
     788
     789                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     790
     791                    /*
     792                     * Iterate the test values and do the actual testing.
     793                     */
     794                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
     795                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     796                        {
     797                            uint16_t   cErrors;
     798                            uint16_t   uSavedFtw = 0xff;
     799                            RTUINT256U uMemOpExpect;
     800
     801                            if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
     802
     803                            /*
     804                             * Set up the context and some expectations.
     805                             */
     806                            /* dest */
     807                            if (paTests[iTest].iRegDst == UINT8_MAX)
     808                            {
     809                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     810                                Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     811                                if (bXcptExpect == X86_XCPT_DB)
     812                                    uMemOpExpect = paValues[iVal].uDstOut;
     813                                else
     814                                    Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     815                            }
     816                            else if (fMmxInstr)
     817                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     818
     819                            /* source #1 (/ destination for MMX and SSE) */
     820                            if (paTests[iTest].iRegSrc1 == UINT8_MAX)
     821                            {
     822                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     823                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp);
     824                                if (paTests[iTest].iRegDst == UINT8_MAX)
     825                                    BS3_ASSERT(fSseInstr);
     826                                else
     827                                    uMemOpExpect = paValues[iVal].uSrc1;
     828                            }
     829                            else if (fMmxInstr)
     830                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     831                            else if (fSseInstr)
     832                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
     833                            else
     834                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
     835
     836                            /* source #2 */
     837                            if (paTests[iTest].iRegSrc2 == UINT8_MAX)
     838                            {
     839                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     840                                BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
     841                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp);
     842                                uMemOpExpect = paValues[iVal].uSrc2;
     843                            }
     844                            else if (fMmxInstr)
     845                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     846                            else if (fSseInstr)
     847                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
     848                            else
     849                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
     850
     851                            /* Memory pointer. */
     852                            if (paTests[iTest].enmRm >= RM_MEM)
     853                            {
     854                                BS3_ASSERT(   paTests[iTest].iRegDst  == UINT8_MAX
     855                                           || paTests[iTest].iRegSrc1 == UINT8_MAX
     856                                           || paTests[iTest].iRegSrc2 == UINT8_MAX);
     857                                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     858                            }
     859
     860                            /*
     861                             * Execute.
     862                             */
     863                            Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     864
     865                            /*
     866                             * Check the result:
     867                             */
     868                            cErrors = Bs3TestSubErrorCount();
     869
     870                            if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
     871                            {
     872                                uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     873                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */
     874                            }
     875                            if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
     876                            {
     877                                if (fMmxInstr)
     878                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
     879                                else if (fSseInstr)
     880                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
     881                                else
     882                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
     883                            }
     884#if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
     885                            if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
     886                                && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
     887                                && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
     888                                pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
     889#endif
     890                            Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     891
     892                            if (TrapFrame.bXcpt != bXcptExpect)
     893                                Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     894
     895                            /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     896                            if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     897                            {
     898                                if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     899                                    Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     900                                TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     901                            }
     902                            if (bXcptExpect == X86_XCPT_PF)
     903                                Ctx.cr2.u = (uintptr_t)puMemOp;
     904                            Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     905                                                 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     906                                                 pszMode, idTestStep);
     907                            Ctx.cr2.u = 0;
     908
     909                            if (   paTests[iTest].enmRm >= RM_MEM
     910                                && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     911                                Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     912
     913                            if (cErrors != Bs3TestSubErrorCount())
     914                            {
     915                                if (paConfigs[iCfg].fAligned)
     916                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
     917                                                   bRing, iCfg, iTest, iVal, bXcptExpect);
     918                                else
     919                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     920                                                   bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     921                                Bs3TestPrintf("\n");
     922                            }
     923
     924                            if (uSavedFtw != 0xff)
     925                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
     926                        }
    760927                }
    761928
    762                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    763 
    764                 /*
    765                  * Iterate the test values and do the actual testing.
    766                  */
    767                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
    768                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    769                     {
    770                         uint16_t   cErrors;
    771                         uint16_t   uSavedFtw = 0xff;
    772                         RTUINT256U uMemOpExpect;
    773 
    774                         if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
    775 
    776                         /*
    777                          * Set up the context and some expectations.
    778                          */
    779                         /* dest */
    780                         if (paTests[iTest].iRegDst == UINT8_MAX)
    781                         {
    782                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    783                             Bs3MemSet(puMemOp, 0xcc, cbMemOp);
    784                             if (bXcptExpect == X86_XCPT_DB)
    785                                 uMemOpExpect = paValues[iVal].uDstOut;
    786                             else
    787                                 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    788                         }
    789                         else if (fMmxInstr)
    790                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    791 
    792                         /* source #1 (/ destination for MMX and SSE) */
    793                         if (paTests[iTest].iRegSrc1 == UINT8_MAX)
    794                         {
    795                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    796                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp);
    797                             if (paTests[iTest].iRegDst == UINT8_MAX)
    798                                 BS3_ASSERT(fSseInstr);
    799                             else
    800                                 uMemOpExpect = paValues[iVal].uSrc1;
    801                         }
    802                         else if (fMmxInstr)
    803                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    804                         else if (fSseInstr)
    805                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
    806                         else
    807                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
    808 
    809                         /* source #2 */
    810                         if (paTests[iTest].iRegSrc2 == UINT8_MAX)
    811                         {
    812                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    813                             BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
    814                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp);
    815                             uMemOpExpect = paValues[iVal].uSrc2;
    816                         }
    817                         else if (fMmxInstr)
    818                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    819                         else if (fSseInstr)
    820                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
    821                         else
    822                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
    823 
    824                         /* Memory pointer. */
    825                         if (paTests[iTest].enmRm >= RM_MEM)
    826                         {
    827                             BS3_ASSERT(   paTests[iTest].iRegDst  == UINT8_MAX
    828                                        || paTests[iTest].iRegSrc1 == UINT8_MAX
    829                                        || paTests[iTest].iRegSrc2 == UINT8_MAX);
    830                             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    831                         }
    832 
    833                         /*
    834                          * Execute.
    835                          */
    836                         Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    837 
    838                         /*
    839                          * Check the result:
    840                          */
    841                         cErrors = Bs3TestSubErrorCount();
    842 
    843                         if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
    844                         {
    845                             uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    846                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */
    847                         }
    848                         if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
    849                         {
    850                             if (fMmxInstr)
    851                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
    852                             else if (fSseInstr)
    853                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
    854                             else
    855                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
    856                         }
    857     #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
    858                         if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
    859                             && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
    860                             && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
    861                             pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
    862     #endif
    863                         Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    864 
    865                         if (TrapFrame.bXcpt != bXcptExpect)
    866                             Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    867 
    868                         /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    869                         if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    870                         {
    871                             if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    872                                 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    873                             TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    874                         }
    875                         Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    876                                              bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    877                                              pszMode, idTestStep);
    878 
    879                         if (   paTests[iTest].enmRm >= RM_MEM
    880                             && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    881                             Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    882 
    883                         if (cErrors != Bs3TestSubErrorCount())
    884                         {
    885                             if (paConfigs[iCfg].fAligned)
    886                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
    887                                                bRing, iCfg, iTest, iVal, bXcptExpect);
    888                             else
    889                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    890                                                bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    891                             Bs3TestPrintf("\n");
    892                         }
    893 
    894                         if (uSavedFtw != 0xff)
    895                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    896                     }
     929                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    897930            }
    898 
    899             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    900         }
     931        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    901932
    902933        /*
     
    91879218    for (;;)
    91889219    {
    9189         unsigned iCfg;
    9190         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     9220        unsigned fPf = 0;
     9221        do
    91919222        {
    9192             unsigned                    iTest;
    9193             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    9194             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    9195                 continue; /* unsupported config */
    9196 
    9197             /*
    9198              * Iterate the tests.
    9199              */
    9200             for (iTest = 0; iTest < cTests; iTest++)
     9223            unsigned iCfg;
     9224            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    92019225            {
    9202                 BS3CPUINSTR3_TEST2_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    9203                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    9204                 unsigned const  cValues     = paTests[iTest].cValues;
    9205                 bool const      fGprDst     = paTests[iTest].fGprDst;
    9206                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    9207                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    9208                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    9209                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    9210                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    9211                 uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
    9212                 uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
    9213                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    9214                 uint8_t         bXcptExpect =    !g_afTypeSupports[paTests[iTest].enmType]
    9215                                               || paTests[iTest].fInvalidEncoding ? X86_XCPT_UD
    9216                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    9217                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    9218                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    9219                 uint64_t const  fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX
    9220                                             : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1;
    9221                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    9222                 unsigned        cRecompRuns = 0;
    9223                 unsigned        iVal;
    9224 
    9225                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    9226                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    9227                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    9228                     continue;
    9229 
    9230                 /* #AC is only raised in ring-3.: */
    9231                 if (bXcptExpect == X86_XCPT_AC)
     9226                unsigned                    iTest;
     9227                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     9228                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     9229                    continue; /* unsupported config */
     9230
     9231                /*
     9232                 * Iterate the tests.
     9233                 */
     9234                for (iTest = 0; iTest < cTests; iTest++)
    92329235                {
    9233                     if (bRing != 3)
    9234                         bXcptExpect = X86_XCPT_DB;
    9235                     else if (fAvxInstr)
    9236                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
    9237                 }
    9238 
    9239                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    9240 
    9241                 /*
    9242                  * Iterate the test values and do the actual testing.
    9243                  */
    9244                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
    9245                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     9236                    BS3CPUINSTR3_TEST2_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     9237                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     9238                    unsigned const  cValues     = paTests[iTest].cValues;
     9239                    bool const      fGprDst     = paTests[iTest].fGprDst;
     9240                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     9241                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     9242                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     9243                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     9244                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     9245                    uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
     9246                    uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
     9247                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     9248                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     9249                    uint8_t         bXcptExpect =    !g_afTypeSupports[paTests[iTest].enmType]
     9250                                                  || paTests[iTest].fInvalidEncoding ? X86_XCPT_UD
     9251                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     9252                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     9253                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     9254                    uint64_t const  fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX
     9255                                                : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1;
     9256                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     9257                    unsigned        cRecompRuns = 0;
     9258                    unsigned        iVal;
     9259
     9260                    /* If testing unaligned memory accesses (or #PFs), skip register-only tests.  This
     9261                       allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     9262                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     9263                        continue;
     9264
     9265                    /* #AC is only raised in ring-3.: */
     9266                    if (bXcptExpect == X86_XCPT_AC)
    92469267                    {
    9247                         uint16_t   cErrors;
    9248                         uint16_t   uSavedFtw = 0xff;
    9249                         RTUINT256U uMemOpExpect;
    9250 
    9251                         if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
    9252 
    9253                         /*
    9254                          * Set up the context and some expectations.
    9255                          */
    9256                         if (fGprDst)
     9268                        if (bRing != 3)
     9269                            bXcptExpect = X86_XCPT_DB;
     9270                        else if (fAvxInstr)
     9271                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     9272                    }
     9273
     9274                    if (fPf && bXcptExpect == X86_XCPT_DB)
     9275                        bXcptExpect = X86_XCPT_PF;
     9276
     9277                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     9278
     9279                    /*
     9280                     * Iterate the test values and do the actual testing.
     9281                     */
     9282                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
     9283                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    92579284                        {
    9258                             /* dest - gpr/mem */
    9259                             if (paTests[iTest].iGprReg == UINT8_MAX)
     9285                            uint16_t   cErrors;
     9286                            uint16_t   uSavedFtw = 0xff;
     9287                            RTUINT256U uMemOpExpect;
     9288
     9289                            if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
     9290
     9291                            /*
     9292                             * Set up the context and some expectations.
     9293                             */
     9294                            if (fGprDst)
    92609295                            {
    9261                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9262                                 Bs3MemSet(puMemOp, 0xcc, cbMemOp);
    9263                                 if (bXcptExpect != X86_XCPT_DB)
    9264                                     Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    9265                                 else
     9296                                /* dest - gpr/mem */
     9297                                if (paTests[iTest].iGprReg == UINT8_MAX)
    92669298                                {
    9267                                     Bs3MemSet(&uMemOpExpect, 0xaa, sizeof(uMemOpExpect));
    9268                                     switch (paTests[iTest].cbGpr)
     9299                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     9300                                    Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     9301                                    if (bXcptExpect != X86_XCPT_DB)
     9302                                        Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     9303                                    else
    92699304                                    {
    9270                                         case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
    9271                                         case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
    9272                                         case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
    9273                                         case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
    9274                                         default: BS3_ASSERT(0);
     9305                                        Bs3MemSet(&uMemOpExpect, 0xaa, sizeof(uMemOpExpect));
     9306                                        switch (paTests[iTest].cbGpr)
     9307                                        {
     9308                                            case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
     9309                                            case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
     9310                                            case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
     9311                                            case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
     9312                                            default: BS3_ASSERT(0);
     9313                                        }
    92759314                                    }
    92769315                                }
     9316                                else
     9317                                    Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, UINT64_C(0xcccccccccccccccc),
     9318                                                    BS3_MODE_IS_64BIT_CODE(bMode) ? 8 : 4); /* we only restore 63:32 when bMode==LM64 */
     9319
     9320                                /* source - media/mem */
     9321                                if (paTests[iTest].iMediaReg == UINT8_MAX)
     9322                                {
     9323                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     9324                                    BS3_ASSERT(paTests[iTest].iGprReg != UINT8_MAX);
     9325                                    Bs3MemCpy(puMemOpAlias, &paValues[iVal].uMedia, cbMemOp);
     9326                                    uMemOpExpect = paValues[iVal].uMedia;
     9327                                }
     9328                                else if (fMmxInstr)
     9329                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     9330                                else if (fSseInstr)
     9331                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0);
     9332                                else
     9333                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32);
    92779334                            }
    92789335                            else
    9279                                 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, UINT64_C(0xcccccccccccccccc),
    9280                                                 BS3_MODE_IS_64BIT_CODE(bMode) ? 8 : 4); /* we only restore 63:32 when bMode==LM64 */
    9281 
    9282                             /* source - media/mem */
    9283                             if (paTests[iTest].iMediaReg == UINT8_MAX)
    92849336                            {
    9285                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9286                                 BS3_ASSERT(paTests[iTest].iGprReg != UINT8_MAX);
    9287                                 Bs3MemCpy(puMemOp, &paValues[iVal].uMedia, cbMemOp);
    9288                                 uMemOpExpect = paValues[iVal].uMedia;
     9337                                /* dest - media */
     9338                                if (paTests[iTest].iMediaReg == UINT8_MAX)
     9339                                {
     9340                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     9341                                    Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     9342                                    if (bXcptExpect == X86_XCPT_DB)
     9343                                        uMemOpExpect = paValues[iVal].uMedia;
     9344                                    else
     9345                                        Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     9346                                }
     9347
     9348                                /* source - gpr/mem */
     9349                                if (paTests[iTest].iGprReg == UINT8_MAX)
     9350                                {
     9351                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     9352                                    Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     9353                                    if (bXcptExpect == X86_XCPT_DB)
     9354                                        switch (paTests[iTest].cbGpr)
     9355                                        {
     9356                                            case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
     9357                                            case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
     9358                                            case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
     9359                                            case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
     9360                                            default: BS3_ASSERT(0);
     9361                                        }
     9362                                    Bs3MemCpy(puMemOpAlias, &uMemOpExpect, cbMemOp);
     9363                                }
     9364                                else
     9365                                    Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr);
    92899366                            }
    9290                             else if (fMmxInstr)
    9291                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    9292                             else if (fSseInstr)
    9293                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0);
    9294                             else
    9295                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32);
     9367
     9368                            /* Memory pointer. */
     9369                            if (paTests[iTest].enmRm >= RM_MEM)
     9370                            {
     9371                                BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaReg == UINT8_MAX);
     9372                                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     9373                            }
     9374
     9375                            /*
     9376                             * Execute.
     9377                             */
     9378                            Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     9379
     9380                            /*
     9381                             * Check the result:
     9382                             */
     9383                            cErrors = Bs3TestSubErrorCount();
     9384
     9385                            if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
     9386                            {
     9387                                uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     9388                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
     9389                            }
     9390                            if (!fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iMediaReg != UINT8_MAX)
     9391                            {
     9392                                if (fMmxInstr)
     9393                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_SET);
     9394                                else if (fSseInstr)
     9395                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0);
     9396                                else
     9397                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32);
     9398                            }
     9399                            Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     9400
     9401                            if (TrapFrame.bXcpt != bXcptExpect)
     9402                                Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     9403
     9404                            if (fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iGprReg != UINT8_MAX)
     9405                                Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask,
     9406                                                paTests[iTest].cbGpr >= 4 ? 8 : paTests[iTest].cbGpr);
     9407                            /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     9408                            if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     9409                            {
     9410                                if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     9411                                    Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     9412                                TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     9413                            }
     9414                            if (bXcptExpect == X86_XCPT_PF)
     9415                                Ctx.cr2.u = (uintptr_t)puMemOp;
     9416                            Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     9417                                                 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     9418                                                 pszMode, idTestStep);
     9419                            Ctx.cr2.u = 0;
     9420
     9421                            if (   paTests[iTest].enmRm >= RM_MEM
     9422                                && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     9423                                Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     9424
     9425                            if (cErrors != Bs3TestSubErrorCount())
     9426                            {
     9427                                if (paConfigs[iCfg].fAligned)
     9428                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
     9429                                                   bRing, iCfg, iTest, iVal, bXcptExpect);
     9430                                else
     9431                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     9432                                                   bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     9433                                Bs3TestPrintf("\n");
     9434                            }
     9435
     9436                            if (uSavedFtw != 0xff)
     9437                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    92969438                        }
    9297                         else
    9298                         {
    9299                             /* dest - media */
    9300                             if (paTests[iTest].iMediaReg == UINT8_MAX)
    9301                             {
    9302                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9303                                 Bs3MemSet(puMemOp, 0xcc, cbMemOp);
    9304                                 if (bXcptExpect == X86_XCPT_DB)
    9305                                     uMemOpExpect = paValues[iVal].uMedia;
    9306                                 else
    9307                                     Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    9308                             }
    9309 
    9310                             /* source - gpr/mem */
    9311                             if (paTests[iTest].iGprReg == UINT8_MAX)
    9312                             {
    9313                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9314                                 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    9315                                 if (bXcptExpect == X86_XCPT_DB)
    9316                                     switch (paTests[iTest].cbGpr)
    9317                                     {
    9318                                         case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
    9319                                         case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
    9320                                         case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
    9321                                         case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
    9322                                         default: BS3_ASSERT(0);
    9323                                     }
    9324                                 Bs3MemCpy(puMemOp, &uMemOpExpect, cbMemOp);
    9325                             }
    9326                             else
    9327                                 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr);
    9328                         }
    9329 
    9330                         /* Memory pointer. */
    9331                         if (paTests[iTest].enmRm >= RM_MEM)
    9332                         {
    9333                             BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaReg == UINT8_MAX);
    9334                             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    9335                         }
    9336 
    9337                         /*
    9338                          * Execute.
    9339                          */
    9340                         Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    9341 
    9342                         /*
    9343                          * Check the result:
    9344                          */
    9345                         cErrors = Bs3TestSubErrorCount();
    9346 
    9347                         if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
    9348                         {
    9349                             uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    9350                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
    9351                         }
    9352                         if (!fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iMediaReg != UINT8_MAX)
    9353                         {
    9354                             if (fMmxInstr)
    9355                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_SET);
    9356                             else if (fSseInstr)
    9357                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0);
    9358                             else
    9359                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32);
    9360                         }
    9361                         Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    9362 
    9363                         if (TrapFrame.bXcpt != bXcptExpect)
    9364                             Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    9365 
    9366                         if (fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iGprReg != UINT8_MAX)
    9367                             Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask,
    9368                                             paTests[iTest].cbGpr >= 4 ? 8 : paTests[iTest].cbGpr);
    9369                         /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    9370                         if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    9371                         {
    9372                             if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    9373                                 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    9374                             TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    9375                         }
    9376                         Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    9377                                              bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    9378                                              pszMode, idTestStep);
    9379 
    9380                         if (   paTests[iTest].enmRm >= RM_MEM
    9381                             && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    9382                             Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    9383 
    9384                         if (cErrors != Bs3TestSubErrorCount())
    9385                         {
    9386                             if (paConfigs[iCfg].fAligned)
    9387                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
    9388                                                bRing, iCfg, iTest, iVal, bXcptExpect);
    9389                             else
    9390                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    9391                                                bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    9392                             Bs3TestPrintf("\n");
    9393                         }
    9394 
    9395                         if (uSavedFtw != 0xff)
    9396                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    9397                     }
     9439                }
     9440
     9441                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    93989442            }
    9399 
    9400             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    9401         }
     9443        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    94029444
    94039445        /*
     
    99069948    for (;;)
    99079949    {
    9908         unsigned iCfg;
    9909         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     9950        unsigned fPf = 0;
     9951        do
    99109952        {
    9911             unsigned                    iTest;
    9912             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    9913             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    9914                 continue; /* unsupported config */
    9915 
    9916             /*
    9917              * Iterate the tests.
    9918              */
    9919             for (iTest = 0; iTest < cTests; iTest++)
     9953            unsigned iCfg;
     9954            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    99209955            {
    9921                 BS3CPUINSTR3_TEST3_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    9922                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    9923                 unsigned const  cValues     = paTests[iTest].cValues;
    9924                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    9925                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    9926                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    9927                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    9928                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    9929                 uint8_t const   cbMemOp     = cbOperand;
    9930                 uint8_t const   cbAlign     = RT_MIN(cbOperand, !cbMaxAlign ? 16 : cbMaxAlign);
    9931                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    9932                 uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
    9933                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    9934                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    9935                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    9936                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    9937                 unsigned        cRecompRuns = 0;
    9938                 unsigned        iVal;
    9939 
    9940                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    9941                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    9942                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    9943                     continue;
    9944 
    9945                 /* #AC is only raised in ring-3.: */
    9946                 if (bXcptExpect == X86_XCPT_AC)
     9956                unsigned                    iTest;
     9957                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     9958                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     9959                    continue; /* unsupported config */
     9960
     9961                /*
     9962                 * Iterate the tests.
     9963                 */
     9964                for (iTest = 0; iTest < cTests; iTest++)
    99479965                {
    9948                     if (bRing != 3)
    9949                         bXcptExpect = X86_XCPT_DB;
    9950                     else if (fAvxInstr)
    9951                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     9966                    BS3CPUINSTR3_TEST3_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     9967                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     9968                    unsigned const  cValues     = paTests[iTest].cValues;
     9969                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     9970                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     9971                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     9972                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     9973                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     9974                    uint8_t const   cbMemOp     = cbOperand;
     9975                    uint8_t const   cbAlign     = RT_MIN(cbOperand, !cbMaxAlign ? 16 : cbMaxAlign);
     9976                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     9977                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     9978                    uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     9979                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     9980                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     9981                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     9982                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     9983                    unsigned        cRecompRuns = 0;
     9984                    unsigned        iVal;
     9985
     9986                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
     9987                        allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     9988                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     9989                        continue;
     9990
     9991                    /* #AC is only raised in ring-3.: */
     9992                    if (bXcptExpect == X86_XCPT_AC)
     9993                    {
     9994                        if (bRing != 3)
     9995                            bXcptExpect = X86_XCPT_DB;
     9996                        else if (fAvxInstr)
     9997                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     9998                    }
     9999
     10000                    if (fPf && bXcptExpect == X86_XCPT_DB)
     10001                        bXcptExpect = X86_XCPT_PF;
     10002
     10003                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     10004
     10005                    /*
     10006                     * Iterate the test values and do the actual testing.
     10007                     */
     10008                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
     10009                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     10010                        {
     10011                            uint16_t   cErrors;
     10012                            uint16_t   uSavedFtw = 0xff;
     10013                            RTUINT256U uMemOpExpect;
     10014
     10015                            if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
     10016
     10017                            /*
     10018                             * Set up the context and some expectations.
     10019                             */
     10020                            /* dest */
     10021                            if (paTests[iTest].iRegDst == UINT8_MAX)
     10022                            {
     10023                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     10024                                Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     10025                                if (bXcptExpect == X86_XCPT_DB)
     10026                                    uMemOpExpect = paValues[iVal].uDstOut;
     10027                                else
     10028                                    Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     10029                            }
     10030                            else if (fMmxInstr)
     10031                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     10032
     10033                            /* source */
     10034                            if (paTests[iTest].iRegSrc == UINT8_MAX)
     10035                            {
     10036                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     10037                                BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX);
     10038                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc, cbMemOp);
     10039                                uMemOpExpect = paValues[iVal].uSrc;
     10040                            }
     10041                            else if (fMmxInstr)
     10042                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, paValues[iVal].uSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     10043                            else if (fSseInstr)
     10044                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc.DQWords.dqw0);
     10045                            else
     10046                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc, 32);
     10047
     10048                            /* Memory pointer. */
     10049                            if (paTests[iTest].enmRm >= RM_MEM)
     10050                            {
     10051                                BS3_ASSERT(   paTests[iTest].iRegDst == UINT8_MAX
     10052                                           || paTests[iTest].iRegSrc == UINT8_MAX);
     10053                                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     10054                            }
     10055
     10056                            /*
     10057                             * Execute.
     10058                             */
     10059                            Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     10060
     10061                            /*
     10062                             * Check the result:
     10063                             */
     10064                            cErrors = Bs3TestSubErrorCount();
     10065
     10066                            if (bXcptExpect == X86_XCPT_DB && fMmxInstr)
     10067                            {
     10068                                uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     10069                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
     10070                            }
     10071                            if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
     10072                            {
     10073                                if (fMmxInstr)
     10074                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
     10075                                else if (fSseInstr)
     10076                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
     10077                                else
     10078                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
     10079                            }
     10080
     10081                            Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     10082
     10083                            if (TrapFrame.bXcpt != bXcptExpect)
     10084                                Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     10085
     10086                            /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     10087                            if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     10088                            {
     10089                                if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     10090                                    Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     10091                                TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     10092                            }
     10093                            if (bXcptExpect == X86_XCPT_PF)
     10094                                Ctx.cr2.u = (uintptr_t)puMemOp;
     10095                            Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     10096                                                 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     10097                                                 pszMode, idTestStep);
     10098                            Ctx.cr2.u = 0;
     10099
     10100                            if (   paTests[iTest].enmRm >= RM_MEM
     10101                                && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     10102                                Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     10103
     10104                            if (cErrors != Bs3TestSubErrorCount())
     10105                            {
     10106                                if (paConfigs[iCfg].fAligned)
     10107                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
     10108                                                   bRing, iCfg, iTest, iVal, bXcptExpect);
     10109                                else
     10110                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     10111                                                   bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     10112                                Bs3TestPrintf("\n");
     10113                            }
     10114
     10115                            if (uSavedFtw != 0xff)
     10116                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
     10117                        }
    995210118                }
    995310119
    9954                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    9955 
    9956                 /*
    9957                  * Iterate the test values and do the actual testing.
    9958                  */
    9959                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
    9960                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    9961                     {
    9962                         uint16_t   cErrors;
    9963                         uint16_t   uSavedFtw = 0xff;
    9964                         RTUINT256U uMemOpExpect;
    9965 
    9966                         if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
    9967 
    9968                         /*
    9969                          * Set up the context and some expectations.
    9970                          */
    9971                         /* dest */
    9972                         if (paTests[iTest].iRegDst == UINT8_MAX)
    9973                         {
    9974                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9975                             Bs3MemSet(puMemOp, 0xcc, cbMemOp);
    9976                             if (bXcptExpect == X86_XCPT_DB)
    9977                                 uMemOpExpect = paValues[iVal].uDstOut;
    9978                             else
    9979                                 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    9980                         }
    9981                         else if (fMmxInstr)
    9982                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    9983 
    9984                         /* source */
    9985                         if (paTests[iTest].iRegSrc == UINT8_MAX)
    9986                         {
    9987                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    9988                             BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX);
    9989                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc, cbMemOp);
    9990                             uMemOpExpect = paValues[iVal].uSrc;
    9991                         }
    9992                         else if (fMmxInstr)
    9993                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, paValues[iVal].uSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    9994                         else if (fSseInstr)
    9995                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc.DQWords.dqw0);
    9996                         else
    9997                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc, 32);
    9998 
    9999                         /* Memory pointer. */
    10000                         if (paTests[iTest].enmRm >= RM_MEM)
    10001                         {
    10002                             BS3_ASSERT(   paTests[iTest].iRegDst == UINT8_MAX
    10003                                        || paTests[iTest].iRegSrc == UINT8_MAX);
    10004                             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    10005                         }
    10006 
    10007                         /*
    10008                          * Execute.
    10009                          */
    10010                         Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    10011 
    10012                         /*
    10013                          * Check the result:
    10014                          */
    10015                         cErrors = Bs3TestSubErrorCount();
    10016 
    10017                         if (bXcptExpect == X86_XCPT_DB && fMmxInstr)
    10018                         {
    10019                             uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    10020                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
    10021                         }
    10022                         if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
    10023                         {
    10024                             if (fMmxInstr)
    10025                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
    10026                             else if (fSseInstr)
    10027                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
    10028                             else
    10029                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
    10030                         }
    10031 
    10032                         Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    10033 
    10034                         if (TrapFrame.bXcpt != bXcptExpect)
    10035                             Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    10036 
    10037                         /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    10038                         if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    10039                         {
    10040                             if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    10041                                 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    10042                             TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    10043                         }
    10044                         Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    10045                                              bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    10046                                              pszMode, idTestStep);
    10047 
    10048                         if (   paTests[iTest].enmRm >= RM_MEM
    10049                             && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    10050                             Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    10051 
    10052                         if (cErrors != Bs3TestSubErrorCount())
    10053                         {
    10054                             if (paConfigs[iCfg].fAligned)
    10055                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
    10056                                                bRing, iCfg, iTest, iVal, bXcptExpect);
    10057                             else
    10058                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    10059                                                bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    10060                             Bs3TestPrintf("\n");
    10061                         }
    10062 
    10063                         if (uSavedFtw != 0xff)
    10064                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    10065                     }
     10120                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    1006610121            }
    10067 
    10068             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    10069         }
     10122        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    1007010123
    1007110124        /*
     
    1211312166    for (;;)
    1211412167    {
    12115         unsigned iCfg;
    12116         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     12168        unsigned fPf = 0;
     12169        do
    1211712170        {
    12118             unsigned                    iTest;
    12119             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    12120             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    12121                 continue; /* unsupported config */
    12122 
    12123             /*
    12124              * Iterate the tests.
    12125              */
    12126             for (iTest = 0; iTest < cTests; iTest++)
     12171            unsigned iCfg;
     12172            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    1212712173            {
    12128                 BS3CPUINSTR3_TEST4_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    12129                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    12130                 unsigned const  cValues     = paTests[iTest].cValues;
    12131                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    12132                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    12133                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    12134                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    12135                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    12136                 uint8_t const   cbMemOp     = cbOperand;
    12137                 uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
    12138                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    12139                 uint8_t const   idxEflOut   = cbOperand == 32 ? 2 : cbOperand == 16 ? 1 : 0;
    12140                 uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
    12141                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    12142                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    12143                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    12144                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    12145                 unsigned        cRecompRuns = 0;
    12146                 unsigned        iVal;
    12147 
    12148                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    12149                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    12150                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    12151                     continue;
    12152 
    12153                 /* #AC is only raised in ring-3.: */
    12154                 if (bXcptExpect == X86_XCPT_AC)
     12174                unsigned                    iTest;
     12175                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     12176                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     12177                    continue; /* unsupported config */
     12178
     12179                /*
     12180                 * Iterate the tests.
     12181                 */
     12182                for (iTest = 0; iTest < cTests; iTest++)
    1215512183                {
    12156                     if (bRing != 3)
    12157                         bXcptExpect = X86_XCPT_DB;
    12158                     else if (fAvxInstr)
    12159                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     12184                    BS3CPUINSTR3_TEST4_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     12185                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     12186                    unsigned const  cValues     = paTests[iTest].cValues;
     12187                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     12188                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     12189                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     12190                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     12191                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     12192                    uint8_t const   cbMemOp     = cbOperand;
     12193                    uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
     12194                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     12195                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     12196                    uint8_t const   idxEflOut   = cbOperand == 32 ? 2 : cbOperand == 16 ? 1 : 0;
     12197                    uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     12198                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     12199                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     12200                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     12201                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     12202                    unsigned        cRecompRuns = 0;
     12203                    unsigned        iVal;
     12204
     12205                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
     12206                       allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     12207                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     12208                        continue;
     12209
     12210                    /* #AC is only raised in ring-3.: */
     12211                    if (bXcptExpect == X86_XCPT_AC)
     12212                    {
     12213                        if (bRing != 3)
     12214                            bXcptExpect = X86_XCPT_DB;
     12215                        else if (fAvxInstr)
     12216                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     12217                    }
     12218
     12219                    if (fPf && bXcptExpect == X86_XCPT_DB)
     12220                        bXcptExpect = X86_XCPT_PF;
     12221
     12222                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     12223
     12224                    /*
     12225                     * Iterate the test values and do the actual testing.
     12226                     */
     12227                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues * 2)
     12228                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     12229                        {
     12230                            unsigned       iEflVariation;
     12231                            uint32_t const fSavedEfl = Ctx.rflags.u32;
     12232                            for (iEflVariation = 0; iEflVariation < 2; iEflVariation++)
     12233                            {
     12234                                uint16_t   cErrors;
     12235                                uint16_t   uSavedFtw = 0xff;
     12236                                RTUINT256U uMemOpExpect;
     12237
     12238                                if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, iEflVariation)) continue;
     12239
     12240                                /*
     12241                                 * Set up the context and some expectations.
     12242                                 */
     12243                                /* eflags */
     12244                                if (iEflVariation)
     12245                                    Ctx.rflags.u32 = fSavedEfl | X86_EFL_STATUS_BITS;
     12246                                else
     12247                                    Ctx.rflags.u32 = fSavedEfl & ~X86_EFL_STATUS_BITS;
     12248
     12249                                /* source1 */
     12250                                if (paTests[iTest].iRegSrc1 == UINT8_MAX)
     12251                                {
     12252                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12253                                    BS3_ASSERT(paTests[iTest].iRegSrc2 != UINT8_MAX);
     12254                                    Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp);
     12255                                    uMemOpExpect = paValues[iVal].uSrc1;
     12256                                }
     12257                                else if (fMmxInstr)
     12258                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12259                                else if (fSseInstr)
     12260                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
     12261                                else
     12262                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
     12263
     12264                                /* source2 */
     12265                                if (paTests[iTest].iRegSrc2 == UINT8_MAX)
     12266                                {
     12267                                    BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12268                                    BS3_ASSERT(paTests[iTest].iRegSrc1 != UINT8_MAX);
     12269                                    Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp);
     12270                                    uMemOpExpect = paValues[iVal].uSrc2;
     12271                                }
     12272                                else if (fMmxInstr)
     12273                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12274                                else if (fSseInstr)
     12275                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
     12276                                else
     12277                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
     12278
     12279                                /* Memory pointer. */
     12280                                if (paTests[iTest].enmRm >= RM_MEM)
     12281                                {
     12282                                    BS3_ASSERT(   paTests[iTest].iRegSrc1 == UINT8_MAX
     12283                                               || paTests[iTest].iRegSrc2 == UINT8_MAX);
     12284                                    Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     12285                                }
     12286
     12287                                /*
     12288                                 * Execute.
     12289                                 */
     12290                                Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     12291
     12292                                /*
     12293                                 * Check the result:
     12294                                 */
     12295                                cErrors = Bs3TestSubErrorCount();
     12296
     12297                                if (bXcptExpect == X86_XCPT_DB && fMmxInstr)
     12298                                {
     12299                                    uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     12300                                    Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
     12301                                }
     12302                                Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     12303
     12304                                if (TrapFrame.bXcpt != bXcptExpect)
     12305                                    Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     12306
     12307                                /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     12308                                if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     12309                                {
     12310                                    if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     12311                                        Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     12312                                    TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     12313                                }
     12314                                if (bXcptExpect == X86_XCPT_DB)
     12315                                    Ctx.rflags.u32 = (Ctx.rflags.u32 & ~fEflCheck) | paValues[iVal].afEflOut[idxEflOut];
     12316                                if (bXcptExpect == X86_XCPT_PF)
     12317                                    Ctx.cr2.u = (uintptr_t)puMemOp;
     12318                                Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     12319                                                     bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     12320                                                     pszMode, idTestStep);
     12321                                Ctx.cr2.u = 0;
     12322
     12323                                if (   paTests[iTest].enmRm >= RM_MEM
     12324                                    && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     12325                                    Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     12326
     12327                                if (cErrors != Bs3TestSubErrorCount())
     12328                                {
     12329                                    if (paConfigs[iCfg].fAligned)
     12330                                        Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x)",
     12331                                                       bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect);
     12332                                    else
     12333                                        Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     12334                                                       bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect,
     12335                                                       puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     12336                                    Bs3TestPrintf("\n");
     12337                                }
     12338
     12339                                if (uSavedFtw != 0xff)
     12340                                    Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
     12341                            }
     12342                            Ctx.rflags.u32 = fSavedEfl;
     12343                        }
    1216012344                }
    1216112345
    12162                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    12163 
    12164                 /*
    12165                  * Iterate the test values and do the actual testing.
    12166                  */
    12167                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues * 2)
    12168                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    12169                     {
    12170                         unsigned       iEflVariation;
    12171                         uint32_t const fSavedEfl = Ctx.rflags.u32;
    12172                         for (iEflVariation = 0; iEflVariation < 2; iEflVariation++)
    12173                         {
    12174                             uint16_t   cErrors;
    12175                             uint16_t   uSavedFtw = 0xff;
    12176                             RTUINT256U uMemOpExpect;
    12177 
    12178                             if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, iEflVariation)) continue;
    12179 
    12180                             /*
    12181                              * Set up the context and some expectations.
    12182                              */
    12183                             /* eflags */
    12184                             if (iEflVariation)
    12185                                 Ctx.rflags.u32 = fSavedEfl | X86_EFL_STATUS_BITS;
    12186                             else
    12187                                 Ctx.rflags.u32 = fSavedEfl & ~X86_EFL_STATUS_BITS;
    12188 
    12189                             /* source1 */
    12190                             if (paTests[iTest].iRegSrc1 == UINT8_MAX)
    12191                             {
    12192                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12193                                 BS3_ASSERT(paTests[iTest].iRegSrc2 != UINT8_MAX);
    12194                                 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp);
    12195                                 uMemOpExpect = paValues[iVal].uSrc1;
    12196                             }
    12197                             else if (fMmxInstr)
    12198                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12199                             else if (fSseInstr)
    12200                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
    12201                             else
    12202                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
    12203 
    12204                             /* source2 */
    12205                             if (paTests[iTest].iRegSrc2 == UINT8_MAX)
    12206                             {
    12207                                 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12208                                 BS3_ASSERT(paTests[iTest].iRegSrc1 != UINT8_MAX);
    12209                                 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp);
    12210                                 uMemOpExpect = paValues[iVal].uSrc2;
    12211                             }
    12212                             else if (fMmxInstr)
    12213                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12214                             else if (fSseInstr)
    12215                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
    12216                             else
    12217                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
    12218 
    12219                             /* Memory pointer. */
    12220                             if (paTests[iTest].enmRm >= RM_MEM)
    12221                             {
    12222                                 BS3_ASSERT(   paTests[iTest].iRegSrc1 == UINT8_MAX
    12223                                            || paTests[iTest].iRegSrc2 == UINT8_MAX);
    12224                                 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    12225                             }
    12226 
    12227                             /*
    12228                              * Execute.
    12229                              */
    12230                             Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    12231 
    12232                             /*
    12233                              * Check the result:
    12234                              */
    12235                             cErrors = Bs3TestSubErrorCount();
    12236 
    12237                             if (bXcptExpect == X86_XCPT_DB && fMmxInstr)
    12238                             {
    12239                                 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    12240                                 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
    12241                             }
    12242                             Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    12243 
    12244                             if (TrapFrame.bXcpt != bXcptExpect)
    12245                                 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    12246 
    12247                             /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    12248                             if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    12249                             {
    12250                                 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    12251                                     Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    12252                                 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    12253                             }
    12254                             if (bXcptExpect == X86_XCPT_DB)
    12255                                 Ctx.rflags.u32 = (Ctx.rflags.u32 & ~fEflCheck) | paValues[iVal].afEflOut[idxEflOut];
    12256                             Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    12257                                                  bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    12258                                                  pszMode, idTestStep);
    12259 
    12260                             if (   paTests[iTest].enmRm >= RM_MEM
    12261                                 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    12262                                 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    12263 
    12264                             if (cErrors != Bs3TestSubErrorCount())
    12265                             {
    12266                                 if (paConfigs[iCfg].fAligned)
    12267                                     Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x)",
    12268                                                    bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect);
    12269                                 else
    12270                                     Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    12271                                                    bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect,
    12272                                                    puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    12273                                 Bs3TestPrintf("\n");
    12274                             }
    12275 
    12276                             if (uSavedFtw != 0xff)
    12277                                 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    12278                         }
    12279                         Ctx.rflags.u32 = fSavedEfl;
    12280                     }
     12346                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    1228112347            }
    12282 
    12283             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    12284         }
     12348        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    1228512349
    1228612350        /*
     
    1244312507    for (;;)
    1244412508    {
    12445         unsigned iCfg;
    12446         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     12509        unsigned fPf = 0;
     12510        do
    1244712511        {
    12448             unsigned                    iTest;
    12449             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    12450             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    12451                 continue; /* unsupported config */
    12452 
    12453             /*
    12454              * Iterate the tests.
    12455              */
    12456             for (iTest = 0; iTest < cTests; iTest++)
     12512            unsigned iCfg;
     12513            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    1245712514            {
    12458                 BS3CPUINSTR3_TEST5_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    12459                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    12460                 unsigned const  cValues     = paTests[iTest].cValues;
    12461                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    12462                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    12463                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    12464                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    12465                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    12466                 uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
    12467                 uint8_t const   cbAlign     = cbMemOp;
    12468                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    12469                 uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
    12470                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    12471                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    12472                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    12473                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    12474                 unsigned        cRecompRuns = 0;
    12475                 unsigned        iVal;
    12476 
    12477                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    12478                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    12479                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    12480                     continue;
    12481 
    12482                 /* #AC is only raised in ring-3.: */
    12483                 if (bXcptExpect == X86_XCPT_AC)
     12515                unsigned                    iTest;
     12516                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     12517                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     12518                    continue; /* unsupported config */
     12519
     12520                /*
     12521                 * Iterate the tests.
     12522                 */
     12523                for (iTest = 0; iTest < cTests; iTest++)
    1248412524                {
    12485                     if (bRing != 3)
    12486                         bXcptExpect = X86_XCPT_DB;
    12487                     else if (fAvxInstr)
    12488                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     12525                    BS3CPUINSTR3_TEST5_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     12526                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     12527                    unsigned const  cValues     = paTests[iTest].cValues;
     12528                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     12529                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     12530                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     12531                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     12532                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     12533                    uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
     12534                    uint8_t const   cbAlign     = cbMemOp;
     12535                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     12536                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     12537                    uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     12538                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     12539                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     12540                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     12541                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     12542                    unsigned        cRecompRuns = 0;
     12543                    unsigned        iVal;
     12544
     12545                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
     12546                       allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     12547                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     12548                        continue;
     12549
     12550                    /* #AC is only raised in ring-3: */
     12551                    if (bXcptExpect == X86_XCPT_AC)
     12552                    {
     12553                        if (bRing != 3)
     12554                            bXcptExpect = X86_XCPT_DB;
     12555                        else if (fAvxInstr)
     12556                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     12557                    }
     12558
     12559                    if (fPf && bXcptExpect == X86_XCPT_DB)
     12560                        bXcptExpect = X86_XCPT_PF;
     12561
     12562                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     12563
     12564                    /*
     12565                     * Iterate the test values and do the actual testing.
     12566                     */
     12567                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
     12568                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     12569                        {
     12570                            uint16_t   cErrors;
     12571                            uint16_t   uSavedFtw = 0xff;
     12572                            RTUINT256U uMemOpExpect;
     12573
     12574                            if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
     12575
     12576                            /*
     12577                             * Set up the context and some expectations.
     12578                             */
     12579                            /* dest */
     12580                            if (paTests[iTest].iRegDst == UINT8_MAX)
     12581                            {
     12582                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12583                                Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     12584                                if (bXcptExpect == X86_XCPT_DB)
     12585                                    uMemOpExpect = paValues[iVal].uDstOut;
     12586                                else
     12587                                    Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     12588                            }
     12589                            else if (fMmxInstr)
     12590                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12591
     12592                            /* source #1 (/ destination for MMX and SSE) */
     12593                            if (paTests[iTest].iRegSrc1 == UINT8_MAX)
     12594                            {
     12595                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12596                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp);
     12597                                if (paTests[iTest].iRegDst == UINT8_MAX)
     12598                                    BS3_ASSERT(fSseInstr);
     12599                                else
     12600                                    uMemOpExpect = paValues[iVal].uSrc1;
     12601                            }
     12602                            else if (fMmxInstr)
     12603                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12604                            else if (fSseInstr)
     12605                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
     12606                            else
     12607                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
     12608
     12609                            /* source #2 */
     12610                            if (paTests[iTest].iRegSrc2 == UINT8_MAX)
     12611                            {
     12612                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12613                                BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
     12614                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp);
     12615                                uMemOpExpect = paValues[iVal].uSrc2;
     12616                            }
     12617                            else if (fMmxInstr)
     12618                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12619                            else if (fSseInstr)
     12620                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
     12621                            else
     12622                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
     12623
     12624                            /* source #3 */
     12625                            if (paTests[iTest].iRegSrc3 == UINT8_MAX)
     12626                            {
     12627                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     12628                                BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
     12629                                Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc3, cbMemOp);
     12630                                uMemOpExpect = paValues[iVal].uSrc3;
     12631                            }
     12632                            else if (fMmxInstr)
     12633                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc3, paValues[iVal].uSrc3.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     12634                            else if (fSseInstr)
     12635                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3.DQWords.dqw0);
     12636                            else
     12637                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3, 32);
     12638
     12639                            /* Memory pointer. */
     12640                            if (paTests[iTest].enmRm >= RM_MEM)
     12641                            {
     12642                                BS3_ASSERT(   paTests[iTest].iRegDst  == UINT8_MAX
     12643                                           || paTests[iTest].iRegSrc1 == UINT8_MAX
     12644                                           || paTests[iTest].iRegSrc2 == UINT8_MAX
     12645                                           || paTests[iTest].iRegSrc3 == UINT8_MAX);
     12646                                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     12647                            }
     12648
     12649                            /*
     12650                             * Execute.
     12651                             */
     12652                            Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     12653
     12654                            /*
     12655                             * Check the result:
     12656                             */
     12657                            cErrors = Bs3TestSubErrorCount();
     12658
     12659                            if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
     12660                            {
     12661                                uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     12662                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */
     12663                            }
     12664                            if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
     12665                            {
     12666                                if (fMmxInstr)
     12667                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
     12668                                else if (fSseInstr)
     12669                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
     12670                                else
     12671                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
     12672                            }
     12673#if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
     12674                            if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
     12675                                && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
     12676                                && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
     12677                                pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
     12678#endif
     12679                            Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     12680
     12681                            if (TrapFrame.bXcpt != bXcptExpect)
     12682                                Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     12683
     12684                            /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     12685                            if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     12686                            {
     12687                                if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     12688                                    Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     12689                                TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     12690                            }
     12691                            if (bXcptExpect == X86_XCPT_PF)
     12692                                Ctx.cr2.u = (uintptr_t)puMemOp;
     12693                            Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     12694                                                 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     12695                                                 pszMode, idTestStep);
     12696                            Ctx.cr2.u = 0;
     12697
     12698                            if (   paTests[iTest].enmRm >= RM_MEM
     12699                                && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     12700                                Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     12701
     12702                            if (cErrors != Bs3TestSubErrorCount())
     12703                            {
     12704                                if (paConfigs[iCfg].fAligned)
     12705                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
     12706                                                   bRing, iCfg, iTest, iVal, bXcptExpect);
     12707                                else
     12708                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     12709                                                   bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     12710                                Bs3TestPrintf("\n");
     12711                            }
     12712
     12713                            if (uSavedFtw != 0xff)
     12714                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
     12715                        }
    1248912716                }
    1249012717
    12491                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    12492 
    12493                 /*
    12494                  * Iterate the test values and do the actual testing.
    12495                  */
    12496                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
    12497                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    12498                     {
    12499                         uint16_t   cErrors;
    12500                         uint16_t   uSavedFtw = 0xff;
    12501                         RTUINT256U uMemOpExpect;
    12502 
    12503                         if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
    12504 
    12505                         /*
    12506                          * Set up the context and some expectations.
    12507                          */
    12508                         /* dest */
    12509                         if (paTests[iTest].iRegDst == UINT8_MAX)
    12510                         {
    12511                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12512                             Bs3MemSet(puMemOp, 0xcc, cbMemOp);
    12513                             if (bXcptExpect == X86_XCPT_DB)
    12514                                 uMemOpExpect = paValues[iVal].uDstOut;
    12515                             else
    12516                                 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    12517                         }
    12518                         else if (fMmxInstr)
    12519                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12520 
    12521                         /* source #1 (/ destination for MMX and SSE) */
    12522                         if (paTests[iTest].iRegSrc1 == UINT8_MAX)
    12523                         {
    12524                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12525                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp);
    12526                             if (paTests[iTest].iRegDst == UINT8_MAX)
    12527                                 BS3_ASSERT(fSseInstr);
    12528                             else
    12529                                 uMemOpExpect = paValues[iVal].uSrc1;
    12530                         }
    12531                         else if (fMmxInstr)
    12532                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12533                         else if (fSseInstr)
    12534                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0);
    12535                         else
    12536                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32);
    12537 
    12538                         /* source #2 */
    12539                         if (paTests[iTest].iRegSrc2 == UINT8_MAX)
    12540                         {
    12541                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12542                             BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
    12543                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp);
    12544                             uMemOpExpect = paValues[iVal].uSrc2;
    12545                         }
    12546                         else if (fMmxInstr)
    12547                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12548                         else if (fSseInstr)
    12549                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0);
    12550                         else
    12551                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32);
    12552 
    12553                         /* source #3 */
    12554                         if (paTests[iTest].iRegSrc3 == UINT8_MAX)
    12555                         {
    12556                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    12557                             BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX);
    12558                             Bs3MemCpy(puMemOp, &paValues[iVal].uSrc3, cbMemOp);
    12559                             uMemOpExpect = paValues[iVal].uSrc3;
    12560                         }
    12561                         else if (fMmxInstr)
    12562                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc3, paValues[iVal].uSrc3.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    12563                         else if (fSseInstr)
    12564                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3.DQWords.dqw0);
    12565                         else
    12566                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3, 32);
    12567 
    12568                         /* Memory pointer. */
    12569                         if (paTests[iTest].enmRm >= RM_MEM)
    12570                         {
    12571                             BS3_ASSERT(   paTests[iTest].iRegDst  == UINT8_MAX
    12572                                        || paTests[iTest].iRegSrc1 == UINT8_MAX
    12573                                        || paTests[iTest].iRegSrc2 == UINT8_MAX
    12574                                        || paTests[iTest].iRegSrc3 == UINT8_MAX);
    12575                             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    12576                         }
    12577 
    12578                         /*
    12579                          * Execute.
    12580                          */
    12581                         Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    12582 
    12583                         /*
    12584                          * Check the result:
    12585                          */
    12586                         cErrors = Bs3TestSubErrorCount();
    12587 
    12588                         if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
    12589                         {
    12590                             uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    12591                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */
    12592                         }
    12593                         if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX)
    12594                         {
    12595                             if (fMmxInstr)
    12596                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET);
    12597                             else if (fSseInstr)
    12598                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0);
    12599                             else
    12600                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand);
    12601                         }
    12602 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
    12603                         if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
    12604                             && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
    12605                             && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
    12606                             pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
    12607 #endif
    12608                         Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    12609 
    12610                         if (TrapFrame.bXcpt != bXcptExpect)
    12611                             Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    12612 
    12613                         /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    12614                         if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    12615                         {
    12616                             if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    12617                                 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    12618                             TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    12619                         }
    12620                         Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    12621                                              bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    12622                                              pszMode, idTestStep);
    12623 
    12624                         if (   paTests[iTest].enmRm >= RM_MEM
    12625                             && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    12626                             Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    12627 
    12628                         if (cErrors != Bs3TestSubErrorCount())
    12629                         {
    12630                             if (paConfigs[iCfg].fAligned)
    12631                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
    12632                                                bRing, iCfg, iTest, iVal, bXcptExpect);
    12633                             else
    12634                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    12635                                                bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    12636                             Bs3TestPrintf("\n");
    12637                         }
    12638 
    12639                         if (uSavedFtw != 0xff)
    12640                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    12641                     }
     12718                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    1264212719            }
    12643 
    12644             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    12645         }
     12720        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    1264612721
    1264712722        /*
     
    1300813083    for (;;)
    1300913084    {
    13010         unsigned iCfg;
    13011         for (iCfg = 0; iCfg < cConfigs; iCfg++)
     13085        unsigned fPf = 0;
     13086        do
    1301213087        {
    13013             unsigned                    iTest;
    13014             BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
    13015             if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
    13016                 continue; /* unsupported config */
    13017 
    13018             /*
    13019              * Iterate the tests.
    13020              */
    13021             for (iTest = 0; iTest < cTests; iTest++)
     13088            unsigned iCfg;
     13089            for (iCfg = 0; iCfg < cConfigs; iCfg++)
    1302213090            {
    13023                 BS3CPUINSTR3_TEST6_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
    13024                 uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
    13025                 unsigned const  cValues     = paTests[iTest].cValues;
    13026                 bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
    13027                 bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
    13028                 bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
    13029                 uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
    13030                                             : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
    13031                 uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
    13032                 uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
    13033                 PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]);
    13034                 uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
    13035                                             : fMmxInstr ? paConfigs[iCfg].bXcptMmx
    13036                                             : fSseInstr ? paConfigs[iCfg].bXcptSse
    13037                                             : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
    13038                 uint64_t const  fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX
    13039                                             : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1;
    13040                 uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
    13041                 unsigned        cRecompRuns = 0;
    13042                 unsigned        iVal;
    13043 
    13044                 /* If testing unaligned memory accesses, skip register-only tests.  This allows
    13045                    setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
    13046                 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck))
    13047                     continue;
    13048 
    13049                 /* #AC is only raised in ring-3.: */
    13050                 if (bXcptExpect == X86_XCPT_AC)
     13091                unsigned                    iTest;
     13092                BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg;
     13093                if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     13094                    continue; /* unsupported config */
     13095
     13096                /*
     13097                 * Iterate the tests.
     13098                 */
     13099                for (iTest = 0; iTest < cTests; iTest++)
    1305113100                {
    13052                     if (bRing != 3)
    13053                         bXcptExpect = X86_XCPT_DB;
    13054                     else if (fAvxInstr)
    13055                         bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     13101                    BS3CPUINSTR3_TEST6_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues;
     13102                    uint8_t const   cbInstr     = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1];
     13103                    unsigned const  cValues     = paTests[iTest].cValues;
     13104                    bool const      fMmxInstr   = paTests[iTest].enmType < T_SSE;
     13105                    bool const      fSseInstr   = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128;
     13106                    bool const      fAvxInstr   = paTests[iTest].enmType >= T_AVX_128;
     13107                    uint8_t const   cbOperand   = paTests[iTest].enmType < T_128BITS ? 64/8
     13108                                                : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8;
     13109                    uint8_t const   cbMemOp     = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm);
     13110                    uint8_t const   cbAlign     = RT_MIN(cbOperand, 16);
     13111                    PRTUINT256U     puMemOp     = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     13112                    PRTUINT256U     puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     13113                    uint8_t         bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD
     13114                                                : fMmxInstr ? paConfigs[iCfg].bXcptMmx
     13115                                                : fSseInstr ? paConfigs[iCfg].bXcptSse
     13116                                                : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     13117                    uint64_t const  fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX
     13118                                                : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1;
     13119                    uint16_t        idTestStep  = bRing * 10000 + iCfg * 100 + iTest * 10;
     13120                    unsigned        cRecompRuns = 0;
     13121                    unsigned        iVal;
     13122
     13123                    /* If testing unaligned memory accesses, skip register-only tests.  This allows
     13124                       setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions.  */
     13125                    if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     13126                        continue;
     13127
     13128                    /* #AC is only raised in ring-3.: */
     13129                    if (bXcptExpect == X86_XCPT_AC)
     13130                    {
     13131                        if (bRing != 3)
     13132                            bXcptExpect = X86_XCPT_DB;
     13133                        else if (fAvxInstr)
     13134                            bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */
     13135                    }
     13136
     13137                    if (fPf && bXcptExpect == X86_XCPT_DB)
     13138                        bXcptExpect = X86_XCPT_PF;
     13139
     13140                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
     13141
     13142                    /*
     13143                     * Iterate the test values and do the actual testing.
     13144                     */
     13145                    while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
     13146                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     13147                        {
     13148                            uint16_t   cErrors;
     13149                            uint16_t   uSavedFtw = 0xff;
     13150                            RTUINT256U uMemOpExpect;
     13151
     13152                            if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
     13153
     13154                            /*
     13155                             * Set up the context and some expectations.
     13156                             */
     13157                            /* source - media */
     13158                            BS3_ASSERT(paTests[iTest].iMediaRegSrc != UINT8_MAX);
     13159                            if (fMmxInstr)
     13160                                Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegSrc, paValues[iVal].uMediaSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
     13161                            else if (fSseInstr)
     13162                                Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc.DQWords.dqw0);
     13163                            else
     13164                                Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc, 32);
     13165
     13166                            /* source - gpr/mem */
     13167                            if (paTests[iTest].iGprReg == UINT8_MAX)
     13168                            {
     13169                                BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
     13170                                Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
     13171                                if (bXcptExpect == X86_XCPT_DB)
     13172                                    switch (paTests[iTest].cbGpr)
     13173                                    {
     13174                                        case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
     13175                                        case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
     13176                                        case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
     13177                                        case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
     13178                                        default: BS3_ASSERT(0);
     13179                                    }
     13180                                Bs3MemCpy(puMemOpAlias, &uMemOpExpect, cbMemOp);
     13181                            }
     13182                            else
     13183                                Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr);
     13184
     13185                            /* Memory pointer. */
     13186                            if (paTests[iTest].enmRm >= RM_MEM)
     13187                            {
     13188                                BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaRegSrc == UINT8_MAX);
     13189                                Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
     13190                            }
     13191
     13192                            /*
     13193                             * Execute.
     13194                             */
     13195                            Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
     13196
     13197                            /*
     13198                             * Check the result:
     13199                             */
     13200                            cErrors = Bs3TestSubErrorCount();
     13201
     13202                            if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
     13203                            {
     13204                                uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
     13205                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
     13206                            }
     13207
     13208                            if (bXcptExpect == X86_XCPT_DB)
     13209                            {
     13210                                if (fMmxInstr)
     13211                                    Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegDst, paValues[iVal].uMediaDst.QWords.qw0, BS3EXTCTXTOPMM_SET);
     13212                                else if (fSseInstr)
     13213                                    Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst.DQWords.dqw0);
     13214                                else
     13215                                    Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst, 32);
     13216                            }
     13217
     13218                            Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
     13219
     13220                            if (TrapFrame.bXcpt != bXcptExpect)
     13221                                Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
     13222
     13223                            /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     13224                            if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     13225                            {
     13226                                if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     13227                                    Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     13228                                TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     13229                            }
     13230                            if (bXcptExpect == X86_XCPT_PF)
     13231                                Ctx.cr2.u = (uintptr_t)puMemOp;
     13232                            Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
     13233                                                 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     13234                                                 pszMode, idTestStep);
     13235                            Ctx.cr2.u = 0;
     13236
     13237                            if (   paTests[iTest].enmRm >= RM_MEM
     13238                                && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0)
     13239                                Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias);
     13240
     13241                            if (cErrors != Bs3TestSubErrorCount())
     13242                            {
     13243                                if (paConfigs[iCfg].fAligned)
     13244                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
     13245                                                   bRing, iCfg, iTest, iVal, bXcptExpect);
     13246                                else
     13247                                    Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
     13248                                                   bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
     13249                                Bs3TestPrintf("\n");
     13250                            }
     13251
     13252                            if (uSavedFtw != 0xff)
     13253                                Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
     13254                        }
    1305613255                }
    1305713256
    13058                 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker);
    13059 
    13060                 /*
    13061                  * Iterate the test values and do the actual testing.
    13062                  */
    13063                 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues)
    13064                     for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
    13065                     {
    13066                         uint16_t   cErrors;
    13067                         uint16_t   uSavedFtw = 0xff;
    13068                         RTUINT256U uMemOpExpect;
    13069 
    13070                         if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue;
    13071 
    13072                         /*
    13073                          * Set up the context and some expectations.
    13074                          */
    13075                         /* source - media */
    13076                         BS3_ASSERT(paTests[iTest].iMediaRegSrc != UINT8_MAX);
    13077                         if (fMmxInstr)
    13078                             Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegSrc, paValues[iVal].uMediaSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO);
    13079                         else if (fSseInstr)
    13080                             Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc.DQWords.dqw0);
    13081                         else
    13082                             Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc, 32);
    13083 
    13084                         /* source - gpr/mem */
    13085                         if (paTests[iTest].iGprReg == UINT8_MAX)
    13086                         {
    13087                             BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM);
    13088                             Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect));
    13089                             if (bXcptExpect == X86_XCPT_DB)
    13090                                 switch (paTests[iTest].cbGpr)
    13091                                 {
    13092                                     case 1: uMemOpExpect.au8[0]  = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break;
    13093                                     case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break;
    13094                                     case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break;
    13095                                     case 8: uMemOpExpect.au64[0] =           (paValues[iVal].uGpr & fGprValMask); break;
    13096                                     default: BS3_ASSERT(0);
    13097                                 }
    13098                             Bs3MemCpy(puMemOp, &uMemOpExpect, cbMemOp);
    13099                         }
    13100                         else
    13101                             Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr);
    13102 
    13103                         /* Memory pointer. */
    13104                         if (paTests[iTest].enmRm >= RM_MEM)
    13105                         {
    13106                             BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaRegSrc == UINT8_MAX);
    13107                             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp);
    13108                         }
    13109 
    13110                         /*
    13111                          * Execute.
    13112                          */
    13113                         Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut);
    13114 
    13115                         /*
    13116                          * Check the result:
    13117                          */
    13118                         cErrors = Bs3TestSubErrorCount();
    13119 
    13120                         if (fMmxInstr && bXcptExpect == X86_XCPT_DB)
    13121                         {
    13122                             uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx);
    13123                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff);
    13124                         }
    13125 
    13126                         if (bXcptExpect == X86_XCPT_DB)
    13127                         {
    13128                             if (fMmxInstr)
    13129                                 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegDst, paValues[iVal].uMediaDst.QWords.qw0, BS3EXTCTXTOPMM_SET);
    13130                             else if (fSseInstr)
    13131                                 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst.DQWords.dqw0);
    13132                             else
    13133                                 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst, 32);
    13134                         }
    13135 
    13136                         Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep);
    13137 
    13138                         if (TrapFrame.bXcpt != bXcptExpect)
    13139                             Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt);
    13140 
    13141                         /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    13142                         if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
    13143                         {
    13144                             if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
    13145                                 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
    13146                             TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
    13147                         }
    13148                         Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0,
    13149                                              bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    13150                                              pszMode, idTestStep);
    13151 
    13152                         if (   paTests[iTest].enmRm >= RM_MEM
    13153                             && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0)
    13154                             Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp);
    13155 
    13156                         if (cErrors != Bs3TestSubErrorCount())
    13157                         {
    13158                             if (paConfigs[iCfg].fAligned)
    13159                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)",
    13160                                                bRing, iCfg, iTest, iVal, bXcptExpect);
    13161                             else
    13162                                 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)",
    13163                                                bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0);
    13164                             Bs3TestPrintf("\n");
    13165                         }
    13166 
    13167                         if (uSavedFtw != 0xff)
    13168                             Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw);
    13169                     }
     13257                bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    1317013258            }
    13171 
    13172             bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx);
    13173         }
     13259        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
    1317413260
    1317513261        /*
     
    1353213618                                                            bs3CpuInstr3_vpbroadcastb_vpbroadcastw_vpbroadcastd_vpbroadcastq_vbroadcasti128,   0 },
    1353313619#endif
    13534 #if defined (ALL_TESTS)
     13620#if defined(ALL_TESTS)
    1353513621        { "vinserti128/vinsertf128",                        bs3CpuInstr3_vinserti128_vinsertf128, 0 },
    1353613622#endif
    13537 #if defined (ALL_TESTS)
     13623#if defined(ALL_TESTS)
    1353813624        { "[v]psubsb/[v]psubsw",                            bs3CpuInstr3_v_psubsb_psubsw, 0 },
    1353913625        { "[v]psubusb/[v]psubusw",                          bs3CpuInstr3_v_psubusb_psubusw, 0 },
     
    1354113627        { "[v]paddsb/[v]paddsw",                            bs3CpuInstr3_v_paddsb_paddsw, 0 },
    1354213628#endif
    13543 #if defined (ALL_TESTS)
     13629#if defined(ALL_TESTS)
    1354413630        { "[v]psllw/[v]pslld/[v]psllq",                     bs3CpuInstr3_v_psllw_pslld_psllq, 0 },
    1354513631        { "[v]psraw/[v]psrad",                              bs3CpuInstr3_v_psraw_psrad, 0 },
    1354613632        { "[v]psrlw/[v]psrld/[v]psrlq",                     bs3CpuInstr3_v_psrlw_psrld_psrlq, 0 },
    1354713633#endif
    13548 #if defined (ALL_TESTS)
     13634#if defined(ALL_TESTS)
    1354913635        { "vpsllvd/vpsllvq",                                bs3CpuInstr3_vpsllvd_vpsllvq, 0 },
    1355013636        { "vpsravd",                                        bs3CpuInstr3_vpsravd, 0 },
    1355113637        { "vpsrlvd/vpsrlvq",                                bs3CpuInstr3_vpsrlvd_vpsrlvq, 0 },
    1355213638#endif
    13553 #if defined (ALL_TESTS)
     13639#if defined(ALL_TESTS)
    1355413640        { "vperm2i128/vperm2f128",                          bs3CpuInstr3_vperm2i128_vperm2f128, 0 },
    1355513641#endif
    13556 #if defined (ALL_TESTS)
     13642#if defined(ALL_TESTS)
    1355713643        { "vpermilps",                                      bs3CpuInstr3_vpermilps, 0 },
    1355813644        { "vpermilpd",                                      bs3CpuInstr3_vpermilpd, 0 },
    1355913645#endif
    13560 #if defined (ALL_TESTS)
     13646#if defined(ALL_TESTS)
    1356113647        { "[v]pmaddwd",                                     bs3CpuInstr3_v_pmaddwd, 0 },
    1356213648#endif
     
    1361213698    if (g_pbBuf)
    1361313699    {
    13614         /*
    13615          * Do the tests.
    13616          */
    13617         Bs3TestDoModesByOne_pe32(g_aTests, RT_ELEMENTS(g_aTests), BS3TESTMODEBYONEENTRY_F_REAL_MODE_READY);
     13700        g_pbBufAliasAlloc = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_TILED, g_cbBuf);
     13701        if (g_pbBufAliasAlloc)
     13702        {
     13703            /*
     13704             * Do the tests.
     13705             */
     13706            Bs3TestDoModesByOne_pe32(g_aTests, RT_ELEMENTS(g_aTests), BS3TESTMODEBYONEENTRY_F_REAL_MODE_READY);
    1361813707#ifdef BS3_SKIPIT_DO_SKIP
    13619         bs3CpuInstr3_ShowTallies();
     13708            bs3CpuInstr3_ShowTallies();
    1362013709#endif
     13710        }
     13711        else
     13712            Bs3TestFailed("Failed to allocate 16K alias buffer (tiled addressable)");
    1362113713    }
    1362213714    else
    13623         Bs3TestFailed("Failed to allocate 16K buffer");
     13715        Bs3TestFailed("Failed to allocate 16K buffer (real mode addressable)");
    1362413716
    1362513717    Bs3TestTerm();
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