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