Changeset 94606 in vbox
- Timestamp:
- Apr 14, 2022 1:48:52 PM (2 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
-
VBox/VMM/testcase/tstIEMAImpl.cpp (modified) (39 diffs)
-
libs/softfloat-3e/source/include/softfloat_types.h (modified) (1 diff)
-
libs/softfloat-3e/source/s_roundPackToExtF80.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp
r94571 r94606 218 218 219 219 220 static int16_t RandI16Src(uint32_t iTest) 221 { 222 RT_NOREF(iTest); 220 /** 2nd operand for and FPU instruction, pairing with RandR80Src1. */ 221 static int16_t RandI16Src2(uint32_t iTest) 222 { 223 if (iTest < 18 * 4) 224 switch (iTest % 4) 225 { 226 case 0: return 0; 227 case 1: return INT16_MAX; 228 case 2: return INT16_MIN; 229 case 3: break; 230 } 223 231 return (int16_t)RandU16(); 224 232 } 225 233 226 234 227 static int32_t RandI32Src(uint32_t iTest) 228 { 229 RT_NOREF(iTest); 235 /** 2nd operand for and FPU instruction, pairing with RandR80Src1. */ 236 static int32_t RandI32Src2(uint32_t iTest) 237 { 238 if (iTest < 18 * 4) 239 switch (iTest % 4) 240 { 241 case 0: return 0; 242 case 1: return INT32_MAX; 243 case 2: return INT32_MIN; 244 case 3: break; 245 } 230 246 return (int32_t)RandU32(); 231 247 } … … 263 279 264 280 265 static RTFLOAT80U RandR80Ex(unsigned cTarget = 80, bool fIntTarget = false) 281 282 static RTFLOAT80U RandR80Ex(uint8_t bType, unsigned cTarget = 80, bool fIntTarget = false) 266 283 { 267 284 Assert(cTarget == (!fIntTarget ? 80U : 16U) || cTarget == 64U || cTarget == 32U || (cTarget == 59U && fIntTarget)); … … 272 289 273 290 /* 274 * Make it more likely that we get a good selection of special values.291 * Adjust the random stuff according to bType. 275 292 */ 276 uint8_t bType = RandU8() &0x1f;293 bType &= 0x1f; 277 294 if (bType == 0 || bType == 1 || bType == 2 || bType == 3) 278 295 { … … 283 300 AssertMsg(bType != 0 || RTFLOAT80U_IS_ZERO(&r80), ("%s\n", FormatR80(&r80))); 284 301 AssertMsg(bType != 1 || RTFLOAT80U_IS_PSEUDO_INF(&r80), ("%s\n", FormatR80(&r80))); 302 Assert( bType != 1 || RTFLOAT80U_IS_387_INVALID(&r80)); 285 303 AssertMsg(bType != 2 || RTFLOAT80U_IS_INF(&r80), ("%s\n", FormatR80(&r80))); 286 304 AssertMsg(bType != 3 || RTFLOAT80U_IS_INDEFINITE(&r80), ("%s\n", FormatR80(&r80))); … … 313 331 AssertMsg(RTFLOAT80U_IS_PSEUDO_NAN(&r80), ("%s bType=%#x\n", FormatR80(&r80), bType)); 314 332 AssertMsg(RTFLOAT80U_IS_NAN(&r80), ("%s bType=%#x\n", FormatR80(&r80), bType)); 315 } 316 else if (bType == 10 || bType == 11) 317 { 318 /* Quiet and signalling NaNs (using fInteger to pick which). */ 333 Assert(RTFLOAT80U_IS_387_INVALID(&r80)); 334 } 335 else if (bType == 10 || bType == 11 || bType == 12 || bType == 13) 336 { 337 /* Quiet and signalling NaNs. */ 319 338 if (bType & 1) 320 339 SafeR80FractionShift(&r80, r80.sj64.uExponent % 62); … … 322 341 r80.sj64.uFraction = RTRandU64Ex(1, RT_BIT_64(RTFLOAT80U_FRACTION_BITS) - 1); 323 342 r80.sj64.uExponent = 0x7fff; 324 if ( r80.sj64.fInteger)325 r80.sj64.uFraction |= RT_BIT_64(62); 343 if (bType < 12) 344 r80.sj64.uFraction |= RT_BIT_64(62); /* quiet */ 326 345 else 327 r80.sj64.uFraction &= ~RT_BIT_64(62); 346 r80.sj64.uFraction &= ~RT_BIT_64(62); /* signaling */ 328 347 r80.sj64.fInteger = 1; 348 AssertMsg(bType >= 12 || RTFLOAT80U_IS_QUIET_NAN(&r80), ("%s\n", FormatR80(&r80))); 349 AssertMsg(bType < 12 || RTFLOAT80U_IS_SIGNALLING_NAN(&r80), ("%s\n", FormatR80(&r80))); 329 350 AssertMsg(RTFLOAT80U_IS_SIGNALLING_NAN(&r80) || RTFLOAT80U_IS_QUIET_NAN(&r80), ("%s\n", FormatR80(&r80))); 330 351 AssertMsg(RTFLOAT80U_IS_QUIET_OR_SIGNALLING_NAN(&r80), ("%s\n", FormatR80(&r80))); 331 352 AssertMsg(RTFLOAT80U_IS_NAN(&r80), ("%s\n", FormatR80(&r80))); 332 353 } 333 else if (bType == 1 2 || bType == 13)354 else if (bType == 14 || bType == 15) 334 355 { 335 356 /* Unnormals */ … … 340 361 r80.sj64.uExponent = (uint16_t)RTRandU32Ex(1, RTFLOAT80U_EXP_MAX - 1); 341 362 AssertMsg(RTFLOAT80U_IS_UNNORMAL(&r80), ("%s\n", FormatR80(&r80))); 342 } 343 else if (bType < 24) 363 Assert(RTFLOAT80U_IS_387_INVALID(&r80)); 364 } 365 else if (bType < 26) 344 366 { 345 367 /* Make sure we have lots of normalized values. */ … … 356 378 r80.sj64.uExponent = uMaxExp - 1; 357 379 358 if (bType == 1 4)380 if (bType == 16) 359 381 { /* All 1s is useful to testing rounding. Also try trigger special 360 382 behaviour by sometimes rounding out of range, while we're at it. */ … … 380 402 r80.sj64.uExponent = uMaxExp; 381 403 382 if (bType == 1 4)404 if (bType == 16) 383 405 { /* All 1s is useful to testing rounding. Also try trigger special 384 406 behaviour by sometimes rounding out of range, while we're at it. */ … … 398 420 399 421 400 static RTFLOAT80U RandR80Src(uint32_t iTest) 401 { 402 RT_NOREF(iTest); 403 return RandR80Ex(); 422 static RTFLOAT80U RandR80(unsigned cTarget = 80, bool fIntTarget = false) 423 { 424 /* 425 * Make it more likely that we get a good selection of special values. 426 */ 427 return RandR80Ex(RandU8(), cTarget, fIntTarget); 428 429 } 430 431 432 static RTFLOAT80U RandR80Src(uint32_t iTest, unsigned cTarget = 80, bool fIntTarget = false) 433 { 434 /* Make sure we cover all the basic types first before going for random selection: */ 435 if (iTest <= 18) 436 return RandR80Ex(18 - iTest, cTarget, fIntTarget); /* Starting with 3 normals. */ 437 return RandR80(cTarget, fIntTarget); 438 } 439 440 441 /** 442 * Helper for RandR80Src1 and RandR80Src2 that converts bType from a 0..11 range 443 * to a 0..17, covering all basic value types. 444 */ 445 static uint8_t RandR80Src12RemapType(uint8_t bType) 446 { 447 switch (bType) 448 { 449 case 0: return 18; /* normal */ 450 case 1: return 16; /* normal extreme rounding */ 451 case 2: return 14; /* unnormal */ 452 case 3: return 12; /* Signalling NaN */ 453 case 4: return 10; /* Quiet NaN */ 454 case 5: return 8; /* PseudoNaN */ 455 case 6: return 6; /* Pseudo Denormal */ 456 case 7: return 4; /* Denormal */ 457 case 8: return 3; /* Indefinite */ 458 case 9: return 2; /* Infinity */ 459 case 10: return 1; /* Pseudo-Infinity */ 460 case 11: return 0; /* Zero */ 461 default: AssertFailedReturn(18); 462 } 463 } 464 465 466 /** 467 * This works in tandem with RandR80Src2 to make sure we cover all operand 468 * type mixes first before we venture into regular random testing. 469 * 470 * There are 11 basic variations, when we leave out the five odd ones using 471 * SafeR80FractionShift. Because of the special normalized value targetting at 472 * rounding, we make it an even 12. So 144 combinations for two operands. 473 */ 474 static RTFLOAT80U RandR80Src1(uint32_t iTest, unsigned cPartnerBits = 80, bool fPartnerInt = false) 475 { 476 if (cPartnerBits == 80) 477 { 478 Assert(!fPartnerInt); 479 if (iTest < 12 * 12) 480 return RandR80Ex(RandR80Src12RemapType(iTest / 12)); 481 } 482 else if ((cPartnerBits == 64 || cPartnerBits == 32) && !fPartnerInt) 483 { 484 if (iTest < 12 * 10) 485 return RandR80Ex(RandR80Src12RemapType(iTest / 10)); 486 } 487 else if (iTest < 18 * 4 && fPartnerInt) 488 return RandR80Ex(iTest / 4); 489 return RandR80(); 490 } 491 492 493 /** Partner to RandR80Src1. */ 494 static RTFLOAT80U RandR80Src2(uint32_t iTest) 495 { 496 if (iTest < 12 * 12) 497 return RandR80Ex(RandR80Src12RemapType(iTest % 12)); 498 return RandR80(); 404 499 } 405 500 … … 414 509 415 510 416 static RTFLOAT64U RandR64Src(uint32_t iTest) 417 { 418 RT_NOREF(iTest); 419 511 static RTFLOAT64U RandR64Ex(uint8_t bType) 512 { 420 513 RTFLOAT64U r64; 421 514 r64.u = RandU64(); … … 425 518 * On average 6 out of 16 calls should return a special value. 426 519 */ 427 uint8_t bType = RandU8() &0xf;520 bType &= 0xf; 428 521 if (bType == 0 || bType == 1) 429 522 { … … 445 538 AssertMsg(RTFLOAT64U_IS_SUBNORMAL(&r64), ("%s bType=%#x\n", FormatR64(&r64), bType)); 446 539 } 447 else if (bType == 4 || bType == 5 )540 else if (bType == 4 || bType == 5 || bType == 6 || bType == 7) 448 541 { 449 542 /* NaNs */ 450 if (bType == 5)543 if (bType & 1) 451 544 SafeR64FractionShift(&r64, r64.s64.uExponent % 51); 452 545 else if (r64.s64.uFraction == 0) 453 546 r64.s64.uFraction = RTRandU64Ex(1, RT_BIT_64(RTFLOAT64U_FRACTION_BITS) - 1); 454 547 r64.s64.uExponent = 0x7ff; 548 if (bType < 6) 549 r64.s64.uFraction |= RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1); /* quiet */ 550 else 551 r64.s64.uFraction &= ~RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1); /* signalling */ 552 AssertMsg(bType >= 6 || RTFLOAT64U_IS_QUIET_NAN(&r64), ("%s bType=%#x\n", FormatR64(&r64), bType)); 553 AssertMsg(bType < 6 || RTFLOAT64U_IS_SIGNALLING_NAN(&r64), ("%s bType=%#x\n", FormatR64(&r64), bType)); 455 554 AssertMsg(RTFLOAT64U_IS_NAN(&r64), ("%s bType=%#x\n", FormatR64(&r64), bType)); 456 555 } … … 468 567 469 568 569 static RTFLOAT64U RandR64Src(uint32_t iTest) 570 { 571 if (iTest < 16) 572 return RandR64Ex(iTest); 573 return RandR64Ex(RandU8()); 574 } 575 576 577 /** Pairing with a 80-bit floating point arg. */ 578 static RTFLOAT64U RandR64Src2(uint32_t iTest) 579 { 580 if (iTest < 12 * 10) 581 return RandR64Ex(9 - iTest % 10); /* start with normal values */ 582 return RandR64Ex(RandU8()); 583 } 584 585 470 586 static void SafeR32FractionShift(PRTFLOAT32U pr32, uint8_t cShift) 471 587 { … … 477 593 478 594 479 static RTFLOAT32U RandR32Src(uint32_t iTest) 480 { 481 RT_NOREF(iTest); 482 595 static RTFLOAT32U RandR32Ex(uint8_t bType) 596 { 483 597 RTFLOAT32U r32; 484 598 r32.u = RandU32(); … … 488 602 * On average 6 out of 16 calls should return a special value. 489 603 */ 490 uint8_t bType = RandU8() &0xf;604 bType &= 0xf; 491 605 if (bType == 0 || bType == 1) 492 606 { … … 507 621 AssertMsg(RTFLOAT32U_IS_SUBNORMAL(&r32), ("%s bType=%#x\n", FormatR32(&r32), bType)); 508 622 } 509 else if (bType == 4 || bType == 5 )623 else if (bType == 4 || bType == 5 || bType == 6 || bType == 7) 510 624 { 511 625 /* NaNs */ 512 if (bType == 5)626 if (bType & 1) 513 627 SafeR32FractionShift(&r32, r32.s.uExponent % 22); 514 628 else if (r32.s.uFraction == 0) 515 629 r32.s.uFraction = RTRandU32Ex(1, RT_BIT_32(RTFLOAT32U_FRACTION_BITS) - 1); 516 630 r32.s.uExponent = 0xff; 631 if (bType < 6) 632 r32.s.uFraction |= RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); /* quiet */ 633 else 634 r32.s.uFraction &= ~RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); /* signalling */ 635 AssertMsg(bType >= 6 || RTFLOAT32U_IS_QUIET_NAN(&r32), ("%s bType=%#x\n", FormatR32(&r32), bType)); 636 AssertMsg(bType < 6 || RTFLOAT32U_IS_SIGNALLING_NAN(&r32), ("%s bType=%#x\n", FormatR32(&r32), bType)); 517 637 AssertMsg(RTFLOAT32U_IS_NAN(&r32), ("%s bType=%#x\n", FormatR32(&r32), bType)); 518 638 } … … 527 647 } 528 648 return r32; 649 } 650 651 652 static RTFLOAT32U RandR32Src(uint32_t iTest) 653 { 654 if (iTest < 16) 655 return RandR32Ex(iTest); 656 return RandR32Ex(RandU8()); 657 } 658 659 660 /** Pairing with a 80-bit floating point arg. */ 661 static RTFLOAT32U RandR32Src2(uint32_t iTest) 662 { 663 if (iTest < 12 * 10) 664 return RandR32Ex(9 - iTest % 10); /* start with normal values */ 665 return RandR32Ex(RandU8()); 529 666 } 530 667 … … 2562 2699 uint16_t const fFcw = RandFcw(); \ 2563 2700 State.FSW = RandFsw(); \ 2564 RTFLOAT80U const InVal = iTest < cTests ? RandR80Src(iTest) : g_aFpuStR ## a_cBits ## Specials[iTest - cTests]; \ 2701 RTFLOAT80U const InVal = iTest < cTests ? RandR80Src(iTest, a_cBits) \ 2702 : g_aFpuStR ## a_cBits ## Specials[iTest - cTests]; \ 2565 2703 \ 2566 2704 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) \ … … 2806 2944 uint16_t const fFcw = RandFcw(); \ 2807 2945 State.FSW = RandFsw(); \ 2808 RTFLOAT80U const InVal = iTest < cTests ? RandR80 Ex(a_cBits, true) \2946 RTFLOAT80U const InVal = iTest < cTests ? RandR80Src(iTest, a_cBits, true) \ 2809 2947 : g_aFpuStI ## a_cBits ## Specials[iTest - cTests]; \ 2810 2948 \ … … 2941 3079 uint16_t const fFcw = RandFcw(); 2942 3080 State.FSW = RandFsw(); 2943 RTFLOAT80U const InVal = iTest < cTests ? RandR80 Ex(59, true) : s_aSpecials[iTest - cTests];3081 RTFLOAT80U const InVal = iTest < cTests ? RandR80Src(iTest, 59, true) : s_aSpecials[iTest - cTests]; 2944 3082 2945 3083 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) … … 3043 3181 static void FpuBinaryR80Generate(PRTSTREAM pOut, PRTSTREAM pOutCpu, uint32_t cTests) 3044 3182 { 3183 cTests = RT_MAX(160, cTests); /* there are 144 standard input variations */ 3184 3045 3185 static struct { RTFLOAT80U Val1, Val2; } const s_aSpecials[] = 3046 3186 { 3047 { RTFLOAT80U_INIT_C(0, 0xffffeeeeddddcccc, RTFLOAT80U_EXP_BIAS), 3048 RTFLOAT80U_INIT_C(0, 0xffffeeeeddddcccc, RTFLOAT80U_EXP_BIAS) }, /* whatever */ 3187 { RTFLOAT80U_INIT_C(1, 0xdd762f07f2e80eef, 30142), /* causes weird overflows with DOWN and NEAR rounding. */ 3188 RTFLOAT80U_INIT_C(1, 0xffffffffffffffff, RTFLOAT80U_EXP_MAX - 1) }, 3189 { RTFLOAT80U_INIT_ZERO(0), /* causes weird overflows with UP and NEAR rounding when precision is lower than 64. */ 3190 RTFLOAT80U_INIT_C(0, 0xffffffffffffffff, RTFLOAT80U_EXP_MAX - 1) }, 3191 { RTFLOAT80U_INIT_ZERO(0), /* minus variant */ 3192 RTFLOAT80U_INIT_C(1, 0xffffffffffffffff, RTFLOAT80U_EXP_MAX - 1) }, 3049 3193 }; 3050 3194 3051 3195 X86FXSTATE State; 3052 3196 RT_ZERO(State); 3053 uint32_t cMinNormalPairs = cTests/ 4;3197 uint32_t cMinNormalPairs = (cTests - 144) / 4; 3054 3198 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aFpuBinaryR80); iFn++) 3055 3199 { … … 3064 3208 3065 3209 GenerateArrayStart(pOutFn, g_aFpuBinaryR80[iFn].pszName, "FPU_BINARY_R80_TEST_T"); 3210 uint32_t iTestOutput = 0; 3066 3211 uint32_t cNormalInputPairs = 0; 3067 3212 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 3068 3213 { 3069 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80 Ex() : s_aSpecials[iTest - cTests].Val1;3070 RTFLOAT80U const InVal2 = iTest < cTests ? RandR80 Ex() : s_aSpecials[iTest - cTests].Val2;3214 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80Src1(iTest) : s_aSpecials[iTest - cTests].Val1; 3215 RTFLOAT80U const InVal2 = iTest < cTests ? RandR80Src2(iTest) : s_aSpecials[iTest - cTests].Val2; 3071 3216 if (RTFLOAT80U_IS_NORMAL(&InVal1) && RTFLOAT80U_IS_NORMAL(&InVal2)) 3072 3217 cNormalInputPairs++; … … 3077 3222 } 3078 3223 3224 uint16_t const fFcwExtra = 0; 3079 3225 uint16_t const fFcw = RandFcw(); 3080 3226 State.FSW = RandFsw(); 3081 3227 3082 3228 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 3083 {3084 3229 for (uint16_t iPrecision = 0; iPrecision < 4; iPrecision++) 3085 3230 { 3086 for (uint16_t iMask = 0; iMask <= X86_FCW_MASK_ALL; iMask += X86_FCW_MASK_ALL) 3231 State.FCW = (fFcw & ~(X86_FCW_RC_MASK | X86_FCW_PC_MASK | X86_FCW_MASK_ALL)) 3232 | (iRounding << X86_FCW_RC_SHIFT) 3233 | (iPrecision << X86_FCW_PC_SHIFT) 3234 | X86_FCW_MASK_ALL; 3235 IEMFPURESULT ResM = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3236 pfn(&State, &ResM, &InVal1, &InVal2); 3237 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/m = #%u */\n", 3238 State.FCW | fFcwExtra, State.FSW, ResM.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3239 GenFormatR80(&ResM.r80Result), iTest, iRounding, iPrecision, iTestOutput++); 3240 3241 State.FCW = State.FCW & ~X86_FCW_MASK_ALL; 3242 IEMFPURESULT ResU = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3243 pfn(&State, &ResU, &InVal1, &InVal2); 3244 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/u = #%u */\n", 3245 State.FCW | fFcwExtra, State.FSW, ResU.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3246 GenFormatR80(&ResU.r80Result), iTest, iRounding, iPrecision, iTestOutput++); 3247 3248 uint16_t fXcpt = (ResM.FSW | ResU.FSW) & X86_FSW_XCPT_MASK & ~X86_FSW_SF; 3249 if (fXcpt) 3087 3250 { 3088 State.FCW = (fFcw & ~(X86_FCW_RC_MASK | X86_FCW_PC_MASK | X86_FCW_MASK_ALL)) 3089 | (iRounding << X86_FCW_RC_SHIFT) 3090 | (iPrecision << X86_FCW_PC_SHIFT) 3091 | iMask; 3092 IEMFPURESULT Res = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3093 pfn(&State, &Res, &InVal1, &InVal2); 3094 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%c */\n", 3095 State.FCW, State.FSW, Res.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3096 GenFormatR80(&Res.r80Result), iTest, iRounding, iPrecision, iMask ? 'c' : 'u'); 3251 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | fXcpt; 3252 IEMFPURESULT Res1 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3253 pfn(&State, &Res1, &InVal1, &InVal2); 3254 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%#x = #%u */\n", 3255 State.FCW | fFcwExtra, State.FSW, Res1.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3256 GenFormatR80(&Res1.r80Result), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 3257 if (((Res1.FSW & X86_FSW_XCPT_MASK) & fXcpt) != (Res1.FSW & X86_FSW_XCPT_MASK)) 3258 { 3259 fXcpt |= Res1.FSW & X86_FSW_XCPT_MASK; 3260 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | fXcpt; 3261 IEMFPURESULT Res2 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3262 pfn(&State, &Res2, &InVal1, &InVal2); 3263 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/%#x[!] = #%u */\n", 3264 State.FCW | fFcwExtra, State.FSW, Res2.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3265 GenFormatR80(&Res2.r80Result), iTest, iRounding, iPrecision, fXcpt, iTestOutput++); 3266 } 3267 if (!RT_IS_POWER_OF_TWO(fXcpt)) 3268 for (uint16_t fUnmasked = 1; fUnmasked <= X86_FCW_PM; fUnmasked <<= 1) 3269 if (fUnmasked & fXcpt) 3270 { 3271 State.FCW = (State.FCW & ~X86_FCW_MASK_ALL) | (fXcpt & ~fUnmasked); 3272 IEMFPURESULT Res3 = { RTFLOAT80U_INIT(0, 0, 0), 0 }; 3273 pfn(&State, &Res3, &InVal1, &InVal2); 3274 RTStrmPrintf(pOutFn, " { %#06x, %#06x, %#06x, %s, %s, %s }, /* #%u/%u/%u/u%#x = #%u */\n", 3275 State.FCW | fFcwExtra, State.FSW, Res3.FSW, GenFormatR80(&InVal1), GenFormatR80(&InVal2), 3276 GenFormatR80(&Res3.r80Result), iTest, iRounding, iPrecision, fUnmasked, iTestOutput++); 3277 } 3097 3278 } 3098 3279 } 3099 }3100 3280 } 3101 3281 GenerateArrayEnd(pOutFn, g_aFpuBinaryR80[iFn].pszName); … … 3175 3355 }; 3176 3356 3177 # define GEN_FPU_BINARY_SMALL(a_ cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \3357 # define GEN_FPU_BINARY_SMALL(a_fIntType, a_cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \ 3178 3358 static void FpuBinary ## a_UpBits ## Generate(PRTSTREAM pOut, uint32_t cTests) \ 3179 3359 { \ 3360 cTests = RT_MAX(160, cTests); /* there are 144 standard input variations for r80 by r80 */ \ 3361 \ 3180 3362 X86FXSTATE State; \ 3181 3363 RT_ZERO(State); \ 3182 uint32_t cMinNormalPairs = cTests/ 4; \3364 uint32_t cMinNormalPairs = (cTests - 144) / 4; \ 3183 3365 for (size_t iFn = 0; iFn < RT_ELEMENTS(a_aSubTests); iFn++) \ 3184 3366 { \ … … 3187 3369 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aFpuBinary ## a_UpBits ## Specials); iTest += 1) \ 3188 3370 { \ 3189 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80 Ex() \3371 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80Src1(iTest, a_cBits, a_fIntType) \ 3190 3372 : s_aFpuBinary ## a_UpBits ## Specials[iTest - cTests].Val1; \ 3191 a_Type2 const InVal2 = iTest < cTests ? Rand ## a_UpBits ## Src (a_cBits) \3373 a_Type2 const InVal2 = iTest < cTests ? Rand ## a_UpBits ## Src2(iTest) \ 3192 3374 : s_aFpuBinary ## a_UpBits ## Specials[iTest - cTests].Val2; \ 3193 3375 if (RTFLOAT80U_IS_NORMAL(&InVal1) && a_Type2 ## _IS_NORMAL(&InVal2)) \ … … 3225 3407 } 3226 3408 #else 3227 # define GEN_FPU_BINARY_SMALL(a_ cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType)3409 # define GEN_FPU_BINARY_SMALL(a_fIntType, a_cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) 3228 3410 #endif 3229 3411 3230 #define TEST_FPU_BINARY_SMALL(a_ cBits, a_LoBits, a_UpBits, a_I, a_Type2, a_SubTestType, a_aSubTests, a_TestType) \3412 #define TEST_FPU_BINARY_SMALL(a_fIntType, a_cBits, a_LoBits, a_UpBits, a_I, a_Type2, a_SubTestType, a_aSubTests, a_TestType) \ 3231 3413 TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLFPU ## a_UpBits); \ 3232 3414 \ … … 3241 3423 }; \ 3242 3424 \ 3243 GEN_FPU_BINARY_SMALL(a_ cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \3425 GEN_FPU_BINARY_SMALL(a_fIntType, a_cBits, a_LoBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \ 3244 3426 \ 3245 3427 static void FpuBinary ## a_UpBits ## Test(void) \ … … 3284 3466 } 3285 3467 3286 TEST_FPU_BINARY_SMALL( 64, r64, R64, RT_NOTHING, RTFLOAT64U, FPU_BINARY_R64_T, g_aFpuBinaryR64, FPU_BINARY_R64_TEST_T)3287 TEST_FPU_BINARY_SMALL( 32, r32, R32, RT_NOTHING, RTFLOAT32U, FPU_BINARY_R32_T, g_aFpuBinaryR32, FPU_BINARY_R32_TEST_T)3288 TEST_FPU_BINARY_SMALL( 32, i32, I32, i, int32_t, FPU_BINARY_I32_T, g_aFpuBinaryI32, FPU_BINARY_I32_TEST_T)3289 TEST_FPU_BINARY_SMALL(1 6, i16, I16, i, int16_t, FPU_BINARY_I16_T, g_aFpuBinaryI16, FPU_BINARY_I16_TEST_T)3468 TEST_FPU_BINARY_SMALL(0, 64, r64, R64, RT_NOTHING, RTFLOAT64U, FPU_BINARY_R64_T, g_aFpuBinaryR64, FPU_BINARY_R64_TEST_T) 3469 TEST_FPU_BINARY_SMALL(0, 32, r32, R32, RT_NOTHING, RTFLOAT32U, FPU_BINARY_R32_T, g_aFpuBinaryR32, FPU_BINARY_R32_TEST_T) 3470 TEST_FPU_BINARY_SMALL(1, 32, i32, I32, i, int32_t, FPU_BINARY_I32_T, g_aFpuBinaryI32, FPU_BINARY_I32_TEST_T) 3471 TEST_FPU_BINARY_SMALL(1, 16, i16, I16, i, int16_t, FPU_BINARY_I16_T, g_aFpuBinaryI16, FPU_BINARY_I16_TEST_T) 3290 3472 3291 3473 … … 3318 3500 }; 3319 3501 3320 # define GEN_FPU_BINARY_FSW(a_ cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \3502 # define GEN_FPU_BINARY_FSW(a_fIntType, a_cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \ 3321 3503 static void FpuBinaryFsw ## a_UpBits ## Generate(PRTSTREAM pOut, uint32_t cTests) \ 3322 3504 { \ 3505 cTests = RT_MAX(160, cTests); /* there are 144 standard input variations for r80 by r80 */ \ 3506 \ 3323 3507 X86FXSTATE State; \ 3324 3508 RT_ZERO(State); \ 3325 uint32_t cMinNormalPairs = cTests/ 4; \3509 uint32_t cMinNormalPairs = (cTests - 144) / 4; \ 3326 3510 for (size_t iFn = 0; iFn < RT_ELEMENTS(a_aSubTests); iFn++) \ 3327 3511 { \ … … 3330 3514 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aFpuBinaryFsw ## a_UpBits ## Specials); iTest += 1) \ 3331 3515 { \ 3332 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80 Ex() \3516 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80Src1(iTest, a_cBits, a_fIntType) \ 3333 3517 : s_aFpuBinaryFsw ## a_UpBits ## Specials[iTest - cTests].Val1; \ 3334 a_Type2 const InVal2 = iTest < cTests ? Rand ## a_UpBits ## Src (a_cBits) \3518 a_Type2 const InVal2 = iTest < cTests ? Rand ## a_UpBits ## Src2(iTest) \ 3335 3519 : s_aFpuBinaryFsw ## a_UpBits ## Specials[iTest - cTests].Val2; \ 3336 3520 if (RTFLOAT80U_IS_NORMAL(&InVal1) && a_Type2 ## _IS_NORMAL(&InVal2)) \ … … 3360 3544 } 3361 3545 #else 3362 # define GEN_FPU_BINARY_FSW(a_ cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType)3546 # define GEN_FPU_BINARY_FSW(a_fIntType, a_cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) 3363 3547 #endif 3364 3548 3365 #define TEST_FPU_BINARY_FSW(a_ cBits, a_UpBits, a_Type2, a_SubTestType, a_aSubTests, a_TestType, ...) \3549 #define TEST_FPU_BINARY_FSW(a_fIntType, a_cBits, a_UpBits, a_Type2, a_SubTestType, a_aSubTests, a_TestType, ...) \ 3366 3550 TYPEDEF_SUBTEST_TYPE(a_SubTestType, a_TestType, PFNIEMAIMPLFPU ## a_UpBits ## FSW); \ 3367 3551 \ … … 3371 3555 }; \ 3372 3556 \ 3373 GEN_FPU_BINARY_FSW(a_ cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \3557 GEN_FPU_BINARY_FSW(a_fIntType, a_cBits, a_UpBits, a_Type2, a_aSubTests, a_TestType) \ 3374 3558 \ 3375 3559 static void FpuBinaryFsw ## a_UpBits ## Test(void) \ … … 3411 3595 } 3412 3596 3413 TEST_FPU_BINARY_FSW( 80, R80, RTFLOAT80U, FPU_BINARY_FSW_R80_T, g_aFpuBinaryFswR80, FPU_BINARY_R80_TEST_T, ENTRY(fcom_r80_by_r80), ENTRY(fucom_r80_by_r80))3414 TEST_FPU_BINARY_FSW( 64, R64, RTFLOAT64U, FPU_BINARY_FSW_R64_T, g_aFpuBinaryFswR64, FPU_BINARY_R64_TEST_T, ENTRY(fcom_r80_by_r64))3415 TEST_FPU_BINARY_FSW( 32, R32, RTFLOAT32U, FPU_BINARY_FSW_R32_T, g_aFpuBinaryFswR32, FPU_BINARY_R32_TEST_T, ENTRY(fcom_r80_by_r32))3416 TEST_FPU_BINARY_FSW( 32, I32, int32_t, FPU_BINARY_FSW_I32_T, g_aFpuBinaryFswI32, FPU_BINARY_I32_TEST_T, ENTRY(ficom_r80_by_i32))3417 TEST_FPU_BINARY_FSW(1 6, I16, int16_t, FPU_BINARY_FSW_I16_T, g_aFpuBinaryFswI16, FPU_BINARY_I16_TEST_T, ENTRY(ficom_r80_by_i16))3597 TEST_FPU_BINARY_FSW(0, 80, R80, RTFLOAT80U, FPU_BINARY_FSW_R80_T, g_aFpuBinaryFswR80, FPU_BINARY_R80_TEST_T, ENTRY(fcom_r80_by_r80), ENTRY(fucom_r80_by_r80)) 3598 TEST_FPU_BINARY_FSW(0, 64, R64, RTFLOAT64U, FPU_BINARY_FSW_R64_T, g_aFpuBinaryFswR64, FPU_BINARY_R64_TEST_T, ENTRY(fcom_r80_by_r64)) 3599 TEST_FPU_BINARY_FSW(0, 32, R32, RTFLOAT32U, FPU_BINARY_FSW_R32_T, g_aFpuBinaryFswR32, FPU_BINARY_R32_TEST_T, ENTRY(fcom_r80_by_r32)) 3600 TEST_FPU_BINARY_FSW(1, 32, I32, int32_t, FPU_BINARY_FSW_I32_T, g_aFpuBinaryFswI32, FPU_BINARY_I32_TEST_T, ENTRY(ficom_r80_by_i32)) 3601 TEST_FPU_BINARY_FSW(1, 16, I16, int16_t, FPU_BINARY_FSW_I16_T, g_aFpuBinaryFswI16, FPU_BINARY_I16_TEST_T, ENTRY(ficom_r80_by_i16)) 3418 3602 3419 3603 … … 3438 3622 static void FpuBinaryEflR80Generate(PRTSTREAM pOut, uint32_t cTests) 3439 3623 { 3624 cTests = RT_MAX(160, cTests); /* there are 144 standard input variations */ 3625 3440 3626 X86FXSTATE State; 3441 3627 RT_ZERO(State); 3442 uint32_t cMinNormalPairs = cTests/ 4;3628 uint32_t cMinNormalPairs = (cTests - 144) / 4; 3443 3629 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aFpuBinaryEflR80); iFn++) 3444 3630 { … … 3447 3633 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aFpuBinaryEflR80Specials); iTest += 1) 3448 3634 { 3449 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80 Ex() : s_aFpuBinaryEflR80Specials[iTest - cTests].Val1;3450 RTFLOAT80U const InVal2 = iTest < cTests ? RandR80 Ex() : s_aFpuBinaryEflR80Specials[iTest - cTests].Val2;3635 RTFLOAT80U const InVal1 = iTest < cTests ? RandR80Src1(iTest) : s_aFpuBinaryEflR80Specials[iTest - cTests].Val1; 3636 RTFLOAT80U const InVal2 = iTest < cTests ? RandR80Src2(iTest) : s_aFpuBinaryEflR80Specials[iTest - cTests].Val2; 3451 3637 if (RTFLOAT80U_IS_NORMAL(&InVal1) && RTFLOAT80U_IS_NORMAL(&InVal2)) 3452 3638 cNormalInputPairs++; … … 3591 3777 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 3592 3778 { 3593 RTFLOAT80U InVal = iTest < cTests ? RandR80 Ex() : s_aSpecials[iTest - cTests];3779 RTFLOAT80U InVal = iTest < cTests ? RandR80Src(iTest) : s_aSpecials[iTest - cTests]; 3594 3780 if (RTFLOAT80U_IS_NORMAL(&InVal)) 3595 3781 { … … 3806 3992 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 3807 3993 { 3808 RTFLOAT80U const InVal = iTest < cTests ? RandR80 Ex() : s_aSpecials[iTest - cTests];3994 RTFLOAT80U const InVal = iTest < cTests ? RandR80Src(iTest) : s_aSpecials[iTest - cTests]; 3809 3995 if (RTFLOAT80U_IS_NORMAL(&InVal)) 3810 3996 cNormalInputs++; … … 3937 4123 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 3938 4124 { 3939 RTFLOAT80U InVal = iTest < cTests ? RandR80 Ex() : s_aSpecials[iTest - cTests];4125 RTFLOAT80U InVal = iTest < cTests ? RandR80Src(iTest) : s_aSpecials[iTest - cTests]; 3940 4126 if (RTFLOAT80U_IS_NORMAL(&InVal)) 3941 4127 { -
trunk/src/libs/softfloat-3e/source/include/softfloat_types.h
r94558 r94606 96 96 /* softfloat_flag_inexact and friends. */ 97 97 uint8_t exceptionFlags; 98 /** Masked exceptions (only underflow is relevant). */ 99 uint8_t exceptionMask; 98 100 /* extF80: rounding precsision: 32, 64 or 80 */ 99 101 uint8_t roundingPrecision; 100 102 } softfloat_state_t; 101 # define SOFTFLOAT_STATE_INIT_DEFAULTS() { softfloat_round_near_even, softfloat_tininess_afterRounding, 0, 80 }103 # define SOFTFLOAT_STATE_INIT_DEFAULTS() { softfloat_round_near_even, softfloat_tininess_afterRounding, 0, 0x3f, 80 } 102 104 #else 103 105 # undef VBOX_WITHOUT_SOFTFLOAT_GLOBALS -
trunk/src/libs/softfloat-3e/source/s_roundPackToExtF80.c
r94564 r94606 40 40 #include "internals.h" 41 41 #include "softfloat.h" 42 #include <iprt/types.h> /* VBox: RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST */ 43 //#include <iprt/assert.h> 42 44 43 45 extFloat80_t … … 57 59 struct uint64_extra sig64Extra; 58 60 union { struct extFloat80M s; extFloat80_t f; } uZ; 61 //RTAssertMsg2("softfloat_roundPackToExtF80: exp=%d sig=%RX64 sigExtra=%RX64 rp=%d\n", exp, sig, sigExtra, roundingPrecision); 59 62 60 63 /*------------------------------------------------------------------------ … … 87 90 /*---------------------------------------------------------------- 88 91 *----------------------------------------------------------------*/ 92 bool fUnmaskedUnderflow = false; /* VBox: unmasked underflow bias */ 89 93 isTiny = 90 94 (softfloat_detectTininess … … 92 96 || (exp < 0) 93 97 || (sig <= (uint64_t) (sig + roundIncrement)); 94 sig = softfloat_shiftRightJam64( sig, 1 - exp ); 98 if ( (pState->exceptionMask & softfloat_flag_underflow) /* VBox: unmasked underflow bias */ 99 || (exp == -63 && sig == 0 && sigExtra == 0) /* zero */ ) { /* VBox: unmasked underflow bias */ 100 sig = softfloat_shiftRightJam64(sig, 1 - exp); 101 } else { /* VBox: unmasked underflow bias */ 102 //RTAssertMsg2("softfloat_roundPackToExtF80: #UE - bias adj: %d -> %d; sig=%#RX64\n", exp, exp + RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST, sig); /* VBox: unmasked underflow bias */ 103 softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias */ 104 exp += RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST; /* VBox: unmasked underflow bias */ 105 fUnmaskedUnderflow = true; /* VBox: unmasked underflow bias */ 106 } /* VBox: unmasked underflow bias */ 107 uint64_t const uOldSig = sig; /* VBox */ 95 108 roundBits = sig & roundMask; 96 109 if ( roundBits ) { 97 110 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); 98 111 softfloat_exceptionFlags |= softfloat_flag_inexact; 99 if ( roundIncrement ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */100 112 #ifdef SOFTFLOAT_ROUND_ODD 101 113 if ( roundingMode == softfloat_round_odd ) { … … 105 117 } 106 118 sig += roundIncrement; 107 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); 119 if ( !fUnmaskedUnderflow ) { /* VBox: unmasked underflow bias */ 120 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); 121 } /* VBox: unmasked underflow bias */ 108 122 roundIncrement = roundMask + 1; 109 123 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) { … … 111 125 } 112 126 sig &= ~roundMask; 127 if ( sig > uOldSig ) { /* VBox: C1 */ 128 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 129 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #1\n"); /* VBox: C1 */ 130 } /* VBox: C1 */ 113 131 goto packReturn; 114 132 } … … 122 140 /*------------------------------------------------------------------------ 123 141 *------------------------------------------------------------------------*/ 124 { /* VBox*/125 uint64_t const uOldSig = sig; /* VBox*/142 { /* VBox: C1 */ 143 uint64_t const uOldSig = sig; /* VBox: C1 */ 126 144 if ( roundBits ) { 127 145 softfloat_exceptionFlags |= softfloat_flag_inexact; … … 129 147 if ( roundingMode == softfloat_round_odd ) { 130 148 sig = (sig & ~roundMask) | (roundMask + 1); 131 if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 149 if ( sig > uOldSig ) { /* VBox: C1 */ 150 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 151 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #2\n"); /* VBox: C1 */ 152 } /* VBox: C1 */ 132 153 goto packReturn; 133 154 } … … 138 159 ++exp; 139 160 sig = UINT64_C( 0x8000000000000000 ); 140 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 161 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 162 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #3\n"); /* VBox: C1 */ 141 163 } 142 164 roundIncrement = roundMask + 1; … … 145 167 } 146 168 sig &= ~roundMask; 147 if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 169 if ( sig > uOldSig ) { /* VBox: C1 */ 170 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 171 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #4\n"); /* VBox: C1 */ 172 } /* VBox: C1 */ 148 173 goto packReturn; 149 } /* VBox*/174 } /* VBox: C1 */ 150 175 /*------------------------------------------------------------------------ 151 176 *------------------------------------------------------------------------*/ … … 164 189 /*---------------------------------------------------------------- 165 190 *----------------------------------------------------------------*/ 191 bool fUnmaskedUnderflow = false; /* VBox: unmasked underflow bias */ 166 192 isTiny = 167 193 (softfloat_detectTininess … … 170 196 || ! doIncrement 171 197 || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF )); 172 sig64Extra = 173 softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp ); 174 exp = 0; 175 sig = sig64Extra.v; 176 sigExtra = sig64Extra.extra; 198 if ( (pState->exceptionMask & softfloat_flag_underflow) /* VBox: unmasked underflow bias */ 199 || (exp == -63 && sig == 0 && sigExtra == 0) /* zero */ ) { /* VBox: unmasked underflow bias */ 200 sig64Extra = 201 softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp ); 202 exp = 0; 203 sig = sig64Extra.v; 204 sigExtra = sig64Extra.extra; 205 } else { /* VBox: unmasked underflow bias */ 206 //RTAssertMsg2("softfloat_roundPackToExtF80: #UE/80 - bias adj: %d -> %d; sig=%#RX64'%016RX64\n", exp, exp + RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST, sig, sigExtra); /* VBox: unmasked underflow bias */ 207 softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias */ 208 exp += RTFLOAT80U_EXP_BIAS_UNDERFLOW_ADJUST; /* VBox: unmasked underflow bias */ 209 fUnmaskedUnderflow = true; /* VBox: unmasked underflow bias */ 210 } /* VBox: unmasked underflow bias */ 177 211 if ( sigExtra ) { 178 212 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); … … 195 229 } 196 230 if ( doIncrement ) { 197 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 231 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 232 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #5\n"); /* VBox: C1 */ 198 233 ++sig; 199 234 sig &= … … 201 236 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) 202 237 & roundNearEven); 203 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); 238 if ( fUnmaskedUnderflow ) { /* VBox: unmasked underflow bias */ 239 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); 240 } else if ((sig & UINT64_C( 0x8000000000000000 )) != 0) { /* VBox: unmasked underflow bias */ 241 exp++; /* VBox: unmasked underflow bias */ 242 } /* VBox: unmasked underflow bias */ 204 243 } 205 244 goto packReturn; … … 225 264 exp = 0x7FFF; 226 265 sig = UINT64_C( 0x8000000000000000 ); 266 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 - Returning infinity means we've rounded up. */ 267 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #6\n"); 268 269 /* VBox: HACK ALERT! Some utterly weird behaviour, found with 'fadd 0,max', precision < 64 and rounding away from 0. */ 270 if ( !(pState->exceptionMask & softfloat_flag_overflow) ) /* VBox */ 271 exp = 8191; /* => -8192 */ /* VBox */ 227 272 } else { 228 273 exp = 0x7FFE; … … 249 294 ++exp; 250 295 sig = UINT64_C( 0x8000000000000000 ); 251 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 296 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 297 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #7\n"); /* VBox: C1 */ 252 298 } else { 253 299 sig &= … … 255 301 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) 256 302 & roundNearEven); 257 if ( sig > uOldSig ) softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox */ 303 if ( sig > uOldSig ) { /* VBox: C1 */ 304 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */ 305 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #8\n"); /* VBox: C1 */ 306 } 258 307 } 259 308 }
Note:
See TracChangeset
for help on using the changeset viewer.

