1 //===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/APFixedPoint.h" 10 #include "llvm/ADT/APFloat.h" 11 #include "llvm/ADT/APSInt.h" 12 #include "gtest/gtest.h" 13 14 using llvm::APFixedPoint; 15 using llvm::APFloat; 16 using llvm::APInt; 17 using llvm::APSInt; 18 using llvm::FixedPointSemantics; 19 20 namespace { 21 22 FixedPointSemantics Saturated(FixedPointSemantics Sema) { 23 Sema.setSaturated(true); 24 return Sema; 25 } 26 27 FixedPointSemantics getSAccumSema() { 28 return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/true, 29 /*isSaturated=*/false, 30 /*hasUnsignedPadding=*/false); 31 } 32 33 FixedPointSemantics getAccumSema() { 34 return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/true, 35 /*isSaturated=*/false, 36 /*hasUnsignedPadding=*/false); 37 } 38 39 FixedPointSemantics getLAccumSema() { 40 return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/true, 41 /*isSaturated=*/false, 42 /*hasUnsignedPadding=*/false); 43 } 44 45 FixedPointSemantics getSFractSema() { 46 return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/true, 47 /*isSaturated=*/false, 48 /*hasUnsignedPadding=*/false); 49 } 50 51 FixedPointSemantics getFractSema() { 52 return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/true, 53 /*isSaturated=*/false, 54 /*hasUnsignedPadding=*/false); 55 } 56 57 FixedPointSemantics getLFractSema() { 58 return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/true, 59 /*isSaturated=*/false, 60 /*hasUnsignedPadding=*/false); 61 } 62 63 FixedPointSemantics getUSAccumSema() { 64 return FixedPointSemantics(/*width=*/16, /*scale=*/8, /*isSigned=*/false, 65 /*isSaturated=*/false, 66 /*hasUnsignedPadding=*/false); 67 } 68 69 FixedPointSemantics getUAccumSema() { 70 return FixedPointSemantics(/*width=*/32, /*scale=*/16, /*isSigned=*/false, 71 /*isSaturated=*/false, 72 /*hasUnsignedPadding=*/false); 73 } 74 75 FixedPointSemantics getULAccumSema() { 76 return FixedPointSemantics(/*width=*/64, /*scale=*/32, /*isSigned=*/false, 77 /*isSaturated=*/false, 78 /*hasUnsignedPadding=*/false); 79 } 80 81 FixedPointSemantics getUSFractSema() { 82 return FixedPointSemantics(/*width=*/8, /*scale=*/8, /*isSigned=*/false, 83 /*isSaturated=*/false, 84 /*hasUnsignedPadding=*/false); 85 } 86 87 FixedPointSemantics getUFractSema() { 88 return FixedPointSemantics(/*width=*/16, /*scale=*/16, /*isSigned=*/false, 89 /*isSaturated=*/false, 90 /*hasUnsignedPadding=*/false); 91 } 92 93 FixedPointSemantics getULFractSema() { 94 return FixedPointSemantics(/*width=*/32, /*scale=*/32, /*isSigned=*/false, 95 /*isSaturated=*/false, 96 /*hasUnsignedPadding=*/false); 97 } 98 99 FixedPointSemantics getPadUSAccumSema() { 100 return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/false, 101 /*isSaturated=*/false, 102 /*hasUnsignedPadding=*/true); 103 } 104 105 FixedPointSemantics getPadUAccumSema() { 106 return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/false, 107 /*isSaturated=*/false, 108 /*hasUnsignedPadding=*/true); 109 } 110 111 FixedPointSemantics getPadULAccumSema() { 112 return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/false, 113 /*isSaturated=*/false, 114 /*hasUnsignedPadding=*/true); 115 } 116 117 FixedPointSemantics getPadUSFractSema() { 118 return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/false, 119 /*isSaturated=*/false, 120 /*hasUnsignedPadding=*/true); 121 } 122 123 FixedPointSemantics getPadUFractSema() { 124 return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/false, 125 /*isSaturated=*/false, 126 /*hasUnsignedPadding=*/true); 127 } 128 129 FixedPointSemantics getPadULFractSema() { 130 return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/false, 131 /*isSaturated=*/false, 132 /*hasUnsignedPadding=*/true); 133 } 134 135 void CheckUnpaddedMax(const FixedPointSemantics &Sema) { 136 ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(), 137 APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned())); 138 } 139 140 void CheckPaddedMax(const FixedPointSemantics &Sema) { 141 ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(), 142 APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()) >> 1); 143 } 144 145 void CheckMin(const FixedPointSemantics &Sema) { 146 ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(), 147 APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned())); 148 } 149 150 TEST(FixedPointTest, getMax) { 151 CheckUnpaddedMax(getSAccumSema()); 152 CheckUnpaddedMax(getAccumSema()); 153 CheckUnpaddedMax(getLAccumSema()); 154 CheckUnpaddedMax(getUSAccumSema()); 155 CheckUnpaddedMax(getUAccumSema()); 156 CheckUnpaddedMax(getULAccumSema()); 157 CheckUnpaddedMax(getSFractSema()); 158 CheckUnpaddedMax(getFractSema()); 159 CheckUnpaddedMax(getLFractSema()); 160 CheckUnpaddedMax(getUSFractSema()); 161 CheckUnpaddedMax(getUFractSema()); 162 CheckUnpaddedMax(getULFractSema()); 163 164 CheckPaddedMax(getPadUSAccumSema()); 165 CheckPaddedMax(getPadUAccumSema()); 166 CheckPaddedMax(getPadULAccumSema()); 167 CheckPaddedMax(getPadUSFractSema()); 168 CheckPaddedMax(getPadUFractSema()); 169 CheckPaddedMax(getPadULFractSema()); 170 } 171 172 TEST(FixedPointTest, getMin) { 173 CheckMin(getSAccumSema()); 174 CheckMin(getAccumSema()); 175 CheckMin(getLAccumSema()); 176 CheckMin(getUSAccumSema()); 177 CheckMin(getUAccumSema()); 178 CheckMin(getULAccumSema()); 179 CheckMin(getSFractSema()); 180 CheckMin(getFractSema()); 181 CheckMin(getLFractSema()); 182 CheckMin(getUSFractSema()); 183 CheckMin(getUFractSema()); 184 CheckMin(getULFractSema()); 185 186 CheckMin(getPadUSAccumSema()); 187 CheckMin(getPadUAccumSema()); 188 CheckMin(getPadULAccumSema()); 189 CheckMin(getPadUSFractSema()); 190 CheckMin(getPadUFractSema()); 191 CheckMin(getPadULFractSema()); 192 } 193 194 void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) { 195 unsigned Scale = Sema.getScale(); 196 197 // Value with a fraction 198 APFixedPoint ValWithFract(APInt(Sema.getWidth(), 199 (IntPart << Scale) + (1ULL << (Scale - 1)), 200 Sema.isSigned()), 201 Sema); 202 ASSERT_EQ(ValWithFract.getIntPart(), IntPart); 203 204 // Just fraction 205 APFixedPoint JustFract( 206 APInt(Sema.getWidth(), (1ULL << (Scale - 1)), Sema.isSigned()), Sema); 207 ASSERT_EQ(JustFract.getIntPart(), 0); 208 209 // Whole number 210 APFixedPoint WholeNum( 211 APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema); 212 ASSERT_EQ(WholeNum.getIntPart(), IntPart); 213 214 // Negative 215 if (Sema.isSigned()) { 216 APFixedPoint Negative( 217 APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema); 218 ASSERT_EQ(Negative.getIntPart(), IntPart); 219 } 220 } 221 222 void CheckIntPartMin(const FixedPointSemantics &Sema, int64_t Expected) { 223 ASSERT_EQ(APFixedPoint::getMin(Sema).getIntPart(), Expected); 224 } 225 226 void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) { 227 ASSERT_EQ(APFixedPoint::getMax(Sema).getIntPart(), Expected); 228 } 229 230 TEST(FixedPoint, getIntPart) { 231 // Normal values 232 CheckIntPart(getSAccumSema(), 2); 233 CheckIntPart(getAccumSema(), 2); 234 CheckIntPart(getLAccumSema(), 2); 235 CheckIntPart(getUSAccumSema(), 2); 236 CheckIntPart(getUAccumSema(), 2); 237 CheckIntPart(getULAccumSema(), 2); 238 239 // Zero 240 CheckIntPart(getSAccumSema(), 0); 241 CheckIntPart(getAccumSema(), 0); 242 CheckIntPart(getLAccumSema(), 0); 243 CheckIntPart(getUSAccumSema(), 0); 244 CheckIntPart(getUAccumSema(), 0); 245 CheckIntPart(getULAccumSema(), 0); 246 247 CheckIntPart(getSFractSema(), 0); 248 CheckIntPart(getFractSema(), 0); 249 CheckIntPart(getLFractSema(), 0); 250 CheckIntPart(getUSFractSema(), 0); 251 CheckIntPart(getUFractSema(), 0); 252 CheckIntPart(getULFractSema(), 0); 253 254 // Min 255 CheckIntPartMin(getSAccumSema(), -256); 256 CheckIntPartMin(getAccumSema(), -65536); 257 CheckIntPartMin(getLAccumSema(), -4294967296); 258 259 CheckIntPartMin(getSFractSema(), -1); 260 CheckIntPartMin(getFractSema(), -1); 261 CheckIntPartMin(getLFractSema(), -1); 262 263 // Max 264 CheckIntPartMax(getSAccumSema(), 255); 265 CheckIntPartMax(getAccumSema(), 65535); 266 CheckIntPartMax(getLAccumSema(), 4294967295); 267 CheckIntPartMax(getUSAccumSema(), 255); 268 CheckIntPartMax(getUAccumSema(), 65535); 269 CheckIntPartMax(getULAccumSema(), 4294967295); 270 271 CheckIntPartMax(getSFractSema(), 0); 272 CheckIntPartMax(getFractSema(), 0); 273 CheckIntPartMax(getLFractSema(), 0); 274 CheckIntPartMax(getUSFractSema(), 0); 275 CheckIntPartMax(getUFractSema(), 0); 276 CheckIntPartMax(getULFractSema(), 0); 277 278 // Padded 279 // Normal Values 280 CheckIntPart(getPadUSAccumSema(), 2); 281 CheckIntPart(getPadUAccumSema(), 2); 282 CheckIntPart(getPadULAccumSema(), 2); 283 284 // Zero 285 CheckIntPart(getPadUSAccumSema(), 0); 286 CheckIntPart(getPadUAccumSema(), 0); 287 CheckIntPart(getPadULAccumSema(), 0); 288 289 CheckIntPart(getPadUSFractSema(), 0); 290 CheckIntPart(getPadUFractSema(), 0); 291 CheckIntPart(getPadULFractSema(), 0); 292 293 // Max 294 CheckIntPartMax(getPadUSAccumSema(), 255); 295 CheckIntPartMax(getPadUAccumSema(), 65535); 296 CheckIntPartMax(getPadULAccumSema(), 4294967295); 297 298 CheckIntPartMax(getPadUSFractSema(), 0); 299 CheckIntPartMax(getPadUFractSema(), 0); 300 CheckIntPartMax(getPadULFractSema(), 0); 301 } 302 303 TEST(FixedPoint, compare) { 304 // Equality 305 // With fractional part (2.5) 306 // Across sizes 307 ASSERT_EQ(APFixedPoint(320, getSAccumSema()), 308 APFixedPoint(81920, getAccumSema())); 309 ASSERT_EQ(APFixedPoint(320, getSAccumSema()), 310 APFixedPoint(5368709120, getLAccumSema())); 311 ASSERT_EQ(APFixedPoint(0, getSAccumSema()), APFixedPoint(0, getLAccumSema())); 312 313 // Across types (0.5) 314 ASSERT_EQ(APFixedPoint(64, getSAccumSema()), 315 APFixedPoint(64, getSFractSema())); 316 ASSERT_EQ(APFixedPoint(16384, getAccumSema()), 317 APFixedPoint(16384, getFractSema())); 318 ASSERT_EQ(APFixedPoint(1073741824, getLAccumSema()), 319 APFixedPoint(1073741824, getLFractSema())); 320 321 // Across widths and types (0.5) 322 ASSERT_EQ(APFixedPoint(64, getSAccumSema()), 323 APFixedPoint(16384, getFractSema())); 324 ASSERT_EQ(APFixedPoint(64, getSAccumSema()), 325 APFixedPoint(1073741824, getLFractSema())); 326 327 // Across saturation 328 ASSERT_EQ(APFixedPoint(320, getSAccumSema()), 329 APFixedPoint(81920, Saturated(getAccumSema()))); 330 331 // Across signs 332 ASSERT_EQ(APFixedPoint(320, getSAccumSema()), 333 APFixedPoint(640, getUSAccumSema())); 334 ASSERT_EQ(APFixedPoint(-320, getSAccumSema()), 335 APFixedPoint(-81920, getAccumSema())); 336 337 // Across padding 338 ASSERT_EQ(APFixedPoint(320, getSAccumSema()), 339 APFixedPoint(320, getPadUSAccumSema())); 340 ASSERT_EQ(APFixedPoint(640, getUSAccumSema()), 341 APFixedPoint(320, getPadUSAccumSema())); 342 343 // Less than 344 ASSERT_LT(APFixedPoint(-1, getSAccumSema()), APFixedPoint(0, getAccumSema())); 345 ASSERT_LT(APFixedPoint(-1, getSAccumSema()), 346 APFixedPoint(0, getUAccumSema())); 347 ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getAccumSema())); 348 ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getUAccumSema())); 349 ASSERT_LT(APFixedPoint(0, getUSAccumSema()), APFixedPoint(1, getAccumSema())); 350 ASSERT_LT(APFixedPoint(0, getUSAccumSema()), 351 APFixedPoint(1, getUAccumSema())); 352 353 // Greater than 354 ASSERT_GT(APFixedPoint(0, getAccumSema()), APFixedPoint(-1, getSAccumSema())); 355 ASSERT_GT(APFixedPoint(0, getUAccumSema()), 356 APFixedPoint(-1, getSAccumSema())); 357 ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getSAccumSema())); 358 ASSERT_GT(APFixedPoint(1, getUAccumSema()), APFixedPoint(0, getSAccumSema())); 359 ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getUSAccumSema())); 360 ASSERT_GT(APFixedPoint(1, getUAccumSema()), 361 APFixedPoint(0, getUSAccumSema())); 362 } 363 364 // Check that a fixed point value in one sema is the same in another sema 365 void CheckUnsaturatedConversion(FixedPointSemantics Src, 366 FixedPointSemantics Dst, int64_t TestVal) { 367 int64_t ScaledVal = TestVal; 368 bool IsNegative = ScaledVal < 0; 369 if (IsNegative) 370 ScaledVal = -ScaledVal; 371 372 if (Dst.getScale() > Src.getScale()) { 373 ScaledVal <<= (Dst.getScale() - Src.getScale()); 374 } else { 375 ScaledVal >>= (Src.getScale() - Dst.getScale()); 376 } 377 378 if (IsNegative) 379 ScaledVal = -ScaledVal; 380 381 APFixedPoint Fixed(TestVal, Src); 382 APFixedPoint Expected(ScaledVal, Dst); 383 ASSERT_EQ(Fixed.convert(Dst), Expected); 384 } 385 386 // Check the value in a given fixed point sema overflows to the saturated min 387 // for another sema 388 void CheckSaturatedConversionMin(FixedPointSemantics Src, 389 FixedPointSemantics Dst, int64_t TestVal) { 390 APFixedPoint Fixed(TestVal, Src); 391 ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMin(Dst)); 392 } 393 394 // Check the value in a given fixed point sema overflows to the saturated max 395 // for another sema 396 void CheckSaturatedConversionMax(FixedPointSemantics Src, 397 FixedPointSemantics Dst, int64_t TestVal) { 398 APFixedPoint Fixed(TestVal, Src); 399 ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMax(Dst)); 400 } 401 402 // Check one signed _Accum sema converted to other sema for different values. 403 void CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src, 404 int64_t OneVal) { 405 int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5 406 int64_t HalfVal = (OneVal / 2); // 0.5 407 408 // +Accums to Accums 409 CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal); 410 CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal); 411 CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal); 412 CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal); 413 CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal); 414 CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal); 415 CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal); 416 CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal); 417 CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal); 418 419 // -Accums to Accums 420 CheckUnsaturatedConversion(Src, getSAccumSema(), -NormalVal); 421 CheckUnsaturatedConversion(Src, getAccumSema(), -NormalVal); 422 CheckUnsaturatedConversion(Src, getLAccumSema(), -NormalVal); 423 CheckSaturatedConversionMin(Src, Saturated(getUSAccumSema()), -NormalVal); 424 CheckSaturatedConversionMin(Src, Saturated(getUAccumSema()), -NormalVal); 425 CheckSaturatedConversionMin(Src, Saturated(getULAccumSema()), -NormalVal); 426 CheckSaturatedConversionMin(Src, Saturated(getPadUSAccumSema()), -NormalVal); 427 CheckSaturatedConversionMin(Src, Saturated(getPadUAccumSema()), -NormalVal); 428 CheckSaturatedConversionMin(Src, Saturated(getPadULAccumSema()), -NormalVal); 429 430 // +Accums to Fracts 431 CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal); 432 CheckUnsaturatedConversion(Src, getFractSema(), HalfVal); 433 CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal); 434 CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal); 435 CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal); 436 CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal); 437 CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal); 438 CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal); 439 CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal); 440 441 // -Accums to Fracts 442 CheckUnsaturatedConversion(Src, getSFractSema(), -HalfVal); 443 CheckUnsaturatedConversion(Src, getFractSema(), -HalfVal); 444 CheckUnsaturatedConversion(Src, getLFractSema(), -HalfVal); 445 CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), -HalfVal); 446 CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), -HalfVal); 447 CheckSaturatedConversionMin(Src, Saturated(getULFractSema()), -HalfVal); 448 CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), -HalfVal); 449 CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), -HalfVal); 450 CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), -HalfVal); 451 452 // 0 to Accums 453 CheckUnsaturatedConversion(Src, getSAccumSema(), 0); 454 CheckUnsaturatedConversion(Src, getAccumSema(), 0); 455 CheckUnsaturatedConversion(Src, getLAccumSema(), 0); 456 CheckUnsaturatedConversion(Src, getUSAccumSema(), 0); 457 CheckUnsaturatedConversion(Src, getUAccumSema(), 0); 458 CheckUnsaturatedConversion(Src, getULAccumSema(), 0); 459 CheckUnsaturatedConversion(Src, getPadUSAccumSema(), 0); 460 CheckUnsaturatedConversion(Src, getPadUAccumSema(), 0); 461 CheckUnsaturatedConversion(Src, getPadULAccumSema(), 0); 462 463 // 0 to Fracts 464 CheckUnsaturatedConversion(Src, getSFractSema(), 0); 465 CheckUnsaturatedConversion(Src, getFractSema(), 0); 466 CheckUnsaturatedConversion(Src, getLFractSema(), 0); 467 CheckUnsaturatedConversion(Src, getUSFractSema(), 0); 468 CheckUnsaturatedConversion(Src, getUFractSema(), 0); 469 CheckUnsaturatedConversion(Src, getULFractSema(), 0); 470 CheckUnsaturatedConversion(Src, getPadUSFractSema(), 0); 471 CheckUnsaturatedConversion(Src, getPadUFractSema(), 0); 472 CheckUnsaturatedConversion(Src, getPadULFractSema(), 0); 473 } 474 475 // Check one unsigned _Accum sema converted to other sema for different 476 // values. 477 void CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src, 478 int64_t OneVal) { 479 int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5 480 int64_t HalfVal = (OneVal / 2); // 0.5 481 482 // +UAccums to Accums 483 CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal); 484 CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal); 485 CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal); 486 CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal); 487 CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal); 488 CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal); 489 CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal); 490 CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal); 491 CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal); 492 493 // +UAccums to Fracts 494 CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal); 495 CheckUnsaturatedConversion(Src, getFractSema(), HalfVal); 496 CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal); 497 CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal); 498 CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal); 499 CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal); 500 CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal); 501 CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal); 502 CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal); 503 } 504 505 TEST(FixedPoint, AccumConversions) { 506 // Normal conversions 507 CheckSignedAccumConversionsAgainstOthers(getSAccumSema(), 128); 508 CheckUnsignedAccumConversionsAgainstOthers(getUSAccumSema(), 256); 509 CheckSignedAccumConversionsAgainstOthers(getAccumSema(), 32768); 510 CheckUnsignedAccumConversionsAgainstOthers(getUAccumSema(), 65536); 511 CheckSignedAccumConversionsAgainstOthers(getLAccumSema(), 2147483648); 512 CheckUnsignedAccumConversionsAgainstOthers(getULAccumSema(), 4294967296); 513 514 CheckUnsignedAccumConversionsAgainstOthers(getPadUSAccumSema(), 128); 515 CheckUnsignedAccumConversionsAgainstOthers(getPadUAccumSema(), 32768); 516 CheckUnsignedAccumConversionsAgainstOthers(getPadULAccumSema(), 2147483648); 517 } 518 519 TEST(FixedPoint, AccumConversionOverflow) { 520 // To SAccum max limit (65536) 521 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getAccumSema()), 522 140737488355328); 523 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUAccumSema()), 524 140737488355328); 525 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUAccumSema()), 526 140737488355328); 527 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getAccumSema()), 528 281474976710656); 529 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUAccumSema()), 530 281474976710656); 531 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUAccumSema()), 532 281474976710656); 533 534 CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getAccumSema()), 535 140737488355328); 536 CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUAccumSema()), 537 140737488355328); 538 CheckSaturatedConversionMax(getPadULAccumSema(), 539 Saturated(getPadUAccumSema()), 140737488355328); 540 541 // To SAccum min limit (-65536) 542 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getAccumSema()), 543 -140737488355328); 544 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUAccumSema()), 545 -140737488355328); 546 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUAccumSema()), 547 -140737488355328); 548 } 549 550 TEST(FixedPoint, SAccumConversionOverflow) { 551 // To SAccum max limit (256) 552 CheckSaturatedConversionMax(getAccumSema(), Saturated(getSAccumSema()), 553 8388608); 554 CheckSaturatedConversionMax(getAccumSema(), Saturated(getUSAccumSema()), 555 8388608); 556 CheckSaturatedConversionMax(getAccumSema(), Saturated(getPadUSAccumSema()), 557 8388608); 558 CheckSaturatedConversionMax(getUAccumSema(), Saturated(getSAccumSema()), 559 16777216); 560 CheckSaturatedConversionMax(getUAccumSema(), Saturated(getUSAccumSema()), 561 16777216); 562 CheckSaturatedConversionMax(getUAccumSema(), Saturated(getPadUSAccumSema()), 563 16777216); 564 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getSAccumSema()), 565 549755813888); 566 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUSAccumSema()), 567 549755813888); 568 CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUSAccumSema()), 569 549755813888); 570 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getSAccumSema()), 571 1099511627776); 572 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUSAccumSema()), 573 1099511627776); 574 CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUSAccumSema()), 575 1099511627776); 576 577 CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getSAccumSema()), 578 8388608); 579 CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getUSAccumSema()), 580 8388608); 581 CheckSaturatedConversionMax(getPadUAccumSema(), 582 Saturated(getPadUSAccumSema()), 8388608); 583 CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getSAccumSema()), 584 549755813888); 585 CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUSAccumSema()), 586 549755813888); 587 CheckSaturatedConversionMax(getPadULAccumSema(), 588 Saturated(getPadUSAccumSema()), 549755813888); 589 590 // To SAccum min limit (-256) 591 CheckSaturatedConversionMin(getAccumSema(), Saturated(getSAccumSema()), 592 -8388608); 593 CheckSaturatedConversionMin(getAccumSema(), Saturated(getUSAccumSema()), 594 -8388608); 595 CheckSaturatedConversionMin(getAccumSema(), Saturated(getPadUSAccumSema()), 596 -8388608); 597 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getSAccumSema()), 598 -549755813888); 599 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUSAccumSema()), 600 -549755813888); 601 CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUSAccumSema()), 602 -549755813888); 603 } 604 605 TEST(FixedPoint, GetValueSignAfterConversion) { 606 APFixedPoint Fixed(255 << 7, getSAccumSema()); 607 ASSERT_TRUE(Fixed.getValue().isSigned()); 608 APFixedPoint UFixed = Fixed.convert(getUSAccumSema()); 609 ASSERT_TRUE(UFixed.getValue().isUnsigned()); 610 ASSERT_EQ(UFixed.getValue(), APSInt::getUnsigned(255 << 8).extOrTrunc(16)); 611 } 612 613 TEST(FixedPoint, ModularWrapAround) { 614 // Positive to negative 615 APFixedPoint Val = APFixedPoint(1ULL << 7, getSAccumSema()); 616 ASSERT_EQ(Val.convert(getLFractSema()).getValue(), -(1ULL << 31)); 617 618 Val = APFixedPoint(1ULL << 23, getAccumSema()); 619 ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), -(1ULL << 15)); 620 621 Val = APFixedPoint(1ULL << 47, getLAccumSema()); 622 ASSERT_EQ(Val.convert(getAccumSema()).getValue(), -(1ULL << 31)); 623 624 // Negative to positive 625 Val = APFixedPoint(/*-1.5*/ -192, getSAccumSema()); 626 ASSERT_EQ(Val.convert(getLFractSema()).getValue(), 1ULL << 30); 627 628 Val = APFixedPoint(-(257 << 15), getAccumSema()); 629 ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), 255 << 7); 630 631 Val = APFixedPoint(-(65537ULL << 31), getLAccumSema()); 632 ASSERT_EQ(Val.convert(getAccumSema()).getValue(), 65535 << 15); 633 634 // Signed to unsigned 635 Val = APFixedPoint(-(1 << 7), getSAccumSema()); 636 ASSERT_EQ(Val.convert(getUSAccumSema()).getValue(), 255 << 8); 637 638 Val = APFixedPoint(-(1 << 15), getAccumSema()); 639 ASSERT_EQ(Val.convert(getUAccumSema()).getValue(), 65535ULL << 16); 640 641 Val = APFixedPoint(-(1ULL << 31), getLAccumSema()); 642 ASSERT_EQ(Val.convert(getULAccumSema()).getValue().getZExtValue(), 643 4294967295ULL << 32); 644 } 645 646 enum OvfKind { MinSat, MaxSat }; 647 648 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema, 649 int64_t ExpectedNonSat) { 650 bool Ovf; 651 ASSERT_EQ(APFixedPoint::getFromFloatValue(Val, Sema, &Ovf).getValue(), 652 ExpectedNonSat); 653 ASSERT_EQ(Ovf, false); 654 ASSERT_EQ( 655 APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(), 656 ExpectedNonSat); 657 ASSERT_EQ(Ovf, false); 658 } 659 660 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema, 661 OvfKind ExpectedOvf) { 662 bool Ovf; 663 (void)APFixedPoint::getFromFloatValue(Val, Sema, &Ovf); 664 ASSERT_EQ(Ovf, true); 665 ASSERT_EQ( 666 APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(), 667 (ExpectedOvf == MinSat ? APFixedPoint::getMin(Sema) 668 : APFixedPoint::getMax(Sema)) 669 .getValue()); 670 ASSERT_EQ(Ovf, false); 671 } 672 673 TEST(FixedPoint, FloatToFixed) { 674 APFloat Val(0.0f); 675 676 // Simple exact fraction 677 Val = APFloat(0.75f); 678 CheckFloatToFixedConversion(Val, getSAccumSema(), 3ULL << 5); 679 CheckFloatToFixedConversion(Val, getAccumSema(), 3ULL << 13); 680 CheckFloatToFixedConversion(Val, getLAccumSema(), 3ULL << 29); 681 682 CheckFloatToFixedConversion(Val, getUSAccumSema(), 3ULL << 6); 683 CheckFloatToFixedConversion(Val, getUAccumSema(), 3ULL << 14); 684 CheckFloatToFixedConversion(Val, getULAccumSema(), 3ULL << 30); 685 686 CheckFloatToFixedConversion(Val, getSFractSema(), 3ULL << 5); 687 CheckFloatToFixedConversion(Val, getFractSema(), 3ULL << 13); 688 CheckFloatToFixedConversion(Val, getLFractSema(), 3ULL << 29); 689 690 CheckFloatToFixedConversion(Val, getUSFractSema(), 3ULL << 6); 691 CheckFloatToFixedConversion(Val, getUFractSema(), 3ULL << 14); 692 CheckFloatToFixedConversion(Val, getULFractSema(), 3ULL << 30); 693 694 // Simple negative exact fraction 695 Val = APFloat(-0.75f); 696 CheckFloatToFixedConversion(Val, getSAccumSema(), -3ULL << 5); 697 CheckFloatToFixedConversion(Val, getAccumSema(), -3ULL << 13); 698 CheckFloatToFixedConversion(Val, getLAccumSema(), -3ULL << 29); 699 700 CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat); 701 CheckFloatToFixedConversion(Val, getUAccumSema(), MinSat); 702 CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat); 703 704 CheckFloatToFixedConversion(Val, getSFractSema(), -3ULL << 5); 705 CheckFloatToFixedConversion(Val, getFractSema(), -3ULL << 13); 706 CheckFloatToFixedConversion(Val, getLFractSema(), -3ULL << 29); 707 708 CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat); 709 CheckFloatToFixedConversion(Val, getUFractSema(), MinSat); 710 CheckFloatToFixedConversion(Val, getULFractSema(), MinSat); 711 712 // Highly precise fraction 713 Val = APFloat(0.999999940395355224609375f); 714 CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL); 715 CheckFloatToFixedConversion(Val, getAccumSema(), 0x7FFFULL); 716 CheckFloatToFixedConversion(Val, getLAccumSema(), 0xFFFFFFULL << 7); 717 718 CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL); 719 CheckFloatToFixedConversion(Val, getUAccumSema(), 0xFFFFULL); 720 CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFFFFFULL << 8); 721 722 CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL); 723 CheckFloatToFixedConversion(Val, getFractSema(), 0x7FFFULL); 724 CheckFloatToFixedConversion(Val, getLFractSema(), 0xFFFFFFULL << 7); 725 726 CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL); 727 CheckFloatToFixedConversion(Val, getUFractSema(), 0xFFFFULL); 728 CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFFFFFULL << 8); 729 730 // Integral and fraction 731 Val = APFloat(17.99609375f); 732 CheckFloatToFixedConversion(Val, getSAccumSema(), 0x11FFULL >> 1); 733 CheckFloatToFixedConversion(Val, getAccumSema(), 0x11FFULL << 7); 734 CheckFloatToFixedConversion(Val, getLAccumSema(), 0x11FFULL << 23); 735 736 CheckFloatToFixedConversion(Val, getUSAccumSema(), 0x11FFULL); 737 CheckFloatToFixedConversion(Val, getUAccumSema(), 0x11FFULL << 8); 738 CheckFloatToFixedConversion(Val, getULAccumSema(), 0x11FFULL << 24); 739 740 CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat); 741 CheckFloatToFixedConversion(Val, getFractSema(), MaxSat); 742 CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat); 743 744 CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat); 745 CheckFloatToFixedConversion(Val, getUFractSema(), MaxSat); 746 CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat); 747 748 // Negative integral and fraction 749 Val = APFloat(-17.99609375f); 750 CheckFloatToFixedConversion(Val, getSAccumSema(), -0x11FELL >> 1); 751 CheckFloatToFixedConversion(Val, getAccumSema(), -0x11FFULL << 7); 752 CheckFloatToFixedConversion(Val, getLAccumSema(), -0x11FFULL << 23); 753 754 CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat); 755 CheckFloatToFixedConversion(Val, getUAccumSema(), MinSat); 756 CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat); 757 758 CheckFloatToFixedConversion(Val, getSFractSema(), MinSat); 759 CheckFloatToFixedConversion(Val, getFractSema(), MinSat); 760 CheckFloatToFixedConversion(Val, getLFractSema(), MinSat); 761 762 CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat); 763 CheckFloatToFixedConversion(Val, getUFractSema(), MinSat); 764 CheckFloatToFixedConversion(Val, getULFractSema(), MinSat); 765 766 // Very large value 767 Val = APFloat(1.0e38f); 768 CheckFloatToFixedConversion(Val, getSAccumSema(), MaxSat); 769 CheckFloatToFixedConversion(Val, getAccumSema(), MaxSat); 770 CheckFloatToFixedConversion(Val, getLAccumSema(), MaxSat); 771 772 CheckFloatToFixedConversion(Val, getUSAccumSema(), MaxSat); 773 CheckFloatToFixedConversion(Val, getUAccumSema(), MaxSat); 774 CheckFloatToFixedConversion(Val, getULAccumSema(), MaxSat); 775 776 CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat); 777 CheckFloatToFixedConversion(Val, getFractSema(), MaxSat); 778 CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat); 779 780 CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat); 781 CheckFloatToFixedConversion(Val, getUFractSema(), MaxSat); 782 CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat); 783 784 // Very small value 785 Val = APFloat(1.0e-38f); 786 CheckFloatToFixedConversion(Val, getSAccumSema(), 0); 787 CheckFloatToFixedConversion(Val, getAccumSema(), 0); 788 CheckFloatToFixedConversion(Val, getLAccumSema(), 0); 789 790 CheckFloatToFixedConversion(Val, getUSAccumSema(), 0); 791 CheckFloatToFixedConversion(Val, getUAccumSema(), 0); 792 CheckFloatToFixedConversion(Val, getULAccumSema(), 0); 793 794 CheckFloatToFixedConversion(Val, getSFractSema(), 0); 795 CheckFloatToFixedConversion(Val, getFractSema(), 0); 796 CheckFloatToFixedConversion(Val, getLFractSema(), 0); 797 798 CheckFloatToFixedConversion(Val, getUSFractSema(), 0); 799 CheckFloatToFixedConversion(Val, getUFractSema(), 0); 800 CheckFloatToFixedConversion(Val, getULFractSema(), 0); 801 802 // Half conversion 803 Val = APFloat(0.99951171875f); 804 bool Ignored; 805 Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); 806 807 CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL); 808 CheckFloatToFixedConversion(Val, getAccumSema(), 0x7FFULL << 4); 809 CheckFloatToFixedConversion(Val, getLAccumSema(), 0x7FFULL << 20); 810 811 CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL); 812 CheckFloatToFixedConversion(Val, getUAccumSema(), 0xFFEULL << 4); 813 CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFEULL << 20); 814 815 CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL); 816 CheckFloatToFixedConversion(Val, getFractSema(), 0x7FFULL << 4); 817 CheckFloatToFixedConversion(Val, getLFractSema(), 0x7FFULL << 20); 818 819 CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL); 820 CheckFloatToFixedConversion(Val, getUFractSema(), 0xFFEULL << 4); 821 CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFEULL << 20); 822 } 823 824 void CheckFixedToFloatConversion(int64_t Val, const FixedPointSemantics &Sema, 825 float Result) { 826 APFixedPoint FXVal(Val, Sema); 827 APFloat APRes(Result); 828 ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEsingle()), APRes); 829 } 830 831 void CheckFixedToHalfConversion(int64_t Val, const FixedPointSemantics &Sema, 832 float Result) { 833 APFixedPoint FXVal(Val, Sema); 834 APFloat APRes(Result); 835 bool Ignored; 836 APRes.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); 837 ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEhalf()), APRes); 838 } 839 840 TEST(FixedPoint, FixedToFloat) { 841 int64_t Val = 0x1ULL; 842 CheckFixedToFloatConversion(Val, getSAccumSema(), 0.0078125f); 843 CheckFixedToFloatConversion(Val, getFractSema(), 0.000030517578125f); 844 CheckFixedToFloatConversion(Val, getAccumSema(), 0.000030517578125f); 845 CheckFixedToFloatConversion(Val, getLFractSema(), 846 0.0000000004656612873077392578125f); 847 848 CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.00390625f); 849 CheckFixedToFloatConversion(Val, getUFractSema(), 0.0000152587890625f); 850 CheckFixedToFloatConversion(Val, getUAccumSema(), 0.0000152587890625f); 851 CheckFixedToFloatConversion(Val, getULFractSema(), 852 0.00000000023283064365386962890625f); 853 854 Val = 0x7FULL; 855 CheckFixedToFloatConversion(Val, getSAccumSema(), 0.9921875f); 856 CheckFixedToFloatConversion(Val, getFractSema(), 0.003875732421875f); 857 CheckFixedToFloatConversion(Val, getAccumSema(), 0.003875732421875f); 858 CheckFixedToFloatConversion(Val, getLFractSema(), 859 0.0000000591389834880828857421875f); 860 861 CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.49609375f); 862 CheckFixedToFloatConversion(Val, getUFractSema(), 0.0019378662109375f); 863 CheckFixedToFloatConversion(Val, getUAccumSema(), 0.0019378662109375f); 864 CheckFixedToFloatConversion(Val, getULFractSema(), 865 0.00000002956949174404144287109375f); 866 867 Val = -0x1ULL; 868 CheckFixedToFloatConversion(Val, getSAccumSema(), -0.0078125f); 869 CheckFixedToFloatConversion(Val, getFractSema(), -0.000030517578125f); 870 CheckFixedToFloatConversion(Val, getAccumSema(), -0.000030517578125f); 871 CheckFixedToFloatConversion(Val, getLFractSema(), 872 -0.0000000004656612873077392578125f); 873 874 875 CheckFixedToFloatConversion(-0x80ULL, getSAccumSema(), -1.0f); 876 CheckFixedToFloatConversion(-0x8000ULL, getFractSema(), -1.0f); 877 CheckFixedToFloatConversion(-0x8000ULL, getAccumSema(), -1.0f); 878 CheckFixedToFloatConversion(-0x80000000ULL, getLFractSema(), -1.0f); 879 880 Val = 0xAFAULL; 881 CheckFixedToFloatConversion(Val, getSAccumSema(), 21.953125f); 882 CheckFixedToFloatConversion(Val, getFractSema(), 0.08575439453125f); 883 CheckFixedToFloatConversion(Val, getAccumSema(), 0.08575439453125f); 884 CheckFixedToFloatConversion(Val, getLFractSema(), 885 0.000001308508217334747314453125f); 886 887 CheckFixedToFloatConversion(Val, getUSAccumSema(), 10.9765625f); 888 CheckFixedToFloatConversion(Val, getUFractSema(), 0.042877197265625f); 889 CheckFixedToFloatConversion(Val, getUAccumSema(), 0.042877197265625f); 890 CheckFixedToFloatConversion(Val, getULFractSema(), 891 0.0000006542541086673736572265625f); 892 893 Val = -0xAFAULL; 894 CheckFixedToFloatConversion(Val, getSAccumSema(), -21.953125f); 895 CheckFixedToFloatConversion(Val, getFractSema(), -0.08575439453125f); 896 CheckFixedToFloatConversion(Val, getAccumSema(), -0.08575439453125f); 897 CheckFixedToFloatConversion(Val, getLFractSema(), 898 -0.000001308508217334747314453125f); 899 900 Val = 0x40000080ULL; 901 CheckFixedToFloatConversion(Val, getAccumSema(), 32768.00390625f); 902 CheckFixedToFloatConversion(Val, getLFractSema(), 903 0.500000059604644775390625f); 904 905 CheckFixedToFloatConversion(Val, getUAccumSema(), 16384.001953125f); 906 CheckFixedToFloatConversion(Val, getULFractSema(), 907 0.2500000298023223876953125f); 908 909 Val = 0x40000040ULL; 910 CheckFixedToFloatConversion(Val, getAccumSema(), 32768.0f); 911 CheckFixedToFloatConversion(Val, getLFractSema(), 0.5f); 912 913 CheckFixedToFloatConversion(Val, getUAccumSema(), 16384.0f); 914 CheckFixedToFloatConversion(Val, getULFractSema(), 0.25f); 915 916 Val = 0x7FF0ULL; 917 CheckFixedToHalfConversion(Val, getAccumSema(), 0.99951171875f); 918 CheckFixedToHalfConversion(Val, getLFractSema(), 0.000015251338481903076171875f); 919 920 CheckFixedToHalfConversion(Val, getUAccumSema(), 0.499755859375f); 921 CheckFixedToHalfConversion(Val, getULFractSema(), 0.0000076256692409515380859375f); 922 } 923 924 } // namespace 925