OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 | 2 |
3 #include "vm/bigint_operations.h" | 3 #include "vm/bigint_operations.h" |
4 | 4 |
5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
6 #include "platform/utils.h" | 6 #include "platform/utils.h" |
7 | 7 |
8 #include "vm/double_internals.h" | 8 #include "vm/double_internals.h" |
9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 value <<= kDigitBitSize; | 480 value <<= kDigitBitSize; |
481 value += static_cast<intptr_t>(bigint.GetChunkAt(i)); | 481 value += static_cast<intptr_t>(bigint.GetChunkAt(i)); |
482 } | 482 } |
483 if (bigint.IsNegative()) { | 483 if (bigint.IsNegative()) { |
484 value = -value; | 484 value = -value; |
485 } | 485 } |
486 return Smi::New(value); | 486 return Smi::New(value); |
487 } | 487 } |
488 | 488 |
489 | 489 |
| 490 static double Uint64ToDouble(uint64_t x) { |
| 491 #if _WIN64 |
| 492 // For static_cast<double>(x) MSVC x64 generates |
| 493 // |
| 494 // cvtsi2sd xmm0, rax |
| 495 // test rax, rax |
| 496 // jns done |
| 497 // addsd xmm0, static_cast<double>(2^64) |
| 498 // done: |
| 499 // |
| 500 // while GCC -m64 generates |
| 501 // |
| 502 // test rax, rax |
| 503 // js negative |
| 504 // cvtsi2sd xmm0, rax |
| 505 // jmp done |
| 506 // negative: |
| 507 // mov rdx, rax |
| 508 // shr rdx, 1 |
| 509 // and eax, 0x1 |
| 510 // or rdx, rax |
| 511 // cvtsi2sd xmm0, rdx |
| 512 // addsd xmm0, xmm0 |
| 513 // done: |
| 514 // |
| 515 // which results in a different rounding. |
| 516 // |
| 517 // For consistency between platforms fallback to GCC style converstion |
| 518 // on Win64. |
| 519 // |
| 520 const int64_t y = static_cast<int64_t>(x); |
| 521 if (y > 0) { |
| 522 return static_cast<double>(y); |
| 523 } else { |
| 524 const double half = static_cast<double>( |
| 525 static_cast<int64_t>(x >> 1) | (y & 1)); |
| 526 return half + half; |
| 527 } |
| 528 #else |
| 529 return static_cast<double>(x); |
| 530 #endif |
| 531 } |
| 532 |
| 533 |
490 RawDouble* BigintOperations::ToDouble(const Bigint& bigint) { | 534 RawDouble* BigintOperations::ToDouble(const Bigint& bigint) { |
491 ASSERT(IsClamped(bigint)); | 535 ASSERT(IsClamped(bigint)); |
492 if (bigint.IsZero()) { | 536 if (bigint.IsZero()) { |
493 return Double::New(0.0); | 537 return Double::New(0.0); |
494 } | 538 } |
495 if (AbsFitsIntoUint64(bigint)) { | 539 if (AbsFitsIntoUint64(bigint)) { |
496 double absolute_value = static_cast<double>(AbsToUint64(bigint)); | 540 double absolute_value = Uint64ToDouble(AbsToUint64(bigint)); |
497 double result = bigint.IsNegative() ? -absolute_value : absolute_value; | 541 double result = bigint.IsNegative() ? -absolute_value : absolute_value; |
498 return Double::New(result); | 542 return Double::New(result); |
499 } | 543 } |
500 | 544 |
501 static const int kPhysicalSignificandSize = 52; | 545 static const int kPhysicalSignificandSize = 52; |
502 // The significand size has an additional hidden bit. | 546 // The significand size has an additional hidden bit. |
503 static const int kSignificandSize = kPhysicalSignificandSize + 1; | 547 static const int kSignificandSize = kPhysicalSignificandSize + 1; |
504 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; | 548 static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; |
505 static const int kMaxExponent = 0x7FF - kExponentBias; | 549 static const int kMaxExponent = 0x7FF - kExponentBias; |
506 static const uint64_t kOne64 = 1; | 550 static const uint64_t kOne64 = 1; |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 intptr_t BigintOperations::CountBits(Chunk digit) { | 1858 intptr_t BigintOperations::CountBits(Chunk digit) { |
1815 intptr_t result = 0; | 1859 intptr_t result = 0; |
1816 while (digit != 0) { | 1860 while (digit != 0) { |
1817 digit >>= 1; | 1861 digit >>= 1; |
1818 result++; | 1862 result++; |
1819 } | 1863 } |
1820 return result; | 1864 return result; |
1821 } | 1865 } |
1822 | 1866 |
1823 } // namespace dart | 1867 } // namespace dart |
OLD | NEW |