Changeset 94569 in vbox
- Timestamp:
- Apr 12, 2022 9:38:56 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp
r94540 r94569 3529 3529 TYPEDEF_SUBTEST_TYPE(FPU_UNARY_R80_T, FPU_UNARY_R80_TEST_T, PFNIEMAIMPLFPUR80UNARY); 3530 3530 3531 enum { kUnary_Accurate = 0, kUnary_ Rounding_F2xm1 };3531 enum { kUnary_Accurate = 0, kUnary_Accurate_Trigonometry /*probably not accurate, but need impl to know*/, kUnary_Rounding_F2xm1 }; 3532 3532 static const FPU_UNARY_R80_T g_aFpuUnaryR80[] = 3533 3533 { … … 3538 3538 ENTRY_EX( fsqrt_r80, kUnary_Accurate), 3539 3539 ENTRY_EX( frndint_r80, kUnary_Accurate), 3540 ENTRY_AMD_EX( fsin_r80, 0, kUnary_Accurate ), // value & C1 differences for pseudo denormals and others (e.g. -1m0x2b1e5683cbca5725^-3485)3541 ENTRY_INTEL_EX(fsin_r80, 0, kUnary_Accurate ),3542 ENTRY_AMD_EX( fcos_r80, 0, kUnary_Accurate ), // value & C1 differences3543 ENTRY_INTEL_EX(fcos_r80, 0, kUnary_Accurate ),3540 ENTRY_AMD_EX( fsin_r80, 0, kUnary_Accurate_Trigonometry), // value & C1 differences for pseudo denormals and others (e.g. -1m0x2b1e5683cbca5725^-3485) 3541 ENTRY_INTEL_EX(fsin_r80, 0, kUnary_Accurate_Trigonometry), 3542 ENTRY_AMD_EX( fcos_r80, 0, kUnary_Accurate_Trigonometry), // value & C1 differences 3543 ENTRY_INTEL_EX(fcos_r80, 0, kUnary_Accurate_Trigonometry), 3544 3544 }; 3545 3545 … … 3560 3560 static RTFLOAT80U const s_aSpecials[] = 3561 3561 { 3562 #if 13563 3562 RTFLOAT80U_INIT_C(0, 0x8000000000000000, RTFLOAT80U_EXP_BIAS - 1), /* 0.5 (for f2xm1) */ 3564 3563 RTFLOAT80U_INIT_C(1, 0x8000000000000000, RTFLOAT80U_EXP_BIAS - 1), /* -0.5 (for f2xm1) */ 3565 3564 RTFLOAT80U_INIT_C(0, 0x8000000000000000, RTFLOAT80U_EXP_BIAS), /* 1.0 (for f2xm1) */ 3566 3565 RTFLOAT80U_INIT_C(1, 0x8000000000000000, RTFLOAT80U_EXP_BIAS), /* -1.0 (for f2xm1) */ 3567 #endif3568 3566 RTFLOAT80U_INIT_C(0, 0x8000000000000000, 0), /* +1.0^-16382 */ 3569 3567 RTFLOAT80U_INIT_C(1, 0x8000000000000000, 0), /* -1.0^-16382 */ 3570 #if 13571 3568 RTFLOAT80U_INIT_C(0, 0xc000000000000000, 0), /* +1.1^-16382 */ 3572 3569 RTFLOAT80U_INIT_C(1, 0xc000000000000000, 0), /* -1.1^-16382 */ 3573 3570 RTFLOAT80U_INIT_C(0, 0xc000100000000000, 0), /* +1.1xxx1^-16382 */ 3574 3571 RTFLOAT80U_INIT_C(1, 0xc000100000000000, 0), /* -1.1xxx1^-16382 */ 3575 #endif3576 3572 }; 3577 3573 X86FXSTATE State; … … 3590 3586 3591 3587 GenerateArrayStart(pOutFn, g_aFpuUnaryR80[iFn].pszName, "FPU_UNARY_R80_TEST_T"); 3592 uint32_t cNormalInputs = 0; 3588 uint32_t iTestOutput = 0; 3589 uint32_t cNormalInputs = 0; 3593 3590 uint32_t cTargetRangeInputs = 0; 3594 3591 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) … … 3599 3596 if (g_aFpuUnaryR80[iFn].uExtra == kUnary_Rounding_F2xm1) 3600 3597 { 3601 unsigned uTargetExp = RTFLOAT80U_EXP_BIAS; 3602 unsigned cTargetExp = 69; 3598 unsigned uTargetExp = g_aFpuUnaryR80[iFn].uExtra == kUnary_Rounding_F2xm1 3599 ? RTFLOAT80U_EXP_BIAS /* 2^0..2^-69 */ : RTFLOAT80U_EXP_BIAS + 63 + 1 /* 2^64..2^-64 */; 3600 unsigned cTargetExp = g_aFpuUnaryR80[iFn].uExtra == kUnary_Rounding_F2xm1 ? 69 : 63*2 + 2; 3603 3601 if (InVal.s.uExponent <= uTargetExp && InVal.s.uExponent >= uTargetExp - cTargetExp) 3604 3602 cTargetRangeInputs++; … … 3622 3620 3623 3621 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 3624 {3625 3622 for (uint16_t iPrecision = 0; iPrecision < 4; iPrecision++) 3626 3623 { … … 3631 3628 IEMFPURESULT ResM = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3632 3629 pfn(&State, &ResM, &InVal); 3633 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/m */\n",3630 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/m = #%u */\n", 3634 3631 State.FCW | fFcwExtra, State.FSW, ResM.FSW, GenFormatR80(&InVal), 3635 GenFormatR80(&ResM.r80Result), iTest, iRounding, iPrecision );3632 GenFormatR80(&ResM.r80Result), iTest, iRounding, iPrecision, iTestOutput++); 3636 3633 3637 3634 State.FCW = State.FCW & ~X86_FCW_MASK_ALL; 3638 3635 IEMFPURESULT ResU = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3639 3636 pfn(&State, &ResU, &InVal); 3640 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/u */\n",3637 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/u = #%u */\n", 3641 3638 State.FCW | fFcwExtra, State.FSW, ResU.FSW, GenFormatR80(&InVal), 3642 GenFormatR80(&ResU.r80Result), iTest, iRounding, iPrecision );3639 GenFormatR80(&ResU.r80Result), iTest, iRounding, iPrecision, iTestOutput++); 3643 3640 3644 3641 uint16_t fXcpt = (ResM.FSW | ResU.FSW) & X86_FSW_XCPT_MASK & ~X86_FSW_SF; … … 3648 3645 IEMFPURESULT Res1 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3649 3646 pfn(&State, &Res1, &InVal); 3650 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/%#x */\n",3647 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/%#x = #%u */\n", 3651 3648 State.FCW | fFcwExtra, State.FSW, Res1.FSW, GenFormatR80(&InVal), 3652 GenFormatR80(&Res1.r80Result), iTest, iRounding, iPrecision, fXcpt );3649 GenFormatR80(&Res1.r80Result), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 3653 3650 if (((Res1.FSW & X86_FSW_XCPT_MASK) & fXcpt) != (Res1.FSW & X86_FSW_XCPT_MASK)) 3654 3651 { … … 3657 3654 IEMFPURESULT Res2 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3658 3655 pfn(&State, &Res2, &InVal); 3659 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/%#x[!] */\n",3656 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/%#x[!] = #%u */\n", 3660 3657 State.FCW | fFcwExtra, State.FSW, Res2.FSW, GenFormatR80(&InVal), 3661 GenFormatR80(&Res2.r80Result), iTest, iRounding, iPrecision, fXcpt );3658 GenFormatR80(&Res2.r80Result), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 3662 3659 } 3663 3660 if (!RT_IS_POWER_OF_TWO(fXcpt)) … … 3668 3665 IEMFPURESULT Res3 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3669 3666 pfn(&State, &Res3, &InVal); 3670 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/u%#x */\n",3667 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s }, /* #%u/%u/%u/u%#x = #%u */\n", 3671 3668 State.FCW | fFcwExtra, State.FSW, Res3.FSW, GenFormatR80(&InVal), 3672 GenFormatR80(&Res3.r80Result), iTest, iRounding, iPrecision, fUnmasked );3669 GenFormatR80(&Res3.r80Result), iTest, iRounding, iPrecision, fUnmasked, iTestOutput++); 3673 3670 } 3674 3671 } 3675 3672 } 3676 }3677 3673 } 3678 3674 GenerateArrayEnd(pOutFn, g_aFpuUnaryR80[iFn].pszName); … … 3906 3902 static const FPU_UNARY_TWO_R80_T g_aFpuUnaryTwoR80[] = 3907 3903 { 3904 ENTRY(fxtract_r80_r80), 3908 3905 ENTRY_AMD( fptan_r80_r80, 0), // rounding differences 3909 3906 ENTRY_INTEL(fptan_r80_r80, 0), 3910 ENTRY(fxtract_r80_r80),3911 3907 ENTRY_AMD( fsincos_r80_r80, 0), // C1 differences & value differences (e.g. -1m0x235cf2f580244a27^-1696) 3912 3908 ENTRY_INTEL(fsincos_r80_r80, 0), … … 3936 3932 3937 3933 GenerateArrayStart(pOutFn, g_aFpuUnaryTwoR80[iFn].pszName, "FPU_UNARY_TWO_R80_TEST_T"); 3938 uint32_t cNormalInputs = 0; 3934 uint32_t iTestOutput = 0; 3935 uint32_t cNormalInputs = 0; 3936 uint32_t cTargetRangeInputs = 0; 3939 3937 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 3940 3938 { 3941 RTFLOAT80U constInVal = iTest < cTests ? RandR80Ex() : s_aSpecials[iTest - cTests];3939 RTFLOAT80U InVal = iTest < cTests ? RandR80Ex() : s_aSpecials[iTest - cTests]; 3942 3940 if (RTFLOAT80U_IS_NORMAL(&InVal)) 3941 { 3942 if (iFn != 0) 3943 { 3944 unsigned uTargetExp = RTFLOAT80U_EXP_BIAS + 63 + 1 /* 2^64..2^-64 */; 3945 unsigned cTargetExp = g_aFpuUnaryR80[iFn].uExtra == kUnary_Rounding_F2xm1 ? 69 : 63*2 + 2; 3946 if (InVal.s.uExponent <= uTargetExp && InVal.s.uExponent >= uTargetExp - cTargetExp) 3947 cTargetRangeInputs++; 3948 else if (cTargetRangeInputs < cMinNormals / 2 && iTest + cMinNormals / 2 >= cTests && iTest < cTests) 3949 { 3950 InVal.s.uExponent = RTRandU32Ex(uTargetExp - cTargetExp, uTargetExp); 3951 cTargetRangeInputs++; 3952 } 3953 } 3943 3954 cNormalInputs++; 3955 } 3944 3956 else if (cNormalInputs < cMinNormals && iTest + cMinNormals >= cTests && iTest < cTests) 3945 3957 { … … 3948 3960 } 3949 3961 3962 uint16_t const fFcwExtra = 0; /* for rounding error indication */ 3950 3963 uint16_t const fFcw = RandFcw(); 3951 3964 State.FSW = RandFsw(); 3952 3965 3953 3966 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 3954 {3955 3967 for (uint16_t iPrecision = 0; iPrecision < 4; iPrecision++) 3956 3968 { 3957 for (uint16_t iMask = 0; iMask <= X86_FCW_MASK_ALL; iMask += X86_FCW_MASK_ALL) 3969 State.FCW = (fFcw & ~(X86_FCW_RC_MASK | X86_FCW_PC_MASK | X86_FCW_MASK_ALL)) 3970 | (iRounding << X86_FCW_RC_SHIFT) 3971 | (iPrecision << X86_FCW_PC_SHIFT) 3972 | X86_FCW_MASK_ALL; 3973 IEMFPURESULTTWO ResM = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 3974 pfn(&State, &ResM, &InVal); 3975 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/m = #%u */\n", 3976 State.FCW | fFcwExtra, State.FSW, ResM.FSW, GenFormatR80(&InVal), GenFormatR80(&ResM.r80Result1), 3977 GenFormatR80(&ResM.r80Result2), iTest, iRounding, iPrecision, iTestOutput++); 3978 3979 State.FCW = State.FCW & ~X86_FCW_MASK_ALL; 3980 IEMFPURESULTTWO ResU = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 3981 pfn(&State, &ResU, &InVal); 3982 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/u = #%u */\n", 3983 State.FCW | fFcwExtra, State.FSW, ResU.FSW, GenFormatR80(&InVal), GenFormatR80(&ResU.r80Result1), 3984 GenFormatR80(&ResU.r80Result2), iTest, iRounding, iPrecision, iTestOutput++); 3985 3986 uint16_t fXcpt = (ResM.FSW | ResU.FSW) & X86_FSW_XCPT_MASK & ~X86_FSW_SF; 3987 if (fXcpt) 3958 3988 { 3959 IEMFPURESULTTWO Res = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 3960 State.FCW = (fFcw & ~(X86_FCW_RC_MASK | X86_FCW_PC_MASK | X86_FCW_MASK_ALL)) 3961 | (iRounding << X86_FCW_RC_SHIFT) 3962 | (iPrecision << X86_FCW_PC_SHIFT) 3963 | iMask; 3964 pfn(&State, &Res, &InVal); 3965 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%c */\n", 3966 State.FCW, State.FSW, Res.FSW, GenFormatR80(&InVal), 3967 GenFormatR80(&Res.r80Result1), GenFormatR80(&Res.r80Result2), 3968 iTest, iRounding, iPrecision, iMask ? 'c' : 'u'); 3989 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | fXcpt; 3990 IEMFPURESULTTWO Res1 = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 3991 pfn(&State, &Res1, &InVal); 3992 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%#x = #%u */\n", 3993 State.FCW | fFcwExtra, State.FSW, Res1.FSW, GenFormatR80(&InVal), GenFormatR80(&Res1.r80Result1), 3994 GenFormatR80(&Res1.r80Result2), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 3995 if (((Res1.FSW & X86_FSW_XCPT_MASK) & fXcpt) != (Res1.FSW & X86_FSW_XCPT_MASK)) 3996 { 3997 fXcpt |= Res1.FSW & X86_FSW_XCPT_MASK; 3998 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | fXcpt; 3999 IEMFPURESULTTWO Res2 = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 4000 pfn(&State, &Res2, &InVal); 4001 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%#x[!] = #%u */\n", 4002 State.FCW | fFcwExtra, State.FSW, Res2.FSW, GenFormatR80(&InVal), GenFormatR80(&Res2.r80Result1), 4003 GenFormatR80(&Res2.r80Result2), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 4004 } 4005 if (!RT_IS_POWER_OF_TWO(fXcpt)) 4006 for (uint16_t fUnmasked = 1; fUnmasked <= X86_FCW_PM; fUnmasked <<= 1) 4007 if (fUnmasked & fXcpt) 4008 { 4009 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | (fXcpt & ~fUnmasked); 4010 IEMFPURESULTTWO Res3 = { RTFLOAT80U_INIT(0, 0, 0), 0, RTFLOAT80U_INIT(0, 0, 0) }; 4011 pfn(&State, &Res3, &InVal); 4012 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/u%#x = #%u */\n", 4013 State.FCW | fFcwExtra, State.FSW, Res3.FSW, GenFormatR80(&InVal), GenFormatR80(&Res3.r80Result1), 4014 GenFormatR80(&Res3.r80Result2), iTest, iRounding, iPrecision, fUnmasked, iTestOutput++); 4015 } 3969 4016 } 3970 4017 } 3971 }3972 4018 } 3973 4019 GenerateArrayEnd(pOutFn, g_aFpuUnaryTwoR80[iFn].pszName);
Note:
See TracChangeset
for help on using the changeset viewer.