Index: trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-4.c32
===================================================================
--- trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-4.c32	(revision 106148)
+++ trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-4.c32	(revision 106174)
@@ -1581,7 +1581,7 @@
             { /*src1     */ { FP32_1(0),    FP32_RAND_V2(1), FP32_RAND_V4(1), FP32_RAND_V6(1), FP32_RAND_V2(1), FP32_RAND_V7(0), FP32_RAND_V3(0), FP32_RAND_V4(1) } },                                        \
             { /* =>      */ { FP32_QNAN(0), FP32_RAND_V2(1), FP32_RAND_V4(1), FP32_RAND_V6(1), FP32_RAND_V2(1), FP32_RAND_V7(0), FP32_RAND_V3(0), FP32_RAND_V4(1) } },                                        \
-              /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
-              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
-              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
+              /*mxcsr:in */ X86_MXCSR_XCPT_MASK,                                                                                                                                                              \
+              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,                                                                                                                                               \
+              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,                                                                                                                                               \
               /*xcpt?    */ false, false },                                                                                                                                                                   \
     /* SNan, Normal (Masked). */                                                                                                                                                                              \
@@ -2318,41 +2318,6 @@
 
 
-/*
- * Code to make testing the tests faster. `bs3CpuInstrX_SkipIt()' randomly
- * skips a large fraction of the micro-tests.  It is sufficiently random
- * that over a large number of runs, all micro-tests will be hit.
- *
- * This improves the runtime of the worst case (`#define ALL_TESTS' on a
- * debug build, run with '--execute-all-in-iem') from ~9000 to ~800 seconds
- * (on an Intel Core i7-10700, fwiw).
- *
- * To activate this 'developer's speed-testing mode', turn on
- * `#define BS3_SKIPIT_DO_SKIP' here.
- *
- * BS3_SKIPIT_AVG_SKIP governs approximately how many micro-tests are
- * skipped in a row; e.g. the default of 26 means about every 27th
- * micro-test is run during a particular test run.  (This is not 27x
- * faster due to other activities which are not skipped!)  Note this is
- * only an average; the actual skips are random.
- *
- * You can also modify bs3CpuInstrX_SkipIt() to focus on specific sub-tests,
- * using its (currently ignored) `bRing, iCfg, iTest, iVal, iVariant' args
- * (to enable this: turn on `#define BS3_SKIPIT_DO_ARGS': which costs about
- * 3% performance).
- *
- * Note! The skipping is not compatible with testing the native recompiler as
- *       it requires the test code to be run a number of times before it kicks
- *       in and does the native recompilation (currently around 16 times).
- */
-#define BS3_SKIPIT_AVG_SKIP     26
-#define BS3_SKIPIT_REPORT_COUNT 150000
-#undef  BS3_SKIPIT_DO_SKIP
-#undef  BS3_SKIPIT_DO_ARGS
-
-#ifndef BS3_SKIPIT_DO_SKIP
-# define BS3_SKIPIT(bRing, iCfg, iTest, iVal, iVariant) (false)
-#else
-# include <iprt/asm-amd64-x86.h>
-# include <iprt/asm-math.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/asm-math.h>
 
 DECLINLINE(uint32_t) bs3CpuInstrX_SimpleRand(void)
@@ -2374,5 +2339,8 @@
     uint32_t uVal = s_uSeedMemory;
     if (!uVal)
+    {
         uVal = (uint32_t)ASMReadTSC();
+        Bs3TestPrintf("PRNG initial seed: 0x%08lx\n", uVal);
+    }
     uVal = ASMModU64ByU32RetU32(ASMMult2xU32RetU64(uVal, 16807), INT32_MAX);
     s_uSeedMemory = uVal;
@@ -2380,4 +2348,44 @@
 }
 
+
+/*
+ * Code to make testing the tests faster. `bs3CpuInstrX_SkipIt()' randomly
+ * skips a fraction of the micro-tests.  It is sufficiently random that
+ * over a large number of runs, all micro-tests will be hit.
+ *
+ * Full test runs take ever longer as we add more instructions and fancier
+ * ways of testing them.  In one example scenario, a debug build running
+ * bs3-cpu-instr-3 under interpreted IEM went from 9000 to 800 seconds,
+ * with BS3_SKIPIT_AVG_SKIP on the default 26.
+ *
+ * To activate this 'developer's speed-testing mode', turn on
+ * `#define BS3_SKIPIT_DO_SKIP' here.
+ *
+ * BS3_SKIPIT_AVG_SKIP governs approximately how many micro-tests are
+ * skipped in a row; e.g. the default of 26 means that on average, every
+ * 26th micro-test is run during a particular test run.  (This is not 26x
+ * faster, due to other activities which are not skipped!)  Note this is
+ * only an average; the actual skips are random.
+ *
+ * You can also modify bs3CpuInstrX_SkipIt() to focus on specific sub-tests,
+ * using its (currently ignored) `bRing, iCfg, iTest, iVal, iVariant' args
+ * (to enable this: turn on `#define BS3_SKIPIT_DO_ARGS': which costs about
+ * 3% performance).
+ *
+ * Note!  For testing the native recompiler, configure the VM to invoke
+ * native recompilation quickly with:
+ *
+ *     VBoxManage setextradata vmname VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled 1
+ *     VBoxManage setextradata vmname VBoxInternal/Devices/VMMDev/0/Config/TestingThresholdNativeRecompiler 2
+ *     VBoxManage setextradata vmname VBoxInternal/IEM/NativeRecompileAtUsedCount 1
+ */
+#define BS3_SKIPIT_AVG_SKIP          26
+#define BS3_SKIPIT_REPORT_COUNT 1000000
+#undef  BS3_SKIPIT_DO_SKIP
+#undef  BS3_SKIPIT_DO_ARGS
+
+#ifndef BS3_SKIPIT_DO_SKIP
+# define BS3_SKIPIT(bRing, iCfg, iTest, iVal, iVariant) (false)
+#else
 static unsigned g_cSeen, g_cSkipped;
 
@@ -2941,4 +2949,510 @@
                             TestCtx.idTestStep   = idTestStep;
                             cErrors = bs3CpuInstr4_WorkerTestType1_Inner(bMode, &TestCtx, &SavedCfg);
+                            if (cErrors != Bs3TestSubErrorCount())
+                            {
+                                if (paConfigs[iCfg].fAligned)
+                                    Bs3TestFailedF("%s: ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%u %s, %s %u-bit)",
+                                                   Bs3GetModeName(bMode), bRing, iCfg, iTest, iVal,
+                                                   bXcptExpect, bs3CpuInstr4XcptName(bXcptExpect), fSseInstr ? "SSE" : "AVX", cbOperand * 8);
+                                else
+                                    Bs3TestFailedF("%s: ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%u %s, puMemOp=%p, EFLAGS=%#RX32, %s %u-bit)",
+                                                   Bs3GetModeName(bMode), bRing, iCfg, iTest, iVal,
+                                                   bXcptExpect, bs3CpuInstr4XcptName(bXcptExpect), puMemOp,
+                                                   TrapFrame.Ctx.rflags.u32, fSseInstr ? "SSE" : "AVX", cbOperand * 8);
+                                Bs3TestPrintf("\n");
+                            }
+                        }
+                    }
+                }
+                bs3CpuInstrXConfigRestore(&SavedCfg, &Ctx, pExtCtx);
+            }
+        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
+
+        /*
+         * Next ring.
+         */
+        bRing++;
+        if (bRing > 3 || bMode == BS3_MODE_RM)
+            break;
+        Bs3RegCtxConvertToRingX(&Ctx, bRing);
+    }
+
+    /*
+     * Cleanup.
+     */
+    bs3CpuInstrXBufCleanup(pbBuf, cbBuf, bMode);
+    bs3CpuInstrXFreeExtCtxs(pExtCtx, pExtCtxOut);
+    return 0;
+}
+
+
+/**
+ * Worker for bs3CpuInstr4_WorkerTestType1 [new WIP version]
+ */
+static uint16_t bs3CpuInstr4_WorkerTestType1A_Inner(uint8_t bMode, PBS3CPUINSTR4_TEST1_CTX_T pTestCtx,
+                                                   PCBS3CPUINSTRX_CONFIG_SAVED_T pSavedCfg)
+{
+    BS3CPUINSTR4_TEST1_T const BS3_FAR        *pTest   = pTestCtx->pTest;
+    BS3CPUINSTR4_TEST1_VALUES_T const BS3_FAR *pValues = &pTestCtx->pTest->paValues[pTestCtx->iVal];
+    PBS3TRAPFRAME    pTrapFrame          = pTestCtx->pTrapFrame;
+    PBS3REGCTX       pCtx                = pTestCtx->pCtx;
+    PBS3EXTCTX       pExtCtx             = pTestCtx->pExtCtx;
+    PBS3EXTCTX       pExtCtxOut          = pTestCtx->pExtCtxOut;
+    uint8_t BS3_FAR *puMemOp             = pTestCtx->puMemOp;
+    uint8_t BS3_FAR *puMemOpAlias        = pTestCtx->puMemOpAlias;
+    uint8_t          cbMemOp             = pTestCtx->cbMemOp;
+    uint8_t const    cbOperand           = pTestCtx->cbOperand;
+    uint8_t const    cbInstr             = ((uint8_t const BS3_FAR *)(uintptr_t)pTestCtx->pTest->pfnWorker)[-1];
+    uint8_t          bXcptExpect         = pTestCtx->bXcptExpect;
+    uint8_t const    bFpXcpt             = pTestCtx->pConfig->fCr4OsXmmExcpt ? X86_XCPT_XF : X86_XCPT_UD;
+    bool const       fSseInstr           = bs3CpuInstr4IsSse(pTest->enmType);
+    uint32_t         uMxCsr;
+    X86YMMREG        MemOpExpect;
+    uint16_t         cErrors;
+    uint16_t         cErrorsInit         = Bs3TestSubErrorCount();
+    uint32_t         uExpectedMxCsr;
+    bool             fFpXcptExpected;
+
+    uint32_t uSpecifiedMask, uExpectedMask, uImpliedMask, uCombinedMask, uMaskedMask, uUnmaskedMask, uThisMask;
+    uint32_t uExpectedMxCsr_orig, uExpectedExceptions, uExpectedUnmaskedExceptions, uInitialExceptions, uRandTmp;
+    const char *pszMaskType;
+    unsigned iMaskType;
+    static bool      sfMismatchShown     = false;
+
+    /*
+     * An exception may be raised based on the test value (128 vs 256 bits).
+     * In addition, we allow setting the exception flags (and mask) prior to
+     * executing the instruction, so we cannot use the exception flags to figure
+     * out if an exception will be raised. Hence, the input values provide us
+     * explicitly whether an exception is expected for 128 and 256-bit variants.
+     */  /** @todo rewrite this to reflect 'worker 1a' when ready to commit */
+    if (pTestCtx->cbOperand > 16)
+    {
+        uExpectedMxCsr  = pValues->u256ExpectedMxCsr;
+        fFpXcptExpected = pValues->f256FpXcptExpected;
+    }
+    else
+    {
+        uExpectedMxCsr  = pValues->u128ExpectedMxCsr;
+        fFpXcptExpected = pValues->f128FpXcptExpected;
+    }
+
+    /*
+     * The test value tables give us the exceptions expected when run fully
+     * masked.  Here we try the instruction under multiple mask schemes: as
+     * requested by the value table; as implied by the stated resulting
+     * exceptions; fully masked; fully unmasked; and possibly some
+     * combinations.
+     *
+     * This is WORK IN PROGRESS code, and unclear whether it will be
+     * completed or will turn out to have been a bad idea.  The idea is to
+     * convert the existing instruction test functions one by one to use
+     * this.  Tables need updating because (1) some output rows are wrong
+     * for instructions which always raise an exception fgiven the stated
+     * mask; (2) output exceptions may be wrong for instructions which
+     * always raise an early DE exception, but would return a late exception
+     * (PE, OE, UE) if DE were masked; (3) entries which specify any or all
+     * exceptions already on in MXCSR must be modified to only show output
+     * exceptions which will be *newly* raised by the instruction itself.
+     *
+     * Code indentation is being retained the same as the parent Worker1
+     * functions for now, to facilitate co-fixing of any other issues found
+     * while this is under development.  Indentation will be fixed if/when
+     * this becomes the replacement Worker1.
+     */
+    uExpectedMxCsr_orig = uExpectedMxCsr;
+    uInitialExceptions = pValues->uMxCsr & X86_MXCSR_XCPT_FLAGS;
+    uSpecifiedMask = pValues->uMxCsr & X86_MXCSR_XCPT_MASK;
+    uExpectedMask = uExpectedMxCsr_orig & X86_MXCSR_XCPT_MASK;
+
+    /* Debug code to help convert the value tables; eventually replace with an assert */
+    if (!sfMismatchShown && (uSpecifiedMask != uExpectedMask))
+    {
+        Bs3TestFailedF("UNEXPECTED: specified mask %#RX32 != expected mask %#RX32 [only flagging 1st instance]\n", uExpectedMask, uSpecifiedMask);
+        sfMismatchShown = true;
+    }
+    uImpliedMask = (uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS) << X86_MXCSR_XCPT_MASK_SHIFT;
+    uCombinedMask = uSpecifiedMask | uImpliedMask;
+    uMaskedMask = X86_MXCSR_XCPT_MASK;
+    uUnmaskedMask = 0;
+
+   for (iMaskType = 0; iMaskType <= 6; iMaskType++)
+   {
+    if (BS3_SKIPIT(0, 0, 0, pTestCtx->iVal, iMaskType))
+        continue;
+
+    switch (iMaskType)
+    {
+        case 0:
+            uThisMask = uSpecifiedMask;
+            pszMaskType = "Specified";
+            break;
+        case 1:
+            if (uExpectedMask == uSpecifiedMask) continue;
+            uThisMask = uExpectedMask;
+            pszMaskType = "Expected";
+            break;
+        case 2:
+            if (uImpliedMask == uSpecifiedMask || uImpliedMask == uExpectedMask) continue;
+            uThisMask = uImpliedMask;
+            pszMaskType = "Implied";
+            break;
+        case 3:
+            if (uCombinedMask == uSpecifiedMask || uCombinedMask == uExpectedMask || uCombinedMask == uImpliedMask) continue;
+            uThisMask = uCombinedMask;
+            pszMaskType = "Combined";
+            break;
+        case 4:
+            if (uMaskedMask == uSpecifiedMask || uMaskedMask == uExpectedMask || uMaskedMask == uImpliedMask || uMaskedMask == uCombinedMask) continue;
+            uThisMask = uMaskedMask;
+            pszMaskType = "Masked";
+            break;
+        case 5:
+            if (uUnmaskedMask == uSpecifiedMask || uUnmaskedMask == uExpectedMask || uUnmaskedMask == uImpliedMask || uUnmaskedMask == uCombinedMask) continue;
+            uThisMask = uUnmaskedMask;
+            pszMaskType = "Unmasked";
+            break;
+        case 6:
+            uRandTmp = bs3CpuInstrX_SimpleRand();
+            switch (uRandTmp & X86_MXCSR_RC_MASK)
+            {
+                case X86_MXCSR_RC_ZERO:
+                case X86_MXCSR_RC_NEAREST:
+                    uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
+                    break;
+                case X86_MXCSR_RC_DOWN:
+                    uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
+                    uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
+                    break;
+                case X86_MXCSR_RC_UP:
+                    uThisMask = uSpecifiedMask;
+                    uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
+                    break;
+                default:
+                    BS3_ASSERT(0);
+            }
+            pszMaskType = "Random";
+            break;
+        /** @todo Consider providing assorted already-set exceptions (WIP) */
+        /** @todo Consider only-early exceptions masked; only-late exceptions masked */
+        /** @todo Consider only-early-specified exceptions masked; only-late-specified exceptions masked */
+        /** -- I think actually this is all covered by the Random case.  Over time. */
+        default:
+            BS3_ASSERT(0);
+    }
+    /* This is the input MXCSR value we'll be sending */
+    uMxCsr = (pValues->uMxCsr & ~(X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS)) | uThisMask | uInitialExceptions;
+
+    /* What exceptions does this test value claim to raise?  Only actual raises, not initially-on exceptions */
+    uExpectedExceptions = uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS;
+    uExpectedUnmaskedExceptions = uExpectedExceptions & ~(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
+
+    /* This is the output MXCSR value we will expect */
+    uExpectedMxCsr = (uExpectedMxCsr_orig & ~(X86_MXCSR_XCPT_MASK)) | uThisMask;
+
+    /* If we hit an unmasked early exception, late exceptions won't be raised. */
+    if (uExpectedUnmaskedExceptions & (X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_ZE))
+        uExpectedMxCsr &= ~(X86_MXCSR_OE | X86_MXCSR_PE | X86_MXCSR_UE);
+
+    /* However, all exceptions which are on before the instruction will still be on. */
+    uExpectedMxCsr |= uInitialExceptions;
+
+    /* A fault is raised only by unmasked exceptions which were caused by the instruction itself. */
+    fFpXcptExpected = (uExpectedUnmaskedExceptions != 0);
+
+    /*
+     * Set up the context and some expectations.
+     */
+    /* Destination. */
+    Bs3MemZero(&MemOpExpect, sizeof(MemOpExpect));
+    if (pTest->iRegDst == UINT8_MAX)
+    {
+        BS3_ASSERT(pTest->enmRm >= RM_MEM);
+        Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
+        if (bXcptExpect == X86_XCPT_DB)
+            MemOpExpect.ymm = pValues->uDstOut.ymm;
+        else
+            Bs3MemSet(&MemOpExpect, 0xcc, sizeof(MemOpExpect));
+    }
+
+    /* Source #1 (/ destination for SSE). */
+    if (pTest->iRegSrc1 == UINT8_MAX)
+    {
+        BS3_ASSERT(pTest->enmRm >= RM_MEM);
+        Bs3MemCpy(puMemOpAlias, &pValues->uSrc1, cbMemOp);
+        if (pTest->iRegDst == UINT8_MAX)
+            BS3_ASSERT(fSseInstr);
+        else
+            MemOpExpect.ymm = pValues->uSrc1.ymm;
+    }
+    else if (fSseInstr)
+        Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm.DQWords.dqw0);
+    else
+        Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm, 32);
+
+    /* Source #2. */
+    if (pTest->iRegSrc2 == UINT8_MAX)
+    {
+        BS3_ASSERT(pTest->enmRm >= RM_MEM);
+        BS3_ASSERT(pTest->iRegDst != UINT8_MAX && pTest->iRegSrc1 != UINT8_MAX);
+        Bs3MemCpy(puMemOpAlias, &pValues->uSrc2, cbMemOp);
+        MemOpExpect.ymm = pValues->uSrc2.ymm;
+    }
+    else if (fSseInstr)
+        Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm.DQWords.dqw0);
+    else
+        Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm, 32);
+
+    /* Memory pointer. */
+    if (pTest->enmRm >= RM_MEM)
+    {
+        BS3_ASSERT(   pTest->iRegDst  == UINT8_MAX
+                   || pTest->iRegSrc1 == UINT8_MAX
+                   || pTest->iRegSrc2 == UINT8_MAX);
+        Bs3RegCtxSetGrpSegFromCurPtr(pCtx, &pCtx->rbx, &pCtx->fs, puMemOp);
+    }
+
+    /* Setup MXCSR for the current test. */
+    uMxCsr |= (pSavedCfg->uMxCsr & X86_MXCSR_MM);
+    BS3_ASSERT(!(uMxCsr & X86_MXCSR_MM));
+    BS3_ASSERT(!(uMxCsr & X86_MXCSR_DAZ) || g_fMxCsrDazSupported);
+    Bs3ExtCtxSetMxCsr(pExtCtx, uMxCsr);
+
+    /*
+     * Prepare globals and execute.
+     */
+    g_uBs3TrapEipHint = pCtx->rip.u32;
+    if (    bXcptExpect == X86_XCPT_DB
+        && !fFpXcptExpected)
+        g_uBs3TrapEipHint += cbInstr + 1;
+    Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(pCtx, pExtCtx, pTrapFrame, pExtCtxOut);
+
+    /*
+     * Check the result.
+     *
+     * If a floating-point exception is expected, the destination is not updated by the instruction.
+     * In the case of SSE instructions, updating the destination here will work because it is the same
+     * as the source, but for AVX++ it won't because the destination is different and would contain 0s.
+     */
+    cErrors = Bs3TestSubErrorCount();
+    if (   bXcptExpect == X86_XCPT_DB
+        && !fFpXcptExpected
+        && pTest->iRegDst != UINT8_MAX)
+    {
+        if (fSseInstr)
+            Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm.DQWords.dqw0);
+        else
+            Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm, cbOperand);
+    }
+#if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
+    if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
+        && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
+        && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
+        pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
+#endif
+    if (bXcptExpect == X86_XCPT_DB)
+        Bs3ExtCtxSetMxCsr(pExtCtx, uExpectedMxCsr | (pSavedCfg->uMxCsr & X86_MXCSR_MM));
+    Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pTestCtx->pszMode, pTestCtx->idTestStep);
+
+    if (bXcptExpect == X86_XCPT_DB)
+    {
+        uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut) & ~X86_MXCSR_MM;
+
+        /* Check if the SIMD FP exception flags and mask (or lack of) are as expected. */
+        if (uGotMxCsr != uExpectedMxCsr)
+        {
+            char szExpectFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
+            char szExpectMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
+            char szExpectOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
+            char szGotFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
+            char szGotMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
+            char szGotOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
+            bs3CpuInstr4GetXcptFlags(&szExpectFlags[0],   sizeof(szExpectFlags),  uExpectedMxCsr);
+            bs3CpuInstr4GetXcptMasks(&szExpectMasks[0],   sizeof(szExpectMasks),  uExpectedMxCsr);
+            bs3CpuInstr4GetXcptOthers(&szExpectOthers[0], sizeof(szExpectOthers), uExpectedMxCsr);
+            bs3CpuInstr4GetXcptFlags(&szGotFlags[0],   sizeof(szGotFlags),  uGotMxCsr);
+            bs3CpuInstr4GetXcptMasks(&szGotMasks[0],   sizeof(szGotMasks),  uGotMxCsr);
+            bs3CpuInstr4GetXcptOthers(&szGotOthers[0], sizeof(szGotOthers), uGotMxCsr);
+            Bs3TestFailedF("Expected MXCSR %#RX32 (%s%s%s ) got MXCSR %#RX32 (%s%s%s )", uExpectedMxCsr,
+                           szExpectFlags, szExpectMasks, szExpectOthers, uGotMxCsr, szGotFlags, szGotMasks, szGotOthers);
+        }
+
+        /* Check if the SIMD FP exception (or lack of) is as expected. */
+        if (fFpXcptExpected)
+        {
+            if (pTrapFrame->bXcpt == bFpXcpt)
+            { /* likely */ }
+            else
+                Bs3TestFailedF("Expected floating-point xcpt %s, got %s", bs3CpuInstr4XcptName(bFpXcpt),
+                               bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
+        }
+        else if (pTrapFrame->bXcpt == X86_XCPT_DB)
+        { /* likely */ }
+        else
+            Bs3TestFailedF("Expected no xcpt, got %s", bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
+    }
+    /* Check if non-FP exception is as expected. */
+    else if (pTrapFrame->bXcpt != bXcptExpect)
+        Bs3TestFailedF("Expected xcpt %s, got %s", bs3CpuInstr4XcptName(bXcptExpect), bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
+
+    /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
+    if (bMode == BS3_MODE_RM && (pCtx->rflags.u32 & X86_EFL_AC))
+    {
+        if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_AC)
+            Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", pTrapFrame->bXcpt);
+        pTrapFrame->Ctx.rflags.u32 |= X86_EFL_AC;
+    }
+    if (bXcptExpect == X86_XCPT_PF)
+        pCtx->cr2.u = (uintptr_t)puMemOp;
+    Bs3TestCheckRegCtxEx(&pTrapFrame->Ctx, pCtx, bXcptExpect == X86_XCPT_DB && !fFpXcptExpected ? cbInstr + 1 : 0, 0 /*cbSpAdjust*/,
+                         (bXcptExpect == X86_XCPT_DB && !fFpXcptExpected) || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
+                         pTestCtx->pszMode, pTestCtx->idTestStep);
+    pCtx->cr2.u = 0;
+
+    if (   pTest->enmRm >= RM_MEM
+        && Bs3MemCmp(puMemOpAlias, &MemOpExpect, cbMemOp) != 0)
+        Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &MemOpExpect, cbMemOp, puMemOpAlias);
+
+    /* Most-not-all of this will be removed once debugged */
+    if (cErrors != Bs3TestSubErrorCount()) Bs3TestFailedF("While testing mask mode %s, Spec=%#RX32, Expc=%#RX32, Impl=%#RX32, Comb=%#RX32, Mask=%#RX32, Umsk=%#RX32, This=%#RX32, uMxCsr=%#RX32, uExpectedMxCsr=%#RX32, save=%#RX32, ixcp=%#RX32", pszMaskType, uSpecifiedMask, uExpectedMask, uImpliedMask, uCombinedMask, uMaskedMask, uUnmaskedMask, uThisMask, uMxCsr, uExpectedMxCsr, uExpectedMxCsr_orig, uInitialExceptions);
+   }
+
+    return cErrorsInit;
+}
+
+
+/**
+ * Test type #1 worker [new WIP version].
+ */
+static uint8_t bs3CpuInstr4_WorkerTestType1A(uint8_t bMode, BS3CPUINSTR4_TEST1_T const BS3_FAR *paTests, unsigned cTests,
+                                            PCBS3CPUINSTR4_CONFIG_T paConfigs, unsigned cConfigs)
+{
+    BS3REGCTX                   Ctx;
+    BS3TRAPFRAME                TrapFrame;
+    const char BS3_FAR * const  pszMode = Bs3GetModeName(bMode);
+    uint8_t                     bRing   = BS3_MODE_IS_V86(bMode) ? 3 : 0;
+    uint8_t BS3_FAR            *pbBuf   = g_pbBuf;
+    uint32_t                    cbBuf   = g_cbBuf;
+    PBS3EXTCTX                  pExtCtxOut;
+    PBS3EXTCTX                  pExtCtx = bs3CpuInstrXAllocExtCtxs(&pExtCtxOut);
+    if (pExtCtx)
+    { /* likely */ }
+    else
+        return 0;
+    if (pExtCtx->enmMethod != BS3EXTCTXMETHOD_ANCIENT)
+    { /* likely */ }
+    else
+    {
+        Bs3TestPrintf("Skipped due to ancient FPU state format\n");
+        return 0;
+    }
+
+    /* Ensure the structures are allocated before we sample the stack pointer. */
+    Bs3MemSet(&Ctx, 0, sizeof(Ctx));
+    Bs3MemSet(&TrapFrame, 0, sizeof(TrapFrame));
+
+    /*
+     * Create test context.
+     */
+    pbBuf = bs3CpuInstrXBufSetup(pbBuf, &cbBuf, bMode);
+    Bs3RegCtxSaveForMode(&Ctx, bMode, 1024);
+    bs3CpuInstr4SetupSseAndAvx(&Ctx, pExtCtx);
+
+    /*
+     * Run the tests in all rings since alignment issues may behave
+     * differently in ring-3 compared to ring-0.
+     */
+    for (;;)
+    {
+        unsigned fPf = 0;
+        do
+        {
+            unsigned iCfg;
+            for (iCfg = 0; iCfg < cConfigs; iCfg++)
+            {
+                unsigned                    iTest;
+                BS3CPUINSTRX_CONFIG_SAVED_T SavedCfg;
+                if (!bs3CpuInstr4ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
+                    continue; /* unsupported config */
+
+                /*
+                 * Iterate the tests.
+                 */
+                for (iTest = 0; iTest < cTests; iTest++)
+                {
+                    BS3CPUINSTR4_TEST1_T const BS3_FAR *pTest = &paTests[iTest];
+                    unsigned const    cValues       = pTest->cValues;
+                    bool const        fSseInstr     = bs3CpuInstr4IsSse(pTest->enmType);
+                    bool const        fAvxInstr     = bs3CpuInstr4IsAvx(pTest->enmType);
+                    uint8_t const     cbOperand     = bs3CpuInstr4GetOperandSize(pTest->enmType);
+                    uint8_t const     cbMemOp       = bs3CpuInstrXMemOpSize(cbOperand, pTest->enmRm);
+                    uint8_t const     cbAlign       = cbMemOp;
+                    uint8_t BS3_FAR  *puMemOp       = bs3CpuInstrXBufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
+                    uint8_t          *puMemOpAlias  = &g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
+                    uint8_t           bXcptExpect   = !g_afTypeSupports[pTest->enmType] ? X86_XCPT_UD
+                                                    : fSseInstr ? paConfigs[iCfg].bXcptSse
+                                                    : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
+                    uint16_t         idTestStep     = bRing * 10000 + iCfg * 100 + iTest * 10;
+                    unsigned         cRecompRuns    = 0;
+                    unsigned const   cMaxRecompRuns = g_cBs3ThresholdNativeRecompiler + cValues;
+                    unsigned         iVal;
+
+                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
+                       allows setting bXcptSse and bXcptAvx to reflect the misaligned exceptions. */
+                    if (   (pTest->enmRm == RM_REG || pTest->enmRm == RM_MEM8)
+                        && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
+                        continue;
+
+                    /* #AC is only raised in ring-3. */
+                    if (bXcptExpect == X86_XCPT_AC)
+                    {
+                        if (bRing != 3)
+                            bXcptExpect = X86_XCPT_DB;
+                        else if (fAvxInstr)
+                            bXcptExpect = pTest->bAvxMisalignXcpt; /* they generally don't raise #AC */
+                    }
+
+                    if (fPf && bXcptExpect == X86_XCPT_DB)
+                        bXcptExpect = X86_XCPT_PF;
+
+                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, pTest->pfnWorker);
+
+                    /*
+                     * Iterate the test values and do the actual testing.
+                     */
+                    while (cRecompRuns < cMaxRecompRuns)
+                    {
+                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
+                        {
+                            uint16_t                 cErrors;
+                            BS3CPUINSTR4_TEST1_CTX_T TestCtx;
+
+                            /*
+                             * If the hardware does not support DAZ bit skip test values that set it.
+                             */
+                            if (   !g_fMxCsrDazSupported
+                                && (pTest->paValues[iVal].uMxCsr & X86_MXCSR_DAZ))
+                                continue;
+
+                            /*
+                             * Setup the test instruction context and pass it to the worker.
+                             * A few of these can be figured out by the worker but initializing
+                             * it outside the inner most loop is more optimal.
+                             */
+                            TestCtx.pConfig      = &paConfigs[iCfg];
+                            TestCtx.pTest        = pTest;
+                            TestCtx.iVal         = iVal;
+                            TestCtx.pszMode      = pszMode;
+                            TestCtx.pTrapFrame   = &TrapFrame;
+                            TestCtx.pCtx         = &Ctx;
+                            TestCtx.pExtCtx      = pExtCtx;
+                            TestCtx.pExtCtxOut   = pExtCtxOut;
+                            TestCtx.puMemOp      = (uint8_t *)puMemOp;
+                            TestCtx.puMemOpAlias = puMemOpAlias;
+                            TestCtx.cbMemOp      = cbMemOp;
+                            TestCtx.cbOperand    = cbOperand;
+                            TestCtx.bXcptExpect  = bXcptExpect;
+                            TestCtx.idTestStep   = idTestStep;
+                            cErrors = bs3CpuInstr4_WorkerTestType1A_Inner(bMode, &TestCtx, &SavedCfg);
                             if (cErrors != Bs3TestSubErrorCount())
                             {
@@ -12287,6 +12801,6 @@
             { /* =>      */ { FP32_0(0), FP32_RAND_V6(1), FP32_RAND_V5(0), FP32_RAND_V4(1), FP32_RAND_V7(0), FP32_RAND_V2(1), FP32_RAND_V1(0), FP32_RAND_V3(1) } },
               /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
-              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
-              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
+              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
+              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
               /*xcpt?    */ false, false },
           { { /*src2     */ { FP32_0(1), FP32_RAND_V6(1), FP32_RAND_V5(1), FP32_RAND_V4(1), FP32_RAND_V3(1), FP32_RAND_V2(1), FP32_RAND_V1(1), FP32_RAND_V0(1) } },
@@ -12301,6 +12815,6 @@
             { /* =>      */ { FP32_0(1), FP32_RAND_V0(1), FP32_RAND_V1(1), FP32_RAND_V6(0), FP32_RAND_V7(1), FP32_RAND_V3(1), FP32_RAND_V5(1), FP32_RAND_V2(1) } },
               /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
-              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
-              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
+              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
+              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
               /*xcpt?    */ false, false },
           { { /*src2     */ { FP32_0(1), FP32_RAND_V6(1), FP32_RAND_V5(1), FP32_RAND_V4(1), FP32_RAND_V3(1), FP32_RAND_V2(1), FP32_RAND_V1(1), FP32_RAND_V0(1) } },
@@ -12575,5 +13089,5 @@
     /*46*/{ { /*src2     */ { FP32_DENORM_MAX(0), FP32_RAND_V2(0), FP32_RAND_V7(1), FP32_RAND_V6(0), FP32_RAND_V2(0), FP32_RAND_V1(1), FP32_RAND_V7(0), FP32_RAND_V2(1) } },
             { /*src1     */ { FP32_0(0),          FP32_RAND_V3(0), FP32_RAND_V4(0), FP32_RAND_V5(1), FP32_RAND_V5(0), FP32_RAND_V6(1), FP32_RAND_V7(0), FP32_RAND_V1(1) } },
-            { /* =>      */ { FP32_0(0),          FP32_RAND_V3(1), FP32_RAND_V4(0), FP32_RAND_V5(1), FP32_RAND_V5(0), FP32_RAND_V6(1), FP32_RAND_V7(0), FP32_RAND_V1(1) } },
+            { /* =>      */ { FP32_0(0),          FP32_RAND_V3(0), FP32_RAND_V4(0), FP32_RAND_V5(1), FP32_RAND_V5(0), FP32_RAND_V6(1), FP32_RAND_V7(0), FP32_RAND_V1(1) } },
               /*mxcsr:in */ 0,
               /*128:out  */ X86_MXCSR_DE,
@@ -12683,5 +13197,5 @@
     static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64);
     unsigned const                         iTest       = BS3CPUINSTR4_TEST_MODES_INDEX(bMode);
-    return bs3CpuInstr4_WorkerTestType1(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
+    return bs3CpuInstr4_WorkerTestType1A(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
                                         g_aXcptConfig3, RT_ELEMENTS(g_aXcptConfig3));
 }
@@ -13168,11 +13682,4 @@
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(1), FP32_0(1), FP32_0(1), FP32_0(1) } },
-              /*mxcsr:in */ 0,
-              /*128:out  */ 0,
-              /*256:out  */ 0,
-              /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(1), FP32_0(1), FP32_0(1), FP32_0(1) } },
-            { /*unused   */ { FP32_x8_UNUSED } },
-            { /* =>      */ { FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(1), FP32_0(1), FP32_0(1), FP32_0(1) } },
               /*mxcsr:in */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
               /*128:out  */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
@@ -13196,5 +13703,5 @@
      * Infinity.
      */
-    /* 5*/{ { /*src1     */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_INF(1),  FP32_0(0), FP32_0(0), FP32_0(0) } },
+    /* 4*/{ { /*src1     */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_INF(1),  FP32_0(0), FP32_0(0), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_QNAN(1), FP32_0(0), FP32_0(0), FP32_0(0) } },
@@ -13203,15 +13710,8 @@
               /*256:out  */ X86_MXCSR_IE,
               /*xcpt?    */ false, true },
-          { { /*src1     */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_INF(1),  FP32_0(0), FP32_0(0), FP32_0(0) } },
-            { /*unused   */ { FP32_x8_UNUSED } },
-            { /* =>      */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_QNAN(1), FP32_0(0), FP32_0(0), FP32_0(0) } },
-              /*mxcsr:in */ X86_MXCSR_XCPT_MASK,
-              /*128:out  */ X86_MXCSR_XCPT_MASK,
-              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,
-              /*xcpt?    */ false, false },
     /*
      * Precision (Overflow, Underflow not possible).
      */
-    /* 7*/{ { /*src1     */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_2(0)                            } },
+    /* 5*/{ { /*src1     */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_2(0)                            } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_V(0, 0x3504f3, 0x7f)/*sqrt(2)*/ } },
@@ -13223,11 +13723,4 @@
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_V(0, 0x3504f3, 0x7f)/*sqrt(2)*/ } },
-              /*mxcsr:in */ X86_MXCSR_PM,
-              /*128:out  */ X86_MXCSR_PM,
-              /*256:out  */ X86_MXCSR_PM | X86_MXCSR_PE,
-              /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_2(0)                            } },
-            { /*unused   */ { FP32_x8_UNUSED } },
-            { /* =>      */ { FP32_0(0), FP32_1(0), FP32_1(0), FP32_0(1), FP32_1(0), FP32_0(0), FP32_1(0), FP32_V(0, 0x3504f3, 0x7f)/*sqrt(2)*/ } },
               /*mxcsr:in */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN,
               /*128:out  */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN,
@@ -13258,5 +13751,5 @@
      * Normals.
      */
-    /*13*/{ { /*src1     */ { FP32_NORM_V0(0), FP32_NORM_V1(0), FP32_NORM_V2(0), FP32_NORM_V3(0), FP32_NORM_V4(0), FP32_NORM_V5(0), FP32_NORM_V6(0), FP32_NORM_V7(0) } },
+    /*10*/{ { /*src1     */ { FP32_NORM_V0(0), FP32_NORM_V1(0), FP32_NORM_V2(0), FP32_NORM_V3(0), FP32_NORM_V4(0), FP32_NORM_V5(0), FP32_NORM_V6(0), FP32_NORM_V7(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x1ccf5c,0x40)/*sqrt(FP32_NORM_V0)*/,
@@ -13356,5 +13849,6 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_PE | X86_MXCSR_RC_ZERO,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_NORM_MAX(0),
+#ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE unexpectedly set in unmasked 256:out */
+ /*--|15*/{ { /*src1     */ { FP32_NORM_MAX(0),
                               FP32_NORM_MIN(0),
                               FP32_NORM_SAFE_INT_MAX(0),
@@ -13377,41 +13871,39 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_PE | X86_MXCSR_IE,
               /*xcpt?    */ false, false },
+#endif /* TODO_X86_MXCSR_PE */
     /** @todo More Normals. */
    /*
     * Denormals.
     */
-    /*19*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+#ifdef TODO_X86_MXCSR_PE /** @todo THESE FAIL ON IEM: X86_MXCSR_PE unexpectedly set in unmasked 256:out */
+ /*--|16*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x7fffff,0x3f), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
               /*mxcsr:in */ 0,
-              /*128:out  */ X86_MXCSR_DE,
-              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE,
+              /*128:out  */ X86_MXCSR_DE | X86_MXCSR_PE,
+              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ true, true },
-#ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE not set in 256:out */
- /*--|20*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|17*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x7fffff,0x3f), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
               /*mxcsr:in */ X86_MXCSR_DM,
               /*128:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_PE,
-              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_IE,
+              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ true, true },
-#endif /* TODO_X86_MXCSR_PE */
- /*20|21*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|18*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x7fffff,0x3f), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
               /*mxcsr:in */ X86_MXCSR_PM,
-              /*128:out  */ X86_MXCSR_PM | X86_MXCSR_DE,
-              /*256:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE,
+              /*128:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_PE,
+              /*256:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ true, true },
-#ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE unexpectedly set in 256:out */
- /*--|22*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|19*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x7fffff,0x3f), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
               /*mxcsr:in */ X86_MXCSR_DM | X86_MXCSR_PM,
               /*128:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_PE,
-              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE,
+              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ false, true },
-#endif /* TODO_X86_MXCSR_PE */
- /*21|23*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|20*/{ { /*src1     */ { FP32_DENORM_MAX(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MAX(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x7fffff,0x3f), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13420,12 +13912,12 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MIN(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MIN(1), FP32_0(1), FP32_0(0) } },
+ /*--|21*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MIN(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MIN(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3,0x34), FP32_V(0,0x3504f3,0x34), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
               /*mxcsr:in */ 0,
-              /*128:out  */ X86_MXCSR_DE,
-              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE,
+              /*128:out  */ X86_MXCSR_DE | X86_MXCSR_PE,
+              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ true, true },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MIN(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MIN(1), FP32_0(1), FP32_0(0) } },
+ /*--|22*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MIN(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MIN(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3,0x34), FP32_V(0,0x3504f3,0x34), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13434,5 +13926,5 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|23*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3+1,0x34), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),     FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13441,5 +13933,5 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_UP,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|24*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3,0x34), FP32_V(0,0x7fffff-1,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),     FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13448,5 +13940,5 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_DOWN,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|25*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3,0x34), FP32_V(0,0x7fffff-1,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),     FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13455,5 +13947,5 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_ZERO,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+ /*--|26*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_V(0,0x3504f3,0x34), FP32_V(0,0x7fffff,0x3f), FP32_0(0), FP32_0(1), FP32_QNAN(1),       FP32_QNAN(1),       FP32_0(1), FP32_0(0) } },
@@ -13462,5 +13954,6 @@
               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_FZ,
               /*xcpt?    */ false, false },
-          { { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
+#endif /* TODO_X86_MXCSR_PE */
+ /*15|27*/{ { /*src1     */ { FP32_DENORM_MIN(0),      FP32_DENORM_MAX(0),      FP32_0(0), FP32_0(1), FP32_DENORM_MIN(1), FP32_DENORM_MAX(1), FP32_0(1), FP32_0(0) } },
             { /*unused   */ { FP32_x8_UNUSED } },
             { /* =>      */ { FP32_0(0),               FP32_0(0),               FP32_0(0), FP32_0(1), FP32_0(1),          FP32_0(1),          FP32_0(1), FP32_0(0) } },
@@ -13474,5 +13967,5 @@
      */
     /** @todo Invalids. */
- /*29|31*/ /* FP32_TABLE_D10_PS_INVALIDS */
+ /*16|28*/ /* FP32_TABLE_D10_PS_INVALIDS */
     /** @todo Underflow, Precision; Rounding; FZ etc. */
     };
@@ -13525,5 +14018,5 @@
     static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64);
     unsigned const                         iTest       = BS3CPUINSTR4_TEST_MODES_INDEX(bMode);
-    return bs3CpuInstr4_WorkerTestType1(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
+    return bs3CpuInstr4_WorkerTestType1A(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
                                         g_aXcptConfig2, RT_ELEMENTS(g_aXcptConfig2));
 }
@@ -13660,4 +14153,8 @@
             {
                 /*
+                 * Poke the PRNG to print the seed before other output.
+                 */
+                (void)bs3CpuInstrX_SimpleRand();
+                /*
                  * Do the tests.
                  */
