VirtualBox

Changeset 106269 in vbox


Ignore:
Timestamp:
Oct 10, 2024 4:37:43 AM (7 weeks ago)
Author:
vboxsync
Message:

ValidationKit/bootsectors: fix indentation and comments; bugref:10658

+ assert that all mask type cases have been covered
+ merge a code path

File:
1 edited

Legend:

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

    r106268 r106269  
    26122612    uExpectedMxCsr = ((uExpectedMxCsr & ~BS3_MXCSR_FIXED_MASK) | uForceOnMask) & ~uForceOffMask;
    26132613
    2614     /*
    2615      * The test value tables give us the exceptions expected when run fully
    2616      * masked.  Here we try the instruction under multiple mask schemes: as
    2617      * requested by the value table; as implied by the stated resulting
    2618      * exceptions; fully masked; fully unmasked; and possibly some
    2619      * combinations.
    2620      *
    2621      * This is WORK IN PROGRESS code, and unclear whether it will be
    2622      * completed or will turn out to have been a bad idea.  The idea is to
    2623      * convert the existing instruction test functions one by one to use
    2624      * this.  Tables need updating because (1) some output rows are wrong
    2625      * for instructions which always raise an exception fgiven the stated
    2626      * mask; (2) output exceptions may be wrong for instructions which
    2627      * always raise an early DE exception, but would return a late exception
    2628      * (PE, OE, UE) if DE were masked; (3) entries which specify any or all
    2629      * exceptions already on in MXCSR must be modified to only show output
    2630      * exceptions which will be *newly* raised by the instruction itself.
    2631      *
    2632      * Code indentation is being retained the same as the parent Worker1
    2633      * functions for now, to facilitate co-fixing of any other issues found
    2634      * while this is under development.  Indentation will be fixed if/when
    2635      * this becomes the replacement Worker1.
    2636      */
    26372614    uExpectedMxCsr_orig = uExpectedMxCsr;
    26382615    uInitialExceptions = pValues->uMxCsr & X86_MXCSR_XCPT_FLAGS;
    26392616    uExpectedMask = uExpectedMxCsr_orig & X86_MXCSR_XCPT_MASK;
    26402617
    2641     /* Debug code to help convert the value tables; eventually replace with an assert */
    2642     if (!sfMismatchShown && (uSpecifiedMask != uExpectedMask))
    2643     {
    2644         Bs3TestFailedF("UNEXPECTED: specified mask %#RX32 != expected mask %#RX32 [only flagging 1st instance]\n", uExpectedMask, uSpecifiedMask);
    2645         sfMismatchShown = true;
    2646     }
     2618    /*
     2619     * The worker no longer insists that uSpecifiedMask == uExpectedMask.  While
     2620     * this is the usual state of affairs, a particular value entry could give
     2621     * different input and output masks to intentionally force extra testing of
     2622     * specific mask values.  This shouldn't actually provide any benefit since
     2623     * random masks will eventually (quickly -- in microseconds) hit all possible
     2624     * combinations; but perhaps there is some reason to do it in some cases?
     2625     * But in most cases, uSpecifiedMask, uExpectedMask, uImpliedMask, and
     2626     * uCombinedMask will be identical; duplicates will be filtered out by the
     2627     * uSeenMasks test.
     2628     */
    26472629    uImpliedMask = (uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS) << X86_MXCSR_XCPT_MASK_SHIFT;
    26482630    uCombinedMask = uSpecifiedMask | uImpliedMask;
     
    26502632    uUnmaskedMask = 0;
    26512633
    2652    for (iMaskType = 0; iMaskType <= 6; iMaskType++)
    2653    {
    2654     if (BS3_SKIPIT(0, 0, 0, pTestCtx->iVal, iMaskType))
    2655         continue;
    2656 
    2657     switch (iMaskType)
    2658     {
    2659         case 0:
    2660             uThisMask = uSpecifiedMask;
    2661             break;
    2662         case 1:
    2663             uThisMask = uExpectedMask;
    2664             break;
    2665         case 2:
    2666             uThisMask = uImpliedMask;
    2667             break;
    2668         case 3:
    2669             uThisMask = uCombinedMask;
    2670             break;
    2671         case 4:
    2672             uThisMask = uMaskedMask;
    2673             break;
    2674         case 5:
    2675             uThisMask = uUnmaskedMask;
    2676             break;
    2677         case 6:
    2678             /* This case must be last, as it trashes uSeenMasks & uInitialExceptions */
    2679             uRandTmp = bs3CpuInstrX_SimpleRand();
    2680             switch (uRandTmp & X86_MXCSR_RC_MASK)
     2634    /*
     2635     * The test value tables give us the exceptions expected when run fully
     2636     * masked.  Here we try the instruction under multiple mask schemes:
     2637     * as requested by the value table; as implied by the stated resulting
     2638     * exceptions; fully masked; fully unmasked; with a random mask; with
     2639     * random exceptions already turned on; both random mask & exceptions.
     2640     */
     2641    for (iMaskType = 0; iMaskType <= RT_ELEMENTS(s_apszMaskType); iMaskType++)
     2642    {
     2643        if (BS3_SKIPIT(0, 0, 0, pTestCtx->iVal, iMaskType))
     2644            continue;
     2645
     2646        switch (iMaskType)
     2647        {
     2648            case 0:
     2649                uThisMask = uSpecifiedMask;
     2650                break;
     2651            case 1:
     2652                uThisMask = uExpectedMask;
     2653                break;
     2654            case 2:
     2655                uThisMask = uImpliedMask;
     2656                break;
     2657            case 3:
     2658                uThisMask = uCombinedMask;
     2659                break;
     2660            case 4:
     2661                uThisMask = uMaskedMask;
     2662                break;
     2663            case 5:
     2664                uThisMask = uUnmaskedMask;
     2665                break;
     2666            case 6:
     2667                /* This case must be last, as it trashes uSeenMasks & uInitialExceptions */
     2668                /* Also confirm 1:1 cases implemented :: mask type descriptions */
     2669                BS3_ASSERT(iMaskType == RT_ELEMENTS(s_apszMaskType));
     2670
     2671                uRandTmp = bs3CpuInstrX_SimpleRand();
     2672                uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
     2673                switch (uRandTmp & X86_MXCSR_RC_MASK)
     2674                {
     2675                    case X86_MXCSR_RC_ZERO:
     2676                    case X86_MXCSR_RC_NEAREST:  /* Random mask */
     2677                        break;
     2678                    case X86_MXCSR_RC_UP:       /* Random initial exceptions */
     2679                        uThisMask = uSpecifiedMask;
     2680                        RT_FALL_THRU();
     2681                    case X86_MXCSR_RC_DOWN:     /* Random mask & initial exceptions */
     2682                        uSeenMasks = 0;         /* Don't skip for same-mask */
     2683                        uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
     2684                        break;
     2685                    default:
     2686                        BS3_ASSERT(0);
     2687                }
     2688                break;
     2689            default:
     2690                BS3_ASSERT(0);
     2691        }
     2692        /* No matter what was chosen, honor FIXED mask bits */
     2693        uThisMask = (uThisMask | uForceOnMask) & ~uForceOffMask;
     2694
     2695        /* Skip millions of redundant tests imposed by the mask twiddling scheme */
     2696        if (uSeenMasks & (RT_BIT_64(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT))) continue;
     2697        uSeenMasks |= RT_BIT_64(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
     2698
     2699        /* This is the input MXCSR value we'll be sending */
     2700        uMxCsr = (pValues->uMxCsr & ~(X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS)) | uThisMask | uInitialExceptions;
     2701
     2702        /* What exceptions does this test value claim to raise?  Only actual raises, not initially-on exceptions */
     2703        uExpectedExceptions = uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS;
     2704        uExpectedUnmaskedExceptions = uExpectedExceptions & ~(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
     2705
     2706        /* This is the output MXCSR value we will expect */
     2707        uExpectedMxCsr = (uExpectedMxCsr_orig & ~(X86_MXCSR_XCPT_MASK)) | uThisMask;
     2708
     2709        /* If we hit an unmasked early exception, late exceptions won't be raised. */
     2710        if (uExpectedUnmaskedExceptions & (X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_ZE))
     2711            uExpectedMxCsr &= ~(X86_MXCSR_OE | X86_MXCSR_PE | X86_MXCSR_UE);
     2712
     2713        /* However, all exceptions which are on before the instruction will still be on. */
     2714        uExpectedMxCsr |= uInitialExceptions;
     2715
     2716        /* A fault is raised only by unmasked exceptions which were caused by the instruction itself. */
     2717        fFpXcptExpected = (uExpectedUnmaskedExceptions != 0);
     2718
     2719        /*
     2720         * Set up the context and some expectations.
     2721         */
     2722        /* Destination. */
     2723        Bs3MemZero(&MemOpExpect, sizeof(MemOpExpect));
     2724        if (pTest->iRegDst == UINT8_MAX)
     2725        {
     2726            BS3_ASSERT(pTest->enmRm >= RM_MEM);
     2727            Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     2728            if (bXcptExpect == X86_XCPT_DB)
     2729                MemOpExpect.ymm = pValues->uDstOut.ymm;
     2730            else
     2731                Bs3MemSet(&MemOpExpect, 0xcc, sizeof(MemOpExpect));
     2732        }
     2733
     2734        /* Source #1 (/ destination for SSE). */
     2735        if (pTest->iRegSrc1 == UINT8_MAX)
     2736        {
     2737            BS3_ASSERT(pTest->enmRm >= RM_MEM);
     2738            Bs3MemCpy(puMemOpAlias, &pValues->uSrc1, cbMemOp);
     2739            if (pTest->iRegDst == UINT8_MAX)
     2740                BS3_ASSERT(fSseInstr);
     2741            else
     2742                MemOpExpect.ymm = pValues->uSrc1.ymm;
     2743        }
     2744        else if (fSseInstr)
     2745            Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm.DQWords.dqw0);
     2746        else
     2747            Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm, 32);
     2748
     2749        /* Source #2. */
     2750        if (pTest->iRegSrc2 == UINT8_MAX)
     2751        {
     2752            BS3_ASSERT(pTest->enmRm >= RM_MEM);
     2753            BS3_ASSERT(pTest->iRegDst != UINT8_MAX && pTest->iRegSrc1 != UINT8_MAX);
     2754            Bs3MemCpy(puMemOpAlias, &pValues->uSrc2, cbMemOp);
     2755            MemOpExpect.ymm = pValues->uSrc2.ymm;
     2756        }
     2757        else if (fSseInstr)
     2758            Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm.DQWords.dqw0);
     2759        else
     2760            Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm, 32);
     2761
     2762        /* Memory pointer. */
     2763        if (pTest->enmRm >= RM_MEM)
     2764        {
     2765            BS3_ASSERT(   pTest->iRegDst  == UINT8_MAX
     2766                       || pTest->iRegSrc1 == UINT8_MAX
     2767                       || pTest->iRegSrc2 == UINT8_MAX);
     2768            Bs3RegCtxSetGrpSegFromCurPtr(pCtx, &pCtx->rbx, &pCtx->fs, puMemOp);
     2769        }
     2770
     2771        /* Setup MXCSR for the current test. */
     2772        uMxCsr |= (pSavedCfg->uMxCsr & X86_MXCSR_MM);
     2773        BS3_ASSERT(!(uMxCsr & X86_MXCSR_MM));
     2774        BS3_ASSERT(!(uMxCsr & X86_MXCSR_DAZ) || g_fMxCsrDazSupported);
     2775        Bs3ExtCtxSetMxCsr(pExtCtx, uMxCsr);
     2776
     2777        /*
     2778         * Prepare globals and execute.
     2779         */
     2780        g_uBs3TrapEipHint = pCtx->rip.u32;
     2781        if (    bXcptExpect == X86_XCPT_DB
     2782            && !fFpXcptExpected)
     2783            g_uBs3TrapEipHint += cbInstr + 1;
     2784        Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(pCtx, pExtCtx, pTrapFrame, pExtCtxOut);
     2785
     2786        /*
     2787         * Check the result.
     2788         *
     2789         * If a floating-point exception is expected, the destination is not updated by the instruction.
     2790         * In the case of SSE instructions, updating the destination here will work because it is the same
     2791         * as the source, but for AVX++ it won't because the destination is different and would contain 0s.
     2792         */
     2793        cErrors = Bs3TestSubErrorCount();
     2794        if (   bXcptExpect == X86_XCPT_DB
     2795            && !fFpXcptExpected
     2796            && pTest->iRegDst != UINT8_MAX)
     2797        {
     2798            if (fSseInstr)
     2799                Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm.DQWords.dqw0);
     2800            else
     2801                Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm, cbOperand);
     2802        }
     2803#if     defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
     2804        if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
     2805            && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
     2806            && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
     2807            pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
     2808#endif
     2809
     2810        if (bXcptExpect == X86_XCPT_DB)
     2811        {
     2812            if (fFuzzyPE)
    26812813            {
    2682                 case X86_MXCSR_RC_ZERO:
    2683                 case X86_MXCSR_RC_NEAREST:  /* Random mask */
    2684                     uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
    2685                     break;
    2686                 case X86_MXCSR_RC_UP:       /* Random initial exceptions */
    2687                     uThisMask = uSpecifiedMask;
    2688                     uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
    2689                     uSeenMasks = 0;         /* Don't skip for same-mask */
    2690                     break;
    2691                 case X86_MXCSR_RC_DOWN:     /* Random mask & initial exceptions */
    2692                     uThisMask = uRandTmp & X86_MXCSR_XCPT_MASK;
    2693                     uInitialExceptions = uRandTmp & X86_MXCSR_XCPT_FLAGS;
    2694                     uSeenMasks = 0;         /* Don't skip for same-mask */
    2695                     break;
    2696                 default:
    2697                     BS3_ASSERT(0);
     2814                uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut);
     2815                uExpectedMxCsr = (uExpectedMxCsr & ~X86_MXCSR_PE) | (uGotMxCsr & X86_MXCSR_PE);
    26982816            }
    2699             break;
    2700         default:
    2701             BS3_ASSERT(0);
    2702     }
    2703     /* No matter what was chosen, honor FIXED mask bits */
    2704     uThisMask = (uThisMask | uForceOnMask) & ~uForceOffMask;
    2705 
    2706     /* Skip millions of redundant tests imposed by the mask twiddling scheme */
    2707     if (uSeenMasks & (RT_BIT_64(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT))) continue;
    2708     uSeenMasks |= RT_BIT_64(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
    2709 
    2710     /* This is the input MXCSR value we'll be sending */
    2711     uMxCsr = (pValues->uMxCsr & ~(X86_MXCSR_XCPT_MASK | X86_MXCSR_XCPT_FLAGS)) | uThisMask | uInitialExceptions;
    2712 
    2713     /* What exceptions does this test value claim to raise?  Only actual raises, not initially-on exceptions */
    2714     uExpectedExceptions = uExpectedMxCsr_orig & X86_MXCSR_XCPT_FLAGS;
    2715     uExpectedUnmaskedExceptions = uExpectedExceptions & ~(uThisMask >> X86_MXCSR_XCPT_MASK_SHIFT);
    2716 
    2717     /* This is the output MXCSR value we will expect */
    2718     uExpectedMxCsr = (uExpectedMxCsr_orig & ~(X86_MXCSR_XCPT_MASK)) | uThisMask;
    2719 
    2720     /* If we hit an unmasked early exception, late exceptions won't be raised. */
    2721     if (uExpectedUnmaskedExceptions & (X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_ZE))
    2722         uExpectedMxCsr &= ~(X86_MXCSR_OE | X86_MXCSR_PE | X86_MXCSR_UE);
    2723 
    2724     /* However, all exceptions which are on before the instruction will still be on. */
    2725     uExpectedMxCsr |= uInitialExceptions;
    2726 
    2727     /* A fault is raised only by unmasked exceptions which were caused by the instruction itself. */
    2728     fFpXcptExpected = (uExpectedUnmaskedExceptions != 0);
    2729 
    2730     /*
    2731      * Set up the context and some expectations.
    2732      */
    2733     /* Destination. */
    2734     Bs3MemZero(&MemOpExpect, sizeof(MemOpExpect));
    2735     if (pTest->iRegDst == UINT8_MAX)
    2736     {
    2737         BS3_ASSERT(pTest->enmRm >= RM_MEM);
    2738         Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp);
     2817            Bs3ExtCtxSetMxCsr(pExtCtx, uExpectedMxCsr | (pSavedCfg->uMxCsr & X86_MXCSR_MM));
     2818        }
     2819
     2820        Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pTestCtx->pszMode, pTestCtx->idTestStep);
     2821
    27392822        if (bXcptExpect == X86_XCPT_DB)
    2740             MemOpExpect.ymm = pValues->uDstOut.ymm;
    2741         else
    2742             Bs3MemSet(&MemOpExpect, 0xcc, sizeof(MemOpExpect));
    2743     }
    2744 
    2745     /* Source #1 (/ destination for SSE). */
    2746     if (pTest->iRegSrc1 == UINT8_MAX)
    2747     {
    2748         BS3_ASSERT(pTest->enmRm >= RM_MEM);
    2749         Bs3MemCpy(puMemOpAlias, &pValues->uSrc1, cbMemOp);
    2750         if (pTest->iRegDst == UINT8_MAX)
    2751             BS3_ASSERT(fSseInstr);
    2752         else
    2753             MemOpExpect.ymm = pValues->uSrc1.ymm;
    2754     }
    2755     else if (fSseInstr)
    2756         Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm.DQWords.dqw0);
    2757     else
    2758         Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc1, &pValues->uSrc1.ymm, 32);
    2759 
    2760     /* Source #2. */
    2761     if (pTest->iRegSrc2 == UINT8_MAX)
    2762     {
    2763         BS3_ASSERT(pTest->enmRm >= RM_MEM);
    2764         BS3_ASSERT(pTest->iRegDst != UINT8_MAX && pTest->iRegSrc1 != UINT8_MAX);
    2765         Bs3MemCpy(puMemOpAlias, &pValues->uSrc2, cbMemOp);
    2766         MemOpExpect.ymm = pValues->uSrc2.ymm;
    2767     }
    2768     else if (fSseInstr)
    2769         Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm.DQWords.dqw0);
    2770     else
    2771         Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegSrc2, &pValues->uSrc2.ymm, 32);
    2772 
    2773     /* Memory pointer. */
    2774     if (pTest->enmRm >= RM_MEM)
    2775     {
    2776         BS3_ASSERT(   pTest->iRegDst  == UINT8_MAX
    2777                    || pTest->iRegSrc1 == UINT8_MAX
    2778                    || pTest->iRegSrc2 == UINT8_MAX);
    2779         Bs3RegCtxSetGrpSegFromCurPtr(pCtx, &pCtx->rbx, &pCtx->fs, puMemOp);
    2780     }
    2781 
    2782     /* Setup MXCSR for the current test. */
    2783     uMxCsr |= (pSavedCfg->uMxCsr & X86_MXCSR_MM);
    2784     BS3_ASSERT(!(uMxCsr & X86_MXCSR_MM));
    2785     BS3_ASSERT(!(uMxCsr & X86_MXCSR_DAZ) || g_fMxCsrDazSupported);
    2786     Bs3ExtCtxSetMxCsr(pExtCtx, uMxCsr);
    2787 
    2788     /*
    2789      * Prepare globals and execute.
    2790      */
    2791     g_uBs3TrapEipHint = pCtx->rip.u32;
    2792     if (    bXcptExpect == X86_XCPT_DB
    2793         && !fFpXcptExpected)
    2794         g_uBs3TrapEipHint += cbInstr + 1;
    2795     Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(pCtx, pExtCtx, pTrapFrame, pExtCtxOut);
    2796 
    2797     /*
    2798      * Check the result.
    2799      *
    2800      * If a floating-point exception is expected, the destination is not updated by the instruction.
    2801      * In the case of SSE instructions, updating the destination here will work because it is the same
    2802      * as the source, but for AVX++ it won't because the destination is different and would contain 0s.
    2803      */
    2804     cErrors = Bs3TestSubErrorCount();
    2805     if (   bXcptExpect == X86_XCPT_DB
    2806         && !fFpXcptExpected
    2807         && pTest->iRegDst != UINT8_MAX)
    2808     {
    2809         if (fSseInstr)
    2810             Bs3ExtCtxSetXmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm.DQWords.dqw0);
    2811         else
    2812             Bs3ExtCtxSetYmm(pExtCtx, pTest->iRegDst, &pValues->uDstOut.ymm, cbOperand);
    2813     }
    2814 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */
    2815     if (   pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE
    2816         && pExtCtx->Ctx.x.Hdr.bmXState == 0x7
    2817         && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3)
    2818         pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7;
    2819 #endif
    2820 
    2821     if (bXcptExpect == X86_XCPT_DB)
    2822     {
    2823         if (fFuzzyPE)
    28242823        {
    2825             uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut);
    2826             uExpectedMxCsr = (uExpectedMxCsr & ~X86_MXCSR_PE) | (uGotMxCsr & X86_MXCSR_PE);
    2827         }
    2828         Bs3ExtCtxSetMxCsr(pExtCtx, uExpectedMxCsr | (pSavedCfg->uMxCsr & X86_MXCSR_MM));
    2829     }
    2830 
    2831     Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pTestCtx->pszMode, pTestCtx->idTestStep);
    2832 
    2833     if (bXcptExpect == X86_XCPT_DB)
    2834     {
    2835         uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut) & ~X86_MXCSR_MM;
    2836 
    2837         /* Check if the SIMD FP exception flags and mask (or lack of) are as expected. */
    2838         if (uGotMxCsr != uExpectedMxCsr)
    2839         {
    2840             char szExpectFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
    2841             char szExpectMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
    2842             char szExpectOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
    2843             char szGotFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
    2844             char szGotMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
    2845             char szGotOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
    2846             bs3CpuInstr4GetXcptFlags(&szExpectFlags[0],   sizeof(szExpectFlags),  uExpectedMxCsr);
    2847             bs3CpuInstr4GetXcptMasks(&szExpectMasks[0],   sizeof(szExpectMasks),  uExpectedMxCsr);
    2848             bs3CpuInstr4GetXcptOthers(&szExpectOthers[0], sizeof(szExpectOthers), uExpectedMxCsr);
    2849             bs3CpuInstr4GetXcptFlags(&szGotFlags[0],   sizeof(szGotFlags),  uGotMxCsr);
    2850             bs3CpuInstr4GetXcptMasks(&szGotMasks[0],   sizeof(szGotMasks),  uGotMxCsr);
    2851             bs3CpuInstr4GetXcptOthers(&szGotOthers[0], sizeof(szGotOthers), uGotMxCsr);
    2852             Bs3TestFailedF("Expected MXCSR %#RX32 (%s%s%s ) got MXCSR %#RX32 (%s%s%s )", uExpectedMxCsr,
    2853                            szExpectFlags, szExpectMasks, szExpectOthers, uGotMxCsr, szGotFlags, szGotMasks, szGotOthers);
    2854         }
    2855 
    2856         /* Check if the SIMD FP exception (or lack of) is as expected. */
    2857         if (fFpXcptExpected)
    2858         {
    2859             if (pTrapFrame->bXcpt == bFpXcpt)
     2824            uint32_t const uGotMxCsr = Bs3ExtCtxGetMxCsr(pExtCtxOut) & ~X86_MXCSR_MM;
     2825
     2826            /* Check if the SIMD FP exception flags and mask (or lack of) are as expected. */
     2827            if (uGotMxCsr != uExpectedMxCsr)
     2828            {
     2829                char szExpectFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
     2830                char szExpectMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
     2831                char szExpectOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
     2832                char szGotFlags[FP_XCPT_FLAGS_NAMES_MAXLEN];
     2833                char szGotMasks[FP_XCPT_MASKS_NAMES_MAXLEN];
     2834                char szGotOthers[FP_XCPT_OTHERS_NAMES_MAXLEN];
     2835                bs3CpuInstr4GetXcptFlags(&szExpectFlags[0],   sizeof(szExpectFlags),  uExpectedMxCsr);
     2836                bs3CpuInstr4GetXcptMasks(&szExpectMasks[0],   sizeof(szExpectMasks),  uExpectedMxCsr);
     2837                bs3CpuInstr4GetXcptOthers(&szExpectOthers[0], sizeof(szExpectOthers), uExpectedMxCsr);
     2838                bs3CpuInstr4GetXcptFlags(&szGotFlags[0],   sizeof(szGotFlags),  uGotMxCsr);
     2839                bs3CpuInstr4GetXcptMasks(&szGotMasks[0],   sizeof(szGotMasks),  uGotMxCsr);
     2840                bs3CpuInstr4GetXcptOthers(&szGotOthers[0], sizeof(szGotOthers), uGotMxCsr);
     2841                Bs3TestFailedF("Expected MXCSR %#RX32 (%s%s%s ) got MXCSR %#RX32 (%s%s%s )", uExpectedMxCsr,
     2842                               szExpectFlags, szExpectMasks, szExpectOthers, uGotMxCsr, szGotFlags, szGotMasks, szGotOthers);
     2843            }
     2844
     2845            /* Check if the SIMD FP exception (or lack of) is as expected. */
     2846            if (fFpXcptExpected)
     2847            {
     2848                if (pTrapFrame->bXcpt == bFpXcpt)
     2849                { /* likely */ }
     2850                else
     2851                    Bs3TestFailedF("Expected floating-point xcpt %s, got %s", bs3CpuInstr4XcptName(bFpXcpt),
     2852                                   bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     2853            }
     2854            else if (pTrapFrame->bXcpt == X86_XCPT_DB)
    28602855            { /* likely */ }
    28612856            else
    2862                 Bs3TestFailedF("Expected floating-point xcpt %s, got %s", bs3CpuInstr4XcptName(bFpXcpt),
    2863                                bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     2857                Bs3TestFailedF("Expected no xcpt, got %s", bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
    28642858        }
    2865         else if (pTrapFrame->bXcpt == X86_XCPT_DB)
    2866         { /* likely */ }
    2867         else
    2868             Bs3TestFailedF("Expected no xcpt, got %s", bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     2859        /* Check if non-FP exception is as expected. */
     2860        else if (pTrapFrame->bXcpt != bXcptExpect)
     2861            Bs3TestFailedF("Expected xcpt %s, got %s", bs3CpuInstr4XcptName(bXcptExpect), bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
     2862
     2863        /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
     2864        if (bMode == BS3_MODE_RM && (pCtx->rflags.u32 & X86_EFL_AC))
     2865        {
     2866            if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_AC)
     2867                Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", pTrapFrame->bXcpt);
     2868            pTrapFrame->Ctx.rflags.u32 |= X86_EFL_AC;
     2869        }
     2870        if (bXcptExpect == X86_XCPT_PF)
     2871            pCtx->cr2.u = (uintptr_t)puMemOp;
     2872        Bs3TestCheckRegCtxEx(&pTrapFrame->Ctx, pCtx, bXcptExpect == X86_XCPT_DB && !fFpXcptExpected ? cbInstr + 1 : 0, 0 /*cbSpAdjust*/,
     2873                             (bXcptExpect == X86_XCPT_DB && !fFpXcptExpected) || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
     2874                             pTestCtx->pszMode, pTestCtx->idTestStep);
     2875        pCtx->cr2.u = 0;
     2876
     2877        if (   pTest->enmRm >= RM_MEM
     2878            && Bs3MemCmp(puMemOpAlias, &MemOpExpect, cbMemOp) != 0)
     2879            Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &MemOpExpect, cbMemOp, puMemOpAlias);
     2880
     2881        if (cErrors != Bs3TestSubErrorCount())
     2882            Bs3TestFailedF("Mask mode %s, mask=%#RX32, in-exceptions=%#RX32, in-MxCsr=%#RX32, expect-MxCsr=%#RX32", s_apszMaskType[iMaskType], uThisMask, uInitialExceptions, uMxCsr, uExpectedMxCsr);
    28692883    }
    2870     /* Check if non-FP exception is as expected. */
    2871     else if (pTrapFrame->bXcpt != bXcptExpect)
    2872         Bs3TestFailedF("Expected xcpt %s, got %s", bs3CpuInstr4XcptName(bXcptExpect), bs3CpuInstr4XcptName(pTrapFrame->bXcpt));
    2873 
    2874     /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */
    2875     if (bMode == BS3_MODE_RM && (pCtx->rflags.u32 & X86_EFL_AC))
    2876     {
    2877         if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_AC)
    2878             Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", pTrapFrame->bXcpt);
    2879         pTrapFrame->Ctx.rflags.u32 |= X86_EFL_AC;
    2880     }
    2881     if (bXcptExpect == X86_XCPT_PF)
    2882         pCtx->cr2.u = (uintptr_t)puMemOp;
    2883     Bs3TestCheckRegCtxEx(&pTrapFrame->Ctx, pCtx, bXcptExpect == X86_XCPT_DB && !fFpXcptExpected ? cbInstr + 1 : 0, 0 /*cbSpAdjust*/,
    2884                          (bXcptExpect == X86_XCPT_DB && !fFpXcptExpected) || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF,
    2885                          pTestCtx->pszMode, pTestCtx->idTestStep);
    2886     pCtx->cr2.u = 0;
    2887 
    2888     if (   pTest->enmRm >= RM_MEM
    2889         && Bs3MemCmp(puMemOpAlias, &MemOpExpect, cbMemOp) != 0)
    2890         Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &MemOpExpect, cbMemOp, puMemOpAlias);
    2891 
    2892     if (cErrors != Bs3TestSubErrorCount())
    2893         Bs3TestFailedF("Mask mode %s, mask=%#RX32, in-exceptions=%#RX32, in-MxCsr=%#RX32, expect-MxCsr=%#RX32", s_apszMaskType[iMaskType], uThisMask, uInitialExceptions, uMxCsr, uExpectedMxCsr);
    2894    }
    28952884
    28962885    return cErrorsInit;
Note: See TracChangeset for help on using the changeset viewer.

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