10b57cec5SDimitry Andric //===-- lib/floatditf.c - integer -> quad-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 di_int to quad-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 QUAD_PRECISION 160b57cec5SDimitry Andric #include "fp_lib.h" 170b57cec5SDimitry Andric 18*06c3fb27SDimitry Andric #if defined(CRT_HAS_TF_MODE) __floatditf(di_int a)190b57cec5SDimitry AndricCOMPILER_RT_ABI fp_t __floatditf(di_int a) { 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric const int aWidth = sizeof a * CHAR_BIT; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric // Handle zero as a special case to protect clz 240b57cec5SDimitry Andric if (a == 0) 250b57cec5SDimitry Andric return fromRep(0); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric // All other cases begin by extracting the sign and absolute value of a 280b57cec5SDimitry Andric rep_t sign = 0; 290b57cec5SDimitry Andric du_int aAbs = (du_int)a; 300b57cec5SDimitry Andric if (a < 0) { 310b57cec5SDimitry Andric sign = signBit; 320b57cec5SDimitry Andric aAbs = ~(du_int)a + 1U; 330b57cec5SDimitry Andric } 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric // Exponent of (fp_t)a is the width of abs(a). 360b57cec5SDimitry Andric const int exponent = (aWidth - 1) - __builtin_clzll(aAbs); 370b57cec5SDimitry Andric rep_t result; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // Shift a into the significand field, rounding if it is a right-shift 400b57cec5SDimitry Andric const int shift = significandBits - exponent; 410b57cec5SDimitry Andric result = (rep_t)aAbs << shift ^ implicitBit; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Insert the exponent 440b57cec5SDimitry Andric result += (rep_t)(exponent + exponentBias) << significandBits; 450b57cec5SDimitry Andric // Insert the sign bit and return 460b57cec5SDimitry Andric return fromRep(result | sign); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #endif 50