floatsisf.c revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// 209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// The LLVM Compiler Infrastructure 409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon//===----------------------------------------------------------------------===// 909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 1009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// This file implements integer to single-precision conversion for the 1109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 1209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// mode. 1309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 1409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon//===----------------------------------------------------------------------===// 1509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 1609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon#define SINGLE_PRECISION 1709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon#include "fp_lib.h" 1809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 1937b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov#include "int_lib.h" 2037b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 210193b74976719b8aea4cb8874ba36b75836a8d6eChandler CarruthARM_EABI_FNALIAS(i2f, floatsisf) 2237b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI fp_t 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__floatsisf(int a) { 2509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 2609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int aWidth = sizeof a * CHAR_BIT; 2709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 2809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Handle zero as a special case to protect clz 2909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (a == 0) 3009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon return fromRep(0); 3109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 3209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // All other cases begin by extracting the sign and absolute value of a 3309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon rep_t sign = 0; 3409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (a < 0) { 3509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon sign = signBit; 3609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon a = -a; 3709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon } 3809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 3909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Exponent of (fp_t)a is the width of abs(a). 4009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int exponent = (aWidth - 1) - __builtin_clz(a); 4109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon rep_t result; 4209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 4309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Shift a into the significand field, rounding if it is a right-shift 4409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (exponent <= significandBits) { 4509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int shift = significandBits - exponent; 4609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result = (rep_t)a << shift ^ implicitBit; 4709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon } else { 4809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int shift = exponent - significandBits; 4909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result = (rep_t)a >> shift ^ implicitBit; 5009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon rep_t round = (rep_t)a << (typeWidth - shift); 5109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (round > signBit) result++; 5209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (round == signBit) result += result & 1; 5309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon } 5409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 5509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Insert the exponent 5609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result += (rep_t)(exponent + exponentBias) << significandBits; 5709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Insert the sign bit and return 5809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon return fromRep(result | sign); 5909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon} 60