VirtualBox

Ignore:
Timestamp:
Sep 28, 2024 6:41:24 AM (7 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164958
Message:

ValidationKit/bootsectors: automatically test varied MXCSR masks & initially-set exceptions [WIP]; adapt sqrtps & minss first; bugref:10658

This introduces a 'Worker 1A' which is intended to eventually replace
Worker 1, but will require converting the test value tables of most
instructions. Committing with just minss & sqrtps instructions
converted so far:

  • minss: remove '| X86_MXCSR_XCPT_FLAGS' from 3 entries: let the worker do that
  • minss: fix an entry with wrong 'dst' value (previously masked by fault)
  • sqrtps: remove 3 now-redundant entries
  • sqrtps: #ifdef out many entries which currently fail on IEM

Also:

  • move PRNG code outside #ifdef BS3_SKIPIT_DO_SKIP as the MXCSR code uses it
  • print initial PRNG seed to help reproduce issues
  • set a reasonable default BS3_SKIPIT_REPORT_COUNT for new scheme
File:
1 edited

Legend:

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

    r106148 r106174  
    15811581            { /*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) } },                                        \
    15821582            { /* =>      */ { 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) } },                                        \
    1583               /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
    1584               /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
    1585               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS,                                                                                                                                       \
     1583              /*mxcsr:in */ X86_MXCSR_XCPT_MASK,                                                                                                                                                              \
     1584              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,                                                                                                                                               \
     1585              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,                                                                                                                                               \
    15861586              /*xcpt?    */ false, false },                                                                                                                                                                   \
    15871587    /* SNan, Normal (Masked). */                                                                                                                                                                              \
     
    23182318
    23192319
    2320 /*
    2321  * Code to make testing the tests faster. `bs3CpuInstrX_SkipIt()' randomly
    2322  * skips a large fraction of the micro-tests.  It is sufficiently random
    2323  * that over a large number of runs, all micro-tests will be hit.
    2324  *
    2325  * This improves the runtime of the worst case (`#define ALL_TESTS' on a
    2326  * debug build, run with '--execute-all-in-iem') from ~9000 to ~800 seconds
    2327  * (on an Intel Core i7-10700, fwiw).
    2328  *
    2329  * To activate this 'developer's speed-testing mode', turn on
    2330  * `#define BS3_SKIPIT_DO_SKIP' here.
    2331  *
    2332  * BS3_SKIPIT_AVG_SKIP governs approximately how many micro-tests are
    2333  * skipped in a row; e.g. the default of 26 means about every 27th
    2334  * micro-test is run during a particular test run.  (This is not 27x
    2335  * faster due to other activities which are not skipped!)  Note this is
    2336  * only an average; the actual skips are random.
    2337  *
    2338  * You can also modify bs3CpuInstrX_SkipIt() to focus on specific sub-tests,
    2339  * using its (currently ignored) `bRing, iCfg, iTest, iVal, iVariant' args
    2340  * (to enable this: turn on `#define BS3_SKIPIT_DO_ARGS': which costs about
    2341  * 3% performance).
    2342  *
    2343  * Note! The skipping is not compatible with testing the native recompiler as
    2344  *       it requires the test code to be run a number of times before it kicks
    2345  *       in and does the native recompilation (currently around 16 times).
    2346  */
    2347 #define BS3_SKIPIT_AVG_SKIP     26
    2348 #define BS3_SKIPIT_REPORT_COUNT 150000
    2349 #undef  BS3_SKIPIT_DO_SKIP
    2350 #undef  BS3_SKIPIT_DO_ARGS
    2351 
    2352 #ifndef BS3_SKIPIT_DO_SKIP
    2353 # define BS3_SKIPIT(bRing, iCfg, iTest, iVal, iVariant) (false)
    2354 #else
    2355 # include <iprt/asm-amd64-x86.h>
    2356 # include <iprt/asm-math.h>
     2320#include <iprt/asm-amd64-x86.h>
     2321#include <iprt/asm-math.h>
    23572322
    23582323DECLINLINE(uint32_t) bs3CpuInstrX_SimpleRand(void)
     
    23742339    uint32_t uVal = s_uSeedMemory;
    23752340    if (!uVal)
     2341    {
    23762342        uVal = (uint32_t)ASMReadTSC();
     2343        Bs3TestPrintf("PRNG initial seed: 0x%08lx\n", uVal);
     2344    }
    23772345    uVal = ASMModU64ByU32RetU32(ASMMult2xU32RetU64(uVal, 16807), INT32_MAX);
    23782346    s_uSeedMemory = uVal;
     
    23802348}
    23812349
     2350
     2351/*
     2352 * Code to make testing the tests faster. `bs3CpuInstrX_SkipIt()' randomly
     2353 * skips a fraction of the micro-tests.  It is sufficiently random that
     2354 * over a large number of runs, all micro-tests will be hit.
     2355 *
     2356 * Full test runs take ever longer as we add more instructions and fancier
     2357 * ways of testing them.  In one example scenario, a debug build running
     2358 * bs3-cpu-instr-3 under interpreted IEM went from 9000 to 800 seconds,
     2359 * with BS3_SKIPIT_AVG_SKIP on the default 26.
     2360 *
     2361 * To activate this 'developer's speed-testing mode', turn on
     2362 * `#define BS3_SKIPIT_DO_SKIP' here.
     2363 *
     2364 * BS3_SKIPIT_AVG_SKIP governs approximately how many micro-tests are
     2365 * skipped in a row; e.g. the default of 26 means that on average, every
     2366 * 26th micro-test is run during a particular test run.  (This is not 26x
     2367 * faster, due to other activities which are not skipped!)  Note this is
     2368 * only an average; the actual skips are random.
     2369 *
     2370 * You can also modify bs3CpuInstrX_SkipIt() to focus on specific sub-tests,
     2371 * using its (currently ignored) `bRing, iCfg, iTest, iVal, iVariant' args
     2372 * (to enable this: turn on `#define BS3_SKIPIT_DO_ARGS': which costs about
     2373 * 3% performance).
     2374 *
     2375 * Note!  For testing the native recompiler, configure the VM to invoke
     2376 * native recompilation quickly with:
     2377 *
     2378 *     VBoxManage setextradata vmname VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled 1
     2379 *     VBoxManage setextradata vmname VBoxInternal/Devices/VMMDev/0/Config/TestingThresholdNativeRecompiler 2
     2380 *     VBoxManage setextradata vmname VBoxInternal/IEM/NativeRecompileAtUsedCount 1
     2381 */
     2382#define BS3_SKIPIT_AVG_SKIP          26
     2383#define BS3_SKIPIT_REPORT_COUNT 1000000
     2384#undef  BS3_SKIPIT_DO_SKIP
     2385#undef  BS3_SKIPIT_DO_ARGS
     2386
     2387#ifndef BS3_SKIPIT_DO_SKIP
     2388# define BS3_SKIPIT(bRing, iCfg, iTest, iVal, iVariant) (false)
     2389#else
    23822390static unsigned g_cSeen, g_cSkipped;
    23832391
     
    29412949                            TestCtx.idTestStep   = idTestStep;
    29422950                            cErrors = bs3CpuInstr4_WorkerTestType1_Inner(bMode, &TestCtx, &SavedCfg);
     2951                            if (cErrors != Bs3TestSubErrorCount())
     2952                            {
     2953                                if (paConfigs[iCfg].fAligned)
     2954                                    Bs3TestFailedF("%s: ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%u %s, %s %u-bit)",
     2955                                                   Bs3GetModeName(bMode), bRing, iCfg, iTest, iVal,
     2956                                                   bXcptExpect, bs3CpuInstr4XcptName(bXcptExpect), fSseInstr ? "SSE" : "AVX", cbOperand * 8);
     2957                                else
     2958                                    Bs3TestFailedF("%s: ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%u %s, puMemOp=%p, EFLAGS=%#RX32, %s %u-bit)",
     2959                                                   Bs3GetModeName(bMode), bRing, iCfg, iTest, iVal,
     2960                                                   bXcptExpect, bs3CpuInstr4XcptName(bXcptExpect), puMemOp,
     2961                                                   TrapFrame.Ctx.rflags.u32, fSseInstr ? "SSE" : "AVX", cbOperand * 8);
     2962                                Bs3TestPrintf("\n");
     2963                            }
     2964                        }
     2965                    }
     2966                }
     2967                bs3CpuInstrXConfigRestore(&SavedCfg, &Ctx, pExtCtx);
     2968            }
     2969        } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode));
     2970
     2971        /*
     2972         * Next ring.
     2973         */
     2974        bRing++;
     2975        if (bRing > 3 || bMode == BS3_MODE_RM)
     2976            break;
     2977        Bs3RegCtxConvertToRingX(&Ctx, bRing);
     2978    }
     2979
     2980    /*
     2981     * Cleanup.
     2982     */
     2983    bs3CpuInstrXBufCleanup(pbBuf, cbBuf, bMode);
     2984    bs3CpuInstrXFreeExtCtxs(pExtCtx, pExtCtxOut);
     2985    return 0;
     2986}
     2987
     2988
     2989/**
     2990 * Worker for bs3CpuInstr4_WorkerTestType1 [new WIP version]
     2991 */
     2992static uint16_t bs3CpuInstr4_WorkerTestType1A_Inner(uint8_t bMode, PBS3CPUINSTR4_TEST1_CTX_T pTestCtx,
     2993                                                   PCBS3CPUINSTRX_CONFIG_SAVED_T pSavedCfg)
     2994{
     2995    BS3CPUINSTR4_TEST1_T const BS3_FAR        *pTest   = pTestCtx->pTest;
     2996    BS3CPUINSTR4_TEST1_VALUES_T const BS3_FAR *pValues = &pTestCtx->pTest->paValues[pTestCtx->iVal];
     2997    PBS3TRAPFRAME    pTrapFrame          = pTestCtx->pTrapFrame;
     2998    PBS3REGCTX       pCtx                = pTestCtx->pCtx;
     2999    PBS3EXTCTX       pExtCtx             = pTestCtx->pExtCtx;
     3000    PBS3EXTCTX       pExtCtxOut          = pTestCtx->pExtCtxOut;
     3001    uint8_t BS3_FAR *puMemOp             = pTestCtx->puMemOp;
     3002    uint8_t BS3_FAR *puMemOpAlias        = pTestCtx->puMemOpAlias;
     3003    uint8_t          cbMemOp             = pTestCtx->cbMemOp;
     3004    uint8_t const    cbOperand           = pTestCtx->cbOperand;
     3005    uint8_t const    cbInstr             = ((uint8_t const BS3_FAR *)(uintptr_t)pTestCtx->pTest->pfnWorker)[-1];
     3006    uint8_t          bXcptExpect         = pTestCtx->bXcptExpect;
     3007    uint8_t const    bFpXcpt             = pTestCtx->pConfig->fCr4OsXmmExcpt ? X86_XCPT_XF : X86_XCPT_UD;
     3008    bool const       fSseInstr           = bs3CpuInstr4IsSse(pTest->enmType);
     3009    uint32_t         uMxCsr;
     3010    X86YMMREG        MemOpExpect;
     3011    uint16_t         cErrors;
     3012    uint16_t         cErrorsInit         = Bs3TestSubErrorCount();
     3013    uint32_t         uExpectedMxCsr;
     3014    bool             fFpXcptExpected;
     3015
     3016    uint32_t uSpecifiedMask, uExpectedMask, uImpliedMask, uCombinedMask, uMaskedMask, uUnmaskedMask, uThisMask;
     3017    uint32_t uExpectedMxCsr_orig, uExpectedExceptions, uExpectedUnmaskedExceptions, uInitialExceptions, uRandTmp;
     3018    const char *pszMaskType;
     3019    unsigned iMaskType;
     3020    static bool      sfMismatchShown     = false;
     3021
     3022    /*
     3023     * An exception may be raised based on the test value (128 vs 256 bits).
     3024     * In addition, we allow setting the exception flags (and mask) prior to
     3025     * executing the instruction, so we cannot use the exception flags to figure
     3026     * out if an exception will be raised. Hence, the input values provide us
     3027     * explicitly whether an exception is expected for 128 and 256-bit variants.
     3028     */  /** @todo rewrite this to reflect 'worker 1a' when ready to commit */
     3029    if (pTestCtx->cbOperand > 16)
     3030    {
     3031        uExpectedMxCsr  = pValues->u256ExpectedMxCsr;
     3032        fFpXcptExpected = pValues->f256FpXcptExpected;
     3033    }
     3034    else
     3035    {
     3036        uExpectedMxCsr  = pValues->u128ExpectedMxCsr;
     3037        fFpXcptExpected = pValues->f128FpXcptExpected;
     3038    }
     3039
     3040    /*
     3041     * The test value tables give us the exceptions expected when run fully
     3042     * masked.  Here we try the instruction under multiple mask schemes: as
     3043     * requested by the value table; as implied by the stated resulting
     3044     * exceptions; fully masked; fully unmasked; and possibly some
     3045     * combinations.
     3046     *
     3047     * This is WORK IN PROGRESS code, and unclear whether it will be
     3048     * completed or will turn out to have been a bad idea.  The idea is to
     3049     * convert the existing instruction test functions one by one to use
     3050     * this.  Tables need updating because (1) some output rows are wrong
     3051     * for instructions which always raise an exception fgiven the stated
     3052     * mask; (2) output exceptions may be wrong for instructions which
     3053     * always raise an early DE exception, but would return a late exception
     3054     * (PE, OE, UE) if DE were masked; (3) entries which specify any or all
     3055     * exceptions already on in MXCSR must be modified to only show output
     3056     * exceptions which will be *newly* raised by the instruction itself.
     3057     *
     3058     * Code indentation is being retained the same as the parent Worker1
     3059     * functions for now, to facilitate co-fixing of any other issues found
     3060     * while this is under development.  Indentation will be fixed if/when
     3061     * this becomes the replacement Worker1.
     3062     */
     3063    uExpectedMxCsr_orig = uExpectedMxCsr;
     3064    uInitialExceptions = pValues->uMxCsr & X86_MXCSR_XCPT_FLAGS;
     3065    uSpecifiedMask = pValues->uMxCsr & X86_MXCSR_XCPT_MASK;
     3066    uExpectedMask = uExpectedMxCsr_orig & X86_MXCSR_XCPT_MASK;
     3067
     3068    /* Debug code to help convert the value tables; eventually replace with an assert */
     3069    if (!sfMismatchShown && (uSpecifiedMask != uExpectedMask))
     3070    {
     3071        Bs3TestFailedF("UNEXPECTED: specified mask %#RX32 != expected mask %#RX32 [only flagging 1st instance]\n", uExpectedMask, uSpecifiedMask);
     3072        sfMismatchShown = true;
     3073    }
     3074    uImpliedMask = (uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS) << X86_MXCSR_XCPT_MASK_SHIFT;
     3075    uCombinedMask = uSpecifiedMask | uImpliedMask;
     3076    uMaskedMask = X86_MXCSR_XCPT_MASK;
     3077    uUnmaskedMask = 0;
     3078
     3079   for (iMaskType = 0; iMaskType <= 6; iMaskType++)
     3080   {
     3081    if (BS3_SKIPIT(0, 0, 0, pTestCtx->iVal, iMaskType))
     3082        continue;
     3083
     3084    switch (iMaskType)
     3085    {
     3086        case 0:
     3087            uThisMask = uSpecifiedMask;
     3088            pszMaskType = "Specified";
     3089            break;
     3090        case 1:
     3091            if (uExpectedMask == uSpecifiedMask) continue;
     3092            uThisMask = uExpectedMask;
     3093            pszMaskType = "Expected";
     3094            break;
     3095        case 2:
     3096            if (uImpliedMask == uSpecifiedMask || uImpliedMask == uExpectedMask) continue;
     3097            uThisMask = uImpliedMask;
     3098            pszMaskType = "Implied";
     3099            break;
     3100        case 3:
     3101            if (uCombinedMask == uSpecifiedMask || uCombinedMask == uExpectedMask || uCombinedMask == uImpliedMask) continue;
     3102            uThisMask = uCombinedMask;
     3103            pszMaskType = "Combined";
     3104            break;
     3105        case 4:
     3106            if (uMaskedMask == uSpecifiedMask || uMaskedMask == uExpectedMask || uMaskedMask == uImpliedMask || uMaskedMask == uCombinedMask) continue;
     3107            uThisMask = uMaskedMask;
     3108            pszMaskType = "Masked";
     3109            break;
     3110        case 5:
     3111            if (uUnmaskedMask == uSpecifiedMask || uUnmaskedMask == uExpectedMask || uUnmaskedMask == uImpliedMask || uUnmaskedMask == uCombinedMask) continue;
     3112            uThisMask = uUnmaskedMask;
     3113            pszMaskType = "Unmasked";
     3114            break;
     3115        case 6:
     3116            uRandTmp = bs3CpuInstrX_SimpleRand();
     3117            switch (uRandTmp & X86_MXCSR_RC_MASK)
     3118            {
     3119                case X86_MXCSR_RC_ZERO:
     3120                case X86_MXCSR_RC_NEAREST:
     3121                    uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
     3122                    break;
     3123                case X86_MXCSR_RC_DOWN:
     3124                    uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
     3125                    uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
     3126                    break;
     3127                case X86_MXCSR_RC_UP:
     3128                    uThisMask = uSpecifiedMask;
     3129                    uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
     3130                    break;
     3131                default:
     3132                    BS3_ASSERT(0);
     3133            }
     3134            pszMaskType = "Random";
     3135            break;
     3136        /** @todo Consider providing assorted already-set exceptions (WIP) */
     3137        /** @todo Consider only-early exceptions masked; only-late exceptions masked */
     3138        /** @todo Consider only-early-specified exceptions masked; only-late-specified exceptions masked */
     3139        /** -- I think actually this is all covered by the Random case.  Over time. */
     3140        default:
     3141            BS3_ASSERT(0);
     3142    }
     3143    /* This is the input MXCSR value we'll be sending */
     3144    uMxCsr = (pValues->uMxCsr & ~(X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS)) | uThisMask | uInitialExceptions;
     3145
     3146    /* What exceptions does this test value claim to raise?  Only actual raises, not initially-on exceptions */
     3147    uExpectedExceptions = uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS;
     3148    uExpectedUnmaskedExceptions = uExpectedExceptions & ~(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
     3149
     3150    /* This is the output MXCSR value we will expect */
     3151    uExpectedMxCsr = (uExpectedMxCsr_orig & ~(X86_MXCSR_XCPT_MASK)) | uThisMask;
     3152
     3153    /* If we hit an unmasked early exception, late exceptions won't be raised. */
     3154    if (uExpectedUnmaskedExceptions & (X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_ZE))
     3155        uExpectedMxCsr &= ~(X86_MXCSR_OE | X86_MXCSR_PE | X86_MXCSR_UE);
     3156
     3157    /* However, all exceptions which are on before the instruction will still be on. */
     3158    uExpectedMxCsr |= uInitialExceptions;
     3159
     3160    /* A fault is raised only by unmasked exceptions which were caused by the instruction itself. */
     3161    fFpXcptExpected = (uExpectedUnmaskedExceptions != 0);
     3162
     3163    /*
     3164     * Set up the context and some expectations.
     3165     */
     3166    /* Destination. */
     3167    Bs3MemZero(&MemOpExpect, sizeof(MemOpExpect));
     3168    if (pTest->iRegDst == UINT8_MAX)
     3169    {
     3170        BS3_ASSERT(pTest->enmRm >= RM_MEM);
     3171        Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     3172        if (bXcptExpect == X86_XCPT_DB)
     3173            MemOpExpect.ymm = pValues->uDstOut.ymm;
     3174        else
     3175            Bs3MemSet(&MemOpExpect, 0xcc, sizeof(MemOpExpect));
     3176    }
     3177
     3178    /* Source #1 (/ destination for SSE). */
     3179    if (pTest->iRegSrc1 == UINT8_MAX)
     3180    {
     3181        BS3_ASSERT(pTest->enmRm >= RM_MEM);
     3182        Bs3MemCpy(puMemOpAlias, &pValues->uSrc1, cbMemOp);
     3183        if (pTest->iRegDst == UINT8_MAX)
     3184            BS3_ASSERT(fSseInstr);
     3185        else
     3186            MemOpExpect.ymm = pValues->uSrc1.ymm;
     3187    }
     3188    else if (fSseInstr)
     3189        Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm.DQWords.dqw0);
     3190    else
     3191        Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm, 32);
     3192
     3193    /* Source #2. */
     3194    if (pTest->iRegSrc2 == UINT8_MAX)
     3195    {
     3196        BS3_ASSERT(pTest->enmRm >= RM_MEM);
     3197        BS3_ASSERT(pTest->iRegDst != UINT8_MAX && pTest->iRegSrc1 != UINT8_MAX);
     3198        Bs3MemCpy(puMemOpAlias, &pValues->uSrc2, cbMemOp);
     3199        MemOpExpect.ymm = pValues->uSrc2.ymm;
     3200    }
     3201    else if (fSseInstr)
     3202        Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm.DQWords.dqw0);
     3203    else
     3204        Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm, 32);
     3205
     3206    /* Memory pointer. */
     3207    if (pTest->enmRm >= RM_MEM)
     3208    {
     3209        BS3_ASSERT(   pTest->iRegDst  == UINT8_MAX
     3210                   || pTest->iRegSrc1 == UINT8_MAX
     3211                   || pTest->iRegSrc2 == UINT8_MAX);
     3212        Bs3RegCtxSetGrpSegFromCurPtr(pCtx, &pCtx->rbx, &pCtx->fs, puMemOp);
     3213    }
     3214
     3215    /* Setup MXCSR for the current test. */
     3216    uMxCsr |= (pSavedCfg->uMxCsr & X86_MXCSR_MM);
     3217    BS3_ASSERT(!(uMxCsr & X86_MXCSR_MM));
     3218    BS3_ASSERT(!(uMxCsr & X86_MXCSR_DAZ) || g_fMxCsrDazSupported);
     3219    Bs3ExtCtxSetMxCsr(pExtCtx, uMxCsr);
     3220
     3221    /*
     3222     * Prepare globals and execute.
     3223     */
     3224    g_uBs3TrapEipHint = pCtx->rip.u32;
     3225    if (    bXcptExpect == X86_XCPT_DB
     3226        && !fFpXcptExpected)
     3227        g_uBs3TrapEipHint += cbInstr + 1;
     3228    Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(pCtx, pExtCtx, pTrapFrame, pExtCtxOut);
     3229
     3230    /*
     3231     * Check the result.
     3232     *
     3233     * If a floating-point exception is expected, the destination is not updated by the instruction.
     3234     * In the case of SSE instructions, updating the destination here will work because it is the same
     3235     * as the source, but for AVX++ it won't because the destination is different and would contain 0s.
     3236     */
     3237    cErrors = Bs3TestSubErrorCount();
     3238    if (   bXcptExpect == X86_XCPT_DB
     3239        && !fFpXcptExpected
     3240        && pTest->iRegDst != UINT8_MAX)
     3241    {
     3242        if (fSseInstr)
     3243            Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm.DQWords.dqw0);
     3244        else
     3245            Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm, cbOperand);
     3246    }
     3247#if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
     3248    if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
     3249        && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
     3250        && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
     3251        pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
     3252#endif
     3253    if (bXcptExpect == X86_XCPT_DB)
     3254        Bs3ExtCtxSetMxCsr(pExtCtx, uExpectedMxCsr | (pSavedCfg->uMxCsr & X86_MXCSR_MM));
     3255    Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pTestCtx->pszMode, pTestCtx->idTestStep);
     3256
     3257    if (bXcptExpect == X86_XCPT_DB)
     3258    {
     3259        uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut) & ~X86_MXCSR_MM;
     3260
     3261        /* Check if the SIMD FP exception flags and mask (or lack of) are as expected. */
     3262        if (uGotMxCsr != uExpectedMxCsr)
     3263        {
     3264            char szExpectFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
     3265            char szExpectMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
     3266            char szExpectOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
     3267            char szGotFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
     3268            char szGotMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
     3269            char szGotOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
     3270            bs3CpuInstr4GetXcptFlags(&szExpectFlags[0],   sizeof(szExpectFlags),  uExpectedMxCsr);
     3271            bs3CpuInstr4GetXcptMasks(&szExpectMasks[0],   sizeof(szExpectMasks),  uExpectedMxCsr);
     3272            bs3CpuInstr4GetXcptOthers(&szExpectOthers[0], sizeof(szExpectOthers), uExpectedMxCsr);
     3273            bs3CpuInstr4GetXcptFlags(&szGotFlags[0],   sizeof(szGotFlags),  uGotMxCsr);
     3274            bs3CpuInstr4GetXcptMasks(&szGotMasks[0],   sizeof(szGotMasks),  uGotMxCsr);
     3275            bs3CpuInstr4GetXcptOthers(&szGotOthers[0], sizeof(szGotOthers), uGotMxCsr);
     3276            Bs3TestFailedF("Expected MXCSR %#RX32 (%s%s%s ) got MXCSR %#RX32 (%s%s%s )", uExpectedMxCsr,
     3277                           szExpectFlags, szExpectMasks, szExpectOthers, uGotMxCsr, szGotFlags, szGotMasks, szGotOthers);
     3278        }
     3279
     3280        /* Check if the SIMD FP exception (or lack of) is as expected. */
     3281        if (fFpXcptExpected)
     3282        {
     3283            if (pTrapFrame->bXcpt == bFpXcpt)
     3284            { /* likely */ }
     3285            else
     3286                Bs3TestFailedF("Expected floating-point xcpt %s, got %s", bs3CpuInstr4XcptName(bFpXcpt),
     3287                               bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     3288        }
     3289        else if (pTrapFrame->bXcpt == X86_XCPT_DB)
     3290        { /* likely */ }
     3291        else
     3292            Bs3TestFailedF("Expected no xcpt, got %s", bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     3293    }
     3294    /* Check if non-FP exception is as expected. */
     3295    else if (pTrapFrame->bXcpt != bXcptExpect)
     3296        Bs3TestFailedF("Expected xcpt %s, got %s", bs3CpuInstr4XcptName(bXcptExpect), bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     3297
     3298    /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     3299    if (bMode == BS3_MODE_RM && (pCtx->rflags.u32 & X86_EFL_AC))
     3300    {
     3301        if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_AC)
     3302            Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", pTrapFrame->bXcpt);
     3303        pTrapFrame->Ctx.rflags.u32 |= X86_EFL_AC;
     3304    }
     3305    if (bXcptExpect == X86_XCPT_PF)
     3306        pCtx->cr2.u = (uintptr_t)puMemOp;
     3307    Bs3TestCheckRegCtxEx(&pTrapFrame->Ctx, pCtx, bXcptExpect == X86_XCPT_DB && !fFpXcptExpected ? cbInstr + 1 : 0, 0 /*cbSpAdjust*/,
     3308                         (bXcptExpect == X86_XCPT_DB && !fFpXcptExpected) || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     3309                         pTestCtx->pszMode, pTestCtx->idTestStep);
     3310    pCtx->cr2.u = 0;
     3311
     3312    if (   pTest->enmRm >= RM_MEM
     3313        && Bs3MemCmp(puMemOpAlias, &MemOpExpect, cbMemOp) != 0)
     3314        Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &MemOpExpect, cbMemOp, puMemOpAlias);
     3315
     3316    /* Most-not-all of this will be removed once debugged */
     3317    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);
     3318   }
     3319
     3320    return cErrorsInit;
     3321}
     3322
     3323
     3324/**
     3325 * Test type #1 worker [new WIP version].
     3326 */
     3327static uint8_t bs3CpuInstr4_WorkerTestType1A(uint8_t bMode, BS3CPUINSTR4_TEST1_T const BS3_FAR *paTests, unsigned cTests,
     3328                                            PCBS3CPUINSTR4_CONFIG_T paConfigs, unsigned cConfigs)
     3329{
     3330    BS3REGCTX                   Ctx;
     3331    BS3TRAPFRAME                TrapFrame;
     3332    const char BS3_FAR * const  pszMode = Bs3GetModeName(bMode);
     3333    uint8_t                     bRing   = BS3_MODE_IS_V86(bMode) ? 3 : 0;
     3334    uint8_t BS3_FAR            *pbBuf   = g_pbBuf;
     3335    uint32_t                    cbBuf   = g_cbBuf;
     3336    PBS3EXTCTX                  pExtCtxOut;
     3337    PBS3EXTCTX                  pExtCtx = bs3CpuInstrXAllocExtCtxs(&pExtCtxOut);
     3338    if (pExtCtx)
     3339    { /* likely */ }
     3340    else
     3341        return 0;
     3342    if (pExtCtx->enmMethod != BS3EXTCTXMETHOD_ANCIENT)
     3343    { /* likely */ }
     3344    else
     3345    {
     3346        Bs3TestPrintf("Skipped due to ancient FPU state format\n");
     3347        return 0;
     3348    }
     3349
     3350    /* Ensure the structures are allocated before we sample the stack pointer. */
     3351    Bs3MemSet(&Ctx, 0, sizeof(Ctx));
     3352    Bs3MemSet(&TrapFrame, 0, sizeof(TrapFrame));
     3353
     3354    /*
     3355     * Create test context.
     3356     */
     3357    pbBuf = bs3CpuInstrXBufSetup(pbBuf, &cbBuf, bMode);
     3358    Bs3RegCtxSaveForMode(&Ctx, bMode, 1024);
     3359    bs3CpuInstr4SetupSseAndAvx(&Ctx, pExtCtx);
     3360
     3361    /*
     3362     * Run the tests in all rings since alignment issues may behave
     3363     * differently in ring-3 compared to ring-0.
     3364     */
     3365    for (;;)
     3366    {
     3367        unsigned fPf = 0;
     3368        do
     3369        {
     3370            unsigned iCfg;
     3371            for (iCfg = 0; iCfg < cConfigs; iCfg++)
     3372            {
     3373                unsigned                    iTest;
     3374                BS3CPUINSTRX_CONFIG_SAVED_T SavedCfg;
     3375                if (!bs3CpuInstr4ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode))
     3376                    continue; /* unsupported config */
     3377
     3378                /*
     3379                 * Iterate the tests.
     3380                 */
     3381                for (iTest = 0; iTest < cTests; iTest++)
     3382                {
     3383                    BS3CPUINSTR4_TEST1_T const BS3_FAR *pTest = &paTests[iTest];
     3384                    unsigned const    cValues       = pTest->cValues;
     3385                    bool const        fSseInstr     = bs3CpuInstr4IsSse(pTest->enmType);
     3386                    bool const        fAvxInstr     = bs3CpuInstr4IsAvx(pTest->enmType);
     3387                    uint8_t const     cbOperand     = bs3CpuInstr4GetOperandSize(pTest->enmType);
     3388                    uint8_t const     cbMemOp       = bs3CpuInstrXMemOpSize(cbOperand, pTest->enmRm);
     3389                    uint8_t const     cbAlign       = cbMemOp;
     3390                    uint8_t BS3_FAR  *puMemOp       = bs3CpuInstrXBufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf);
     3391                    uint8_t          *puMemOpAlias  = &g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf];
     3392                    uint8_t           bXcptExpect   = !g_afTypeSupports[pTest->enmType] ? X86_XCPT_UD
     3393                                                    : fSseInstr ? paConfigs[iCfg].bXcptSse
     3394                                                    : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx;
     3395                    uint16_t         idTestStep     = bRing * 10000 + iCfg * 100 + iTest * 10;
     3396                    unsigned         cRecompRuns    = 0;
     3397                    unsigned const   cMaxRecompRuns = g_cBs3ThresholdNativeRecompiler + cValues;
     3398                    unsigned         iVal;
     3399
     3400                    /* If testing unaligned memory accesses (or #PF), skip register-only tests.  This
     3401                       allows setting bXcptSse and bXcptAvx to reflect the misaligned exceptions. */
     3402                    if (   (pTest->enmRm == RM_REG || pTest->enmRm == RM_MEM8)
     3403                        && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf))
     3404                        continue;
     3405
     3406                    /* #AC is only raised in ring-3. */
     3407                    if (bXcptExpect == X86_XCPT_AC)
     3408                    {
     3409                        if (bRing != 3)
     3410                            bXcptExpect = X86_XCPT_DB;
     3411                        else if (fAvxInstr)
     3412                            bXcptExpect = pTest->bAvxMisalignXcpt; /* they generally don't raise #AC */
     3413                    }
     3414
     3415                    if (fPf && bXcptExpect == X86_XCPT_DB)
     3416                        bXcptExpect = X86_XCPT_PF;
     3417
     3418                    Bs3RegCtxSetRipCsFromCurPtr(&Ctx, pTest->pfnWorker);
     3419
     3420                    /*
     3421                     * Iterate the test values and do the actual testing.
     3422                     */
     3423                    while (cRecompRuns < cMaxRecompRuns)
     3424                    {
     3425                        for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++)
     3426                        {
     3427                            uint16_t                 cErrors;
     3428                            BS3CPUINSTR4_TEST1_CTX_T TestCtx;
     3429
     3430                            /*
     3431                             * If the hardware does not support DAZ bit skip test values that set it.
     3432                             */
     3433                            if (   !g_fMxCsrDazSupported
     3434                                && (pTest->paValues[iVal].uMxCsr & X86_MXCSR_DAZ))
     3435                                continue;
     3436
     3437                            /*
     3438                             * Setup the test instruction context and pass it to the worker.
     3439                             * A few of these can be figured out by the worker but initializing
     3440                             * it outside the inner most loop is more optimal.
     3441                             */
     3442                            TestCtx.pConfig      = &paConfigs[iCfg];
     3443                            TestCtx.pTest        = pTest;
     3444                            TestCtx.iVal         = iVal;
     3445                            TestCtx.pszMode      = pszMode;
     3446                            TestCtx.pTrapFrame   = &TrapFrame;
     3447                            TestCtx.pCtx         = &Ctx;
     3448                            TestCtx.pExtCtx      = pExtCtx;
     3449                            TestCtx.pExtCtxOut   = pExtCtxOut;
     3450                            TestCtx.puMemOp      = (uint8_t *)puMemOp;
     3451                            TestCtx.puMemOpAlias = puMemOpAlias;
     3452                            TestCtx.cbMemOp      = cbMemOp;
     3453                            TestCtx.cbOperand    = cbOperand;
     3454                            TestCtx.bXcptExpect  = bXcptExpect;
     3455                            TestCtx.idTestStep   = idTestStep;
     3456                            cErrors = bs3CpuInstr4_WorkerTestType1A_Inner(bMode, &TestCtx, &SavedCfg);
    29433457                            if (cErrors != Bs3TestSubErrorCount())
    29443458                            {
     
    1228712801            { /* =>      */ { 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) } },
    1228812802              /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
    12289               /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
    12290               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
     12803              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
     12804              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_DOWN,
    1229112805              /*xcpt?    */ false, false },
    1229212806          { { /*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) } },
     
    1230112815            { /* =>      */ { 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) } },
    1230212816              /*mxcsr:in */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
    12303               /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
    12304               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
     12817              /*128:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
     12818              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
    1230512819              /*xcpt?    */ false, false },
    1230612820          { { /*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) } },
     
    1257513089    /*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) } },
    1257613090            { /*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) } },
    12577             { /* =>      */ { 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) } },
     13091            { /* =>      */ { 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) } },
    1257813092              /*mxcsr:in */ 0,
    1257913093              /*128:out  */ X86_MXCSR_DE,
     
    1268313197    static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64);
    1268413198    unsigned const                         iTest       = BS3CPUINSTR4_TEST_MODES_INDEX(bMode);
    12685     return bs3CpuInstr4_WorkerTestType1(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
     13199    return bs3CpuInstr4_WorkerTestType1A(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
    1268613200                                        g_aXcptConfig3, RT_ELEMENTS(g_aXcptConfig3));
    1268713201}
     
    1316813682            { /*unused   */ { FP32_x8_UNUSED } },
    1316913683            { /* =>      */ { FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(1), FP32_0(1), FP32_0(1), FP32_0(1) } },
    13170               /*mxcsr:in */ 0,
    13171               /*128:out  */ 0,
    13172               /*256:out  */ 0,
    13173               /*xcpt?    */ false, false },
    13174           { { /*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) } },
    13175             { /*unused   */ { FP32_x8_UNUSED } },
    13176             { /* =>      */ { FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_0(1), FP32_0(1), FP32_0(1), FP32_0(1) } },
    1317713684              /*mxcsr:in */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
    1317813685              /*128:out  */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP,
     
    1319613703     * Infinity.
    1319713704     */
    13198     /* 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) } },
     13705    /* 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) } },
    1319913706            { /*unused   */ { FP32_x8_UNUSED } },
    1320013707            { /* =>      */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_QNAN(1), FP32_0(0), FP32_0(0), FP32_0(0) } },
     
    1320313710              /*256:out  */ X86_MXCSR_IE,
    1320413711              /*xcpt?    */ false, true },
    13205           { { /*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) } },
    13206             { /*unused   */ { FP32_x8_UNUSED } },
    13207             { /* =>      */ { FP32_INF(0), FP32_0(0), FP32_0(0), FP32_0(0), FP32_QNAN(1), FP32_0(0), FP32_0(0), FP32_0(0) } },
    13208               /*mxcsr:in */ X86_MXCSR_XCPT_MASK,
    13209               /*128:out  */ X86_MXCSR_XCPT_MASK,
    13210               /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_IE,
    13211               /*xcpt?    */ false, false },
    1321213712    /*
    1321313713     * Precision (Overflow, Underflow not possible).
    1321413714     */
    13215     /* 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)                            } },
     13715    /* 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)                            } },
    1321613716            { /*unused   */ { FP32_x8_UNUSED } },
    1321713717            { /* =>      */ { 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)*/ } },
     
    1322313723            { /*unused   */ { FP32_x8_UNUSED } },
    1322413724            { /* =>      */ { 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)*/ } },
    13225               /*mxcsr:in */ X86_MXCSR_PM,
    13226               /*128:out  */ X86_MXCSR_PM,
    13227               /*256:out  */ X86_MXCSR_PM | X86_MXCSR_PE,
    13228               /*xcpt?    */ false, false },
    13229           { { /*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)                            } },
    13230             { /*unused   */ { FP32_x8_UNUSED } },
    13231             { /* =>      */ { 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)*/ } },
    1323213725              /*mxcsr:in */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN,
    1323313726              /*128:out  */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN,
     
    1325813751     * Normals.
    1325913752     */
    13260     /*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) } },
     13753    /*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) } },
    1326113754            { /*unused   */ { FP32_x8_UNUSED } },
    1326213755            { /* =>      */ { FP32_V(0,0x1ccf5c,0x40)/*sqrt(FP32_NORM_V0)*/,
     
    1335613849              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_PE | X86_MXCSR_RC_ZERO,
    1335713850              /*xcpt?    */ false, false },
    13358           { { /*src1     */ { FP32_NORM_MAX(0),
     13851#ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE unexpectedly set in unmasked 256:out */
     13852 /*--|15*/{ { /*src1     */ { FP32_NORM_MAX(0),
    1335913853                              FP32_NORM_MIN(0),
    1336013854                              FP32_NORM_SAFE_INT_MAX(0),
     
    1337713871              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_PE | X86_MXCSR_IE,
    1337813872              /*xcpt?    */ false, false },
     13873#endif /* TODO_X86_MXCSR_PE */
    1337913874    /** @todo More Normals. */
    1338013875   /*
    1338113876    * Denormals.
    1338213877    */
    13383     /*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) } },
     13878#ifdef TODO_X86_MXCSR_PE /** @todo THESE FAIL ON IEM: X86_MXCSR_PE unexpectedly set in unmasked 256:out */
     13879 /*--|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) } },
    1338413880            { /*unused   */ { FP32_x8_UNUSED } },
    1338513881            { /* =>      */ { 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) } },
    1338613882              /*mxcsr:in */ 0,
    13387               /*128:out  */ X86_MXCSR_DE,
    13388               /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE,
     13883              /*128:out  */ X86_MXCSR_DE | X86_MXCSR_PE,
     13884              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1338913885              /*xcpt?    */ true, true },
    13390 #ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE not set in 256:out */
    13391  /*--|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) } },
     13886 /*--|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) } },
    1339213887            { /*unused   */ { FP32_x8_UNUSED } },
    1339313888            { /* =>      */ { 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) } },
    1339413889              /*mxcsr:in */ X86_MXCSR_DM,
    1339513890              /*128:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_PE,
    13396               /*256:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_IE,
     13891              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1339713892              /*xcpt?    */ true, true },
    13398 #endif /* TODO_X86_MXCSR_PE */
    13399  /*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) } },
     13893 /*--|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) } },
    1340013894            { /*unused   */ { FP32_x8_UNUSED } },
    1340113895            { /* =>      */ { 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) } },
    1340213896              /*mxcsr:in */ X86_MXCSR_PM,
    13403               /*128:out  */ X86_MXCSR_PM | X86_MXCSR_DE,
    13404               /*256:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE,
     13897              /*128:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_PE,
     13898              /*256:out  */ X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1340513899              /*xcpt?    */ true, true },
    13406 #ifdef TODO_X86_MXCSR_PE /** @todo THIS FAILS ON IEM: X86_MXCSR_PE unexpectedly set in 256:out */
    13407  /*--|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) } },
     13900 /*--|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) } },
    1340813901            { /*unused   */ { FP32_x8_UNUSED } },
    1340913902            { /* =>      */ { 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) } },
    1341013903              /*mxcsr:in */ X86_MXCSR_DM | X86_MXCSR_PM,
    1341113904              /*128:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_PE,
    13412               /*256:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE,
     13905              /*256:out  */ X86_MXCSR_DM | X86_MXCSR_PM | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1341313906              /*xcpt?    */ false, true },
    13414 #endif /* TODO_X86_MXCSR_PE */
    13415  /*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) } },
     13907 /*--|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) } },
    1341613908            { /*unused   */ { FP32_x8_UNUSED } },
    1341713909            { /* =>      */ { 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) } },
     
    1342013912              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1342113913              /*xcpt?    */ false, false },
    13422           { { /*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) } },
     13914 /*--|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) } },
    1342313915            { /*unused   */ { FP32_x8_UNUSED } },
    1342413916            { /* =>      */ { 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) } },
    1342513917              /*mxcsr:in */ 0,
    13426               /*128:out  */ X86_MXCSR_DE,
    13427               /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE,
     13918              /*128:out  */ X86_MXCSR_DE | X86_MXCSR_PE,
     13919              /*256:out  */ X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1342813920              /*xcpt?    */ true, true },
    13429           { { /*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) } },
     13921 /*--|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) } },
    1343013922            { /*unused   */ { FP32_x8_UNUSED } },
    1343113923            { /* =>      */ { 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) } },
     
    1343413926              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE,
    1343513927              /*xcpt?    */ false, false },
    13436           { { /*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) } },
     13928 /*--|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) } },
    1343713929            { /*unused   */ { FP32_x8_UNUSED } },
    1343813930            { /* =>      */ { 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) } },
     
    1344113933              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_UP,
    1344213934              /*xcpt?    */ false, false },
    13443           { { /*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) } },
     13935 /*--|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) } },
    1344413936            { /*unused   */ { FP32_x8_UNUSED } },
    1344513937            { /* =>      */ { 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) } },
     
    1344813940              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_DOWN,
    1344913941              /*xcpt?    */ false, false },
    13450           { { /*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) } },
     13942 /*--|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) } },
    1345113943            { /*unused   */ { FP32_x8_UNUSED } },
    1345213944            { /* =>      */ { 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) } },
     
    1345513947              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_ZERO,
    1345613948              /*xcpt?    */ false, false },
    13457           { { /*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) } },
     13949 /*--|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) } },
    1345813950            { /*unused   */ { FP32_x8_UNUSED } },
    1345913951            { /* =>      */ { 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) } },
     
    1346213954              /*256:out  */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_FZ,
    1346313955              /*xcpt?    */ false, false },
    13464           { { /*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) } },
     13956#endif /* TODO_X86_MXCSR_PE */
     13957 /*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) } },
    1346513958            { /*unused   */ { FP32_x8_UNUSED } },
    1346613959            { /* =>      */ { FP32_0(0),               FP32_0(0),               FP32_0(0), FP32_0(1), FP32_0(1),          FP32_0(1),          FP32_0(1), FP32_0(0) } },
     
    1347413967     */
    1347513968    /** @todo Invalids. */
    13476  /*29|31*/ /* FP32_TABLE_D10_PS_INVALIDS */
     13969 /*16|28*/ /* FP32_TABLE_D10_PS_INVALIDS */
    1347713970    /** @todo Underflow, Precision; Rounding; FZ etc. */
    1347813971    };
     
    1352514018    static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64);
    1352614019    unsigned const                         iTest       = BS3CPUINSTR4_TEST_MODES_INDEX(bMode);
    13527     return bs3CpuInstr4_WorkerTestType1(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
     14020    return bs3CpuInstr4_WorkerTestType1A(bMode, s_aTests[iTest].paTests, s_aTests[iTest].cTests,
    1352814021                                        g_aXcptConfig2, RT_ELEMENTS(g_aXcptConfig2));
    1352914022}
     
    1366014153            {
    1366114154                /*
     14155                 * Poke the PRNG to print the seed before other output.
     14156                 */
     14157                (void)bs3CpuInstrX_SimpleRand();
     14158                /*
    1366214159                 * Do the tests.
    1366314160                 */
Note: See TracChangeset for help on using the changeset viewer.

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