13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 26ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Redistribution and use in source and binary forms, with or without 36ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// modification, are permitted provided that the following conditions are 46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// met: 56ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// 66ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Redistributions of source code must retain the above copyright 76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// notice, this list of conditions and the following disclaimer. 86ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Redistributions in binary form must reproduce the above 96ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// copyright notice, this list of conditions and the following 106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// disclaimer in the documentation and/or other materials provided 116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// with the distribution. 126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Neither the name of Google Inc. nor the names of its 136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// contributors may be used to endorse or promote products derived 146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// from this software without specific prior written permission. 156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// 166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_DIY_FP_H_ 296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define V8_DIY_FP_H_ 306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 { 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal { 336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// This "Do It Yourself Floating Point" class implements a floating-point number 356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// with a uint64 significand and an int exponent. Normalized DiyFp numbers will 366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// have the most significant bit of the significand set. 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Multiplication and Subtraction do not normalize their results. 386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// DiyFp are not designed to contain special doubles (NaN and Infinity). 396ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass DiyFp { 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const int kSignificandSize = 64; 426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DiyFp() : f_(0), e_(0) {} 446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DiyFp(uint64_t f, int e) : f_(f), e_(e) {} 456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // this = this - other. 476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The exponents of both numbers must be the same and the significand of this 486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // must be bigger than the significand of other. 496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The result will not be normalized. 506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Subtract(const DiyFp& other) { 516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(e_ == other.e_); 526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(f_ >= other.f_); 536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block f_ -= other.f_; 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Returns a - b. 576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The exponents of both numbers must be the same and this must be bigger 586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // than other. The result will not be normalized. 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static DiyFp Minus(const DiyFp& a, const DiyFp& b) { 606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DiyFp result = a; 616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result.Subtract(b); 626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // this = this * other. 676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Multiply(const DiyFp& other); 686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // returns a * b; 706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static DiyFp Times(const DiyFp& a, const DiyFp& b) { 716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DiyFp result = a; 726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result.Multiply(b); 736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Normalize() { 776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(f_ != 0); 786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint64_t f = f_; 796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int e = e_; 806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // This method is mainly called for normalizing boundaries. In general 826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // boundaries need to be shifted by 10 bits. We thus optimize for this case. 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const uint64_t k10MSBits = static_cast<uint64_t>(0x3FF) << 54; 846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while ((f & k10MSBits) == 0) { 856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block f <<= 10; 866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block e -= 10; 876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while ((f & kUint64MSB) == 0) { 896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block f <<= 1; 906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block e--; 916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block f_ = f; 936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block e_ = e; 946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static DiyFp Normalize(const DiyFp& a) { 976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DiyFp result = a; 986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block result.Normalize(); 996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint64_t f() const { return f_; } 1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int e() const { return e_; } 1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void set_f(uint64_t new_value) { f_ = new_value; } 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void set_e(int new_value) { e_ = new_value; } 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const uint64_t kUint64MSB = static_cast<uint64_t>(1) << 63; 1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint64_t f_; 1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int e_; 1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} } // namespace v8::internal 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_DIY_FP_H_ 118