// Copyright 2018 Ulf Adams // // The contents of this file may be used under the terms of the Apache License, // Version 2.0. // // (See accompanying file LICENSE-Apache or copy at // http://www.apache.org/licenses/LICENSE-2.0) // // Alternatively, the contents of this file may be used under the terms of // the Boost Software License, Version 1.0. // (See accompanying file LICENSE-Boost or copy at // https://www.boost.org/LICENSE_1_0.txt) // // Unless required by applicable law or agreed to in writing, this software // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. #include #include "ryu/common.h" #include "ryu/d2s_intrinsics.h" #if !defined(HAS_64_BIT_INTRINSICS) uint64_t __umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { // The casts here help MSVC to avoid calls to the __allmul library function. const uint32_t aLo = (uint32_t)a; const uint32_t aHi = (uint32_t)(a >> 32); const uint32_t bLo = (uint32_t)b; const uint32_t bHi = (uint32_t)(b >> 32); const uint64_t b00 = (uint64_t)aLo * bLo; const uint64_t b01 = (uint64_t)aLo * bHi; const uint64_t b10 = (uint64_t)aHi * bLo; const uint64_t b11 = (uint64_t)aHi * bHi; const uint32_t b00Lo = (uint32_t)b00; const uint32_t b00Hi = (uint32_t)(b00 >> 32); const uint64_t mid1 = b10 + b00Hi; const uint32_t mid1Lo = (uint32_t)(mid1); const uint32_t mid1Hi = (uint32_t)(mid1 >> 32); const uint64_t mid2 = b01 + mid1Lo; const uint32_t mid2Lo = (uint32_t)(mid2); const uint32_t mid2Hi = (uint32_t)(mid2 >> 32); const uint64_t pHi = b11 + mid1Hi + mid2Hi; const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo; *productHi = pHi; return pLo; } // Returns the lower 64 bits of (hi*2^64 + lo) >> dist, with 0 < dist < 64. uint64_t __shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { // We don't need to handle the case dist >= 64 here (see above). assert(dist < 64); assert(dist > 0); return (hi << (64 - dist)) | (lo >> dist); } #endif