10b57cec5SDimitry Andric //===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements integer to double-precision conversion for the 100b57cec5SDimitry Andric // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 110b57cec5SDimitry Andric // mode. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #define DOUBLE_PRECISION 160b57cec5SDimitry Andric #include "fp_lib.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "int_lib.h" 190b57cec5SDimitry Andric 205ffd83dbSDimitry Andric COMPILER_RT_ABI fp_t __floatsidf(si_int a) { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric const int aWidth = sizeof a * CHAR_BIT; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // Handle zero as a special case to protect clz 250b57cec5SDimitry Andric if (a == 0) 260b57cec5SDimitry Andric return fromRep(0); 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // All other cases begin by extracting the sign and absolute value of a 290b57cec5SDimitry Andric rep_t sign = 0; 30*5f757f3fSDimitry Andric su_int aAbs = (su_int)a; 310b57cec5SDimitry Andric if (a < 0) { 320b57cec5SDimitry Andric sign = signBit; 33*5f757f3fSDimitry Andric aAbs = -aAbs; 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric // Exponent of (fp_t)a is the width of abs(a). 37*5f757f3fSDimitry Andric const int exponent = (aWidth - 1) - clzsi(aAbs); 380b57cec5SDimitry Andric rep_t result; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // Shift a into the significand field and clear the implicit bit. Extra 410b57cec5SDimitry Andric // cast to unsigned int is necessary to get the correct behavior for 420b57cec5SDimitry Andric // the input INT_MIN. 430b57cec5SDimitry Andric const int shift = significandBits - exponent; 44*5f757f3fSDimitry Andric result = (rep_t)aAbs << shift ^ implicitBit; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // Insert the exponent 470b57cec5SDimitry Andric result += (rep_t)(exponent + exponentBias) << significandBits; 480b57cec5SDimitry Andric // Insert the sign bit and return 490b57cec5SDimitry Andric return fromRep(result | sign); 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric #if defined(__ARM_EABI__) 530b57cec5SDimitry Andric #if defined(COMPILER_RT_ARMHF_TARGET) 545ffd83dbSDimitry Andric AEABI_RTABI fp_t __aeabi_i2d(si_int a) { return __floatsidf(a); } 550b57cec5SDimitry Andric #else 560b57cec5SDimitry Andric COMPILER_RT_ALIAS(__floatsidf, __aeabi_i2d) 570b57cec5SDimitry Andric #endif 580b57cec5SDimitry Andric #endif 59