Changeset 106174 in vbox for trunk/src/VBox/ValidationKit/bootsectors
- Timestamp:
- Sep 28, 2024 6:41:24 AM (7 months ago)
- svn:sync-xref-src-repo-rev:
- 164958
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-4.c32
r106148 r106174 1581 1581 { /*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) } }, \ 1582 1582 { /* => */ { 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, \ 1586 1586 /*xcpt? */ false, false }, \ 1587 1587 /* SNan, Normal (Masked). */ \ … … 2318 2318 2319 2319 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> 2357 2322 2358 2323 DECLINLINE(uint32_t) bs3CpuInstrX_SimpleRand(void) … … 2374 2339 uint32_t uVal = s_uSeedMemory; 2375 2340 if (!uVal) 2341 { 2376 2342 uVal = (uint32_t)ASMReadTSC(); 2343 Bs3TestPrintf("PRNG initial seed: 0x%08lx\n", uVal); 2344 } 2377 2345 uVal = ASMModU64ByU32RetU32(ASMMult2xU32RetU64(uVal, 16807), INT32_MAX); 2378 2346 s_uSeedMemory = uVal; … … 2380 2348 } 2381 2349 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 2382 2390 static unsigned g_cSeen, g_cSkipped; 2383 2391 … … 2941 2949 TestCtx.idTestStep = idTestStep; 2942 2950 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 */ 2992 static 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 */ 3327 static 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); 2943 3457 if (cErrors != Bs3TestSubErrorCount()) 2944 3458 { … … 12287 12801 { /* => */ { 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) } }, 12288 12802 /*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, 12291 12805 /*xcpt? */ false, false }, 12292 12806 { { /*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 12815 { /* => */ { 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) } }, 12302 12816 /*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, 12305 12819 /*xcpt? */ false, false }, 12306 12820 { { /*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 13089 /*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) } }, 12576 13090 { /*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) } }, 12578 13092 /*mxcsr:in */ 0, 12579 13093 /*128:out */ X86_MXCSR_DE, … … 12683 13197 static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64); 12684 13198 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, 12686 13200 g_aXcptConfig3, RT_ELEMENTS(g_aXcptConfig3)); 12687 13201 } … … 13168 13682 { /*unused */ { FP32_x8_UNUSED } }, 13169 13683 { /* => */ { 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) } },13177 13684 /*mxcsr:in */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP, 13178 13685 /*128:out */ X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_RC_UP, … … 13196 13703 * Infinity. 13197 13704 */ 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) } }, 13199 13706 { /*unused */ { FP32_x8_UNUSED } }, 13200 13707 { /* => */ { 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 13710 /*256:out */ X86_MXCSR_IE, 13204 13711 /*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 },13212 13712 /* 13213 13713 * Precision (Overflow, Underflow not possible). 13214 13714 */ 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) } }, 13216 13716 { /*unused */ { FP32_x8_UNUSED } }, 13217 13717 { /* => */ { 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 13723 { /*unused */ { FP32_x8_UNUSED } }, 13224 13724 { /* => */ { 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)*/ } },13232 13725 /*mxcsr:in */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN, 13233 13726 /*128:out */ X86_MXCSR_PM | X86_MXCSR_RC_DOWN, … … 13258 13751 * Normals. 13259 13752 */ 13260 /*1 3*/{ { /*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) } }, 13261 13754 { /*unused */ { FP32_x8_UNUSED } }, 13262 13755 { /* => */ { FP32_V(0,0x1ccf5c,0x40)/*sqrt(FP32_NORM_V0)*/, … … 13356 13849 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_PE | X86_MXCSR_RC_ZERO, 13357 13850 /*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), 13359 13853 FP32_NORM_MIN(0), 13360 13854 FP32_NORM_SAFE_INT_MAX(0), … … 13377 13871 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DAZ | X86_MXCSR_FZ | X86_MXCSR_PE | X86_MXCSR_IE, 13378 13872 /*xcpt? */ false, false }, 13873 #endif /* TODO_X86_MXCSR_PE */ 13379 13874 /** @todo More Normals. */ 13380 13875 /* 13381 13876 * Denormals. 13382 13877 */ 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) } }, 13384 13880 { /*unused */ { FP32_x8_UNUSED } }, 13385 13881 { /* => */ { 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) } }, 13386 13882 /*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, 13389 13885 /*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) } }, 13392 13887 { /*unused */ { FP32_x8_UNUSED } }, 13393 13888 { /* => */ { 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) } }, 13394 13889 /*mxcsr:in */ X86_MXCSR_DM, 13395 13890 /*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, 13397 13892 /*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) } }, 13400 13894 { /*unused */ { FP32_x8_UNUSED } }, 13401 13895 { /* => */ { 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) } }, 13402 13896 /*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, 13405 13899 /*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) } }, 13408 13901 { /*unused */ { FP32_x8_UNUSED } }, 13409 13902 { /* => */ { 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) } }, 13410 13903 /*mxcsr:in */ X86_MXCSR_DM | X86_MXCSR_PM, 13411 13904 /*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, 13413 13906 /*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) } }, 13416 13908 { /*unused */ { FP32_x8_UNUSED } }, 13417 13909 { /* => */ { 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 13912 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE, 13421 13913 /*xcpt? */ false, false }, 13422 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) } }, 13423 13915 { /*unused */ { FP32_x8_UNUSED } }, 13424 13916 { /* => */ { 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) } }, 13425 13917 /*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, 13428 13920 /*xcpt? */ true, true }, 13429 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) } }, 13430 13922 { /*unused */ { FP32_x8_UNUSED } }, 13431 13923 { /* => */ { 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 13926 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE, 13435 13927 /*xcpt? */ false, false }, 13436 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) } }, 13437 13929 { /*unused */ { FP32_x8_UNUSED } }, 13438 13930 { /* => */ { 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 13933 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_UP, 13442 13934 /*xcpt? */ false, false }, 13443 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) } }, 13444 13936 { /*unused */ { FP32_x8_UNUSED } }, 13445 13937 { /* => */ { 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 13940 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_DOWN, 13449 13941 /*xcpt? */ false, false }, 13450 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) } }, 13451 13943 { /*unused */ { FP32_x8_UNUSED } }, 13452 13944 { /* => */ { 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 13947 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_RC_ZERO, 13456 13948 /*xcpt? */ false, false }, 13457 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) } }, 13458 13950 { /*unused */ { FP32_x8_UNUSED } }, 13459 13951 { /* => */ { 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 13954 /*256:out */ X86_MXCSR_XCPT_MASK | X86_MXCSR_DE | X86_MXCSR_IE | X86_MXCSR_PE | X86_MXCSR_FZ, 13463 13955 /*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) } }, 13465 13958 { /*unused */ { FP32_x8_UNUSED } }, 13466 13959 { /* => */ { 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 13967 */ 13475 13968 /** @todo Invalids. */ 13476 /* 29|31*/ /* FP32_TABLE_D10_PS_INVALIDS */13969 /*16|28*/ /* FP32_TABLE_D10_PS_INVALIDS */ 13477 13970 /** @todo Underflow, Precision; Rounding; FZ etc. */ 13478 13971 }; … … 13525 14018 static BS3CPUINSTR4_TEST1_MODE_T const s_aTests[3] = BS3CPUINSTR4_TEST1_MODES_INIT(s_aTests16, s_aTests32, s_aTests64); 13526 14019 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, 13528 14021 g_aXcptConfig2, RT_ELEMENTS(g_aXcptConfig2)); 13529 14022 } … … 13660 14153 { 13661 14154 /* 14155 * Poke the PRNG to print the seed before other output. 14156 */ 14157 (void)bs3CpuInstrX_SimpleRand(); 14158 /* 13662 14159 * Do the tests. 13663 14160 */
Note:
See TracChangeset
for help on using the changeset viewer.