10b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 20b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 30b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 40b57cec5SDimitry Andric 50b57cec5SDimitry Andric // long double __floatditf(long long x); 60b57cec5SDimitry Andric // This file implements the PowerPC long long -> long double conversion 70b57cec5SDimitry Andric 80b57cec5SDimitry Andric #include "DD.h" 90b57cec5SDimitry Andric __floatditf(int64_t a)100b57cec5SDimitry Andriclong double __floatditf(int64_t a) { 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric static const double twop32 = 0x1.0p32; 130b57cec5SDimitry Andric static const double twop52 = 0x1.0p52; 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric doublebits low = {.d = twop52}; 160b57cec5SDimitry Andric low.x |= a & UINT64_C(0x00000000ffffffff); // 0x1.0p52 + low 32 bits of a. 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric const double high_addend = (double)((int32_t)(a >> 32)) * twop32 - twop52; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric // At this point, we have two double precision numbers 210b57cec5SDimitry Andric // high_addend and low.d, and we wish to return their sum 220b57cec5SDimitry Andric // as a canonicalized long double: 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // This implementation sets the inexact flag spuriously. 250b57cec5SDimitry Andric // This could be avoided, but at some substantial cost. 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric DD result; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric result.s.hi = high_addend + low.d; 300b57cec5SDimitry Andric result.s.lo = (high_addend - result.s.hi) + low.d; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric return result.ld; 330b57cec5SDimitry Andric } 34