13cab2bb3Spatrick //===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick // 93cab2bb3Spatrick // This file implements integer to single-precision conversion for the 103cab2bb3Spatrick // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 113cab2bb3Spatrick // mode. 123cab2bb3Spatrick // 133cab2bb3Spatrick //===----------------------------------------------------------------------===// 143cab2bb3Spatrick 153cab2bb3Spatrick #define SINGLE_PRECISION 163cab2bb3Spatrick #include "fp_lib.h" 173cab2bb3Spatrick 183cab2bb3Spatrick #include "int_lib.h" 193cab2bb3Spatrick __floatsisf(si_int a)20*810390e3SrobertCOMPILER_RT_ABI fp_t __floatsisf(si_int a) { 213cab2bb3Spatrick 223cab2bb3Spatrick const int aWidth = sizeof a * CHAR_BIT; 233cab2bb3Spatrick 243cab2bb3Spatrick // Handle zero as a special case to protect clz 253cab2bb3Spatrick if (a == 0) 263cab2bb3Spatrick return fromRep(0); 273cab2bb3Spatrick 283cab2bb3Spatrick // All other cases begin by extracting the sign and absolute value of a 293cab2bb3Spatrick rep_t sign = 0; 303cab2bb3Spatrick if (a < 0) { 313cab2bb3Spatrick sign = signBit; 323cab2bb3Spatrick a = -a; 333cab2bb3Spatrick } 343cab2bb3Spatrick 353cab2bb3Spatrick // Exponent of (fp_t)a is the width of abs(a). 36*810390e3Srobert const int exponent = (aWidth - 1) - clzsi(a); 373cab2bb3Spatrick rep_t result; 383cab2bb3Spatrick 393cab2bb3Spatrick // Shift a into the significand field, rounding if it is a right-shift 403cab2bb3Spatrick if (exponent <= significandBits) { 413cab2bb3Spatrick const int shift = significandBits - exponent; 423cab2bb3Spatrick result = (rep_t)a << shift ^ implicitBit; 433cab2bb3Spatrick } else { 443cab2bb3Spatrick const int shift = exponent - significandBits; 453cab2bb3Spatrick result = (rep_t)a >> shift ^ implicitBit; 463cab2bb3Spatrick rep_t round = (rep_t)a << (typeWidth - shift); 473cab2bb3Spatrick if (round > signBit) 483cab2bb3Spatrick result++; 493cab2bb3Spatrick if (round == signBit) 503cab2bb3Spatrick result += result & 1; 513cab2bb3Spatrick } 523cab2bb3Spatrick 533cab2bb3Spatrick // Insert the exponent 543cab2bb3Spatrick result += (rep_t)(exponent + exponentBias) << significandBits; 553cab2bb3Spatrick // Insert the sign bit and return 563cab2bb3Spatrick return fromRep(result | sign); 573cab2bb3Spatrick } 583cab2bb3Spatrick 593cab2bb3Spatrick #if defined(__ARM_EABI__) 603cab2bb3Spatrick #if defined(COMPILER_RT_ARMHF_TARGET) __aeabi_i2f(int a)613cab2bb3SpatrickAEABI_RTABI fp_t __aeabi_i2f(int a) { return __floatsisf(a); } 623cab2bb3Spatrick #else 633cab2bb3Spatrick COMPILER_RT_ALIAS(__floatsisf, __aeabi_i2f) 643cab2bb3Spatrick #endif 653cab2bb3Spatrick #endif 66