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 | |
Ivan Posva
2014/06/05 17:42:11
Alternatively we could avoid the ifdef and just do
Vyacheslav Egorov (Google)
2014/06/05 18:05:55
I will ifdef for now because right now all other p
| |
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 |