1*480093f4SDimitry Andric //===--- lib/builtins/ppc/fixtfti.c - Convert long double->int128 *-C -*---===// 2*480093f4SDimitry Andric // 3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*480093f4SDimitry Andric // 7*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8*480093f4SDimitry Andric // 9*480093f4SDimitry Andric // This file implements converting the 128bit IBM/PowerPC long double (double- 10*480093f4SDimitry Andric // double) data type to a signed 128 bit integer. 11*480093f4SDimitry Andric // 12*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13*480093f4SDimitry Andric 14*480093f4SDimitry Andric #include "../int_math.h" 15*480093f4SDimitry Andric 16*480093f4SDimitry Andric // Convert long double into a signed 128-bit integer. __fixtfti(long double input)17*480093f4SDimitry Andric__int128_t __fixtfti(long double input) { 18*480093f4SDimitry Andric 19*480093f4SDimitry Andric // If we are trying to convert a NaN, return the NaN bit pattern. 20*480093f4SDimitry Andric if (crt_isnan(input)) { 21*480093f4SDimitry Andric return ((__uint128_t)0x7FF8000000000000ll) << 64 | 22*480093f4SDimitry Andric (__uint128_t)0x0000000000000000ll; 23*480093f4SDimitry Andric } 24*480093f4SDimitry Andric 25*480093f4SDimitry Andric // Note: overflow is an undefined behavior for this conversion. 26*480093f4SDimitry Andric // For this reason, overflow is not checked here. 27*480093f4SDimitry Andric 28*480093f4SDimitry Andric // If the long double is negative, use unsigned conversion from its absolute 29*480093f4SDimitry Andric // value. 30*480093f4SDimitry Andric if (input < 0.0) { 31*480093f4SDimitry Andric __uint128_t result = (__uint128_t)(-input); 32*480093f4SDimitry Andric return -((__int128_t)result); 33*480093f4SDimitry Andric } 34*480093f4SDimitry Andric 35*480093f4SDimitry Andric // Otherwise, use unsigned conversion from the input value. 36*480093f4SDimitry Andric __uint128_t result = (__uint128_t)input; 37*480093f4SDimitry Andric return result; 38*480093f4SDimitry Andric } 39