137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- floatundixf.c - Implement __floatundixf ---------------------------=== 237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * The LLVM Compiler Infrastructure 437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 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. 737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file implements __floatundixf for the compiler_rt library. 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#if !_ARCH_PPC 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Returns: convert a to a long double, rounding toward even. */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits 2237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * du_int is a 64 bit integral type 2337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | 2637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm 2737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI long double 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__floatundixf(du_int a) 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == 0) 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0.0; 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned N = sizeof(du_int) * CHAR_BIT; 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar int clz = __builtin_clzll(a); 3537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan int e = (N - 1) - clz ; /* exponent */ 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar long_double_bits fb; 378bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan fb.u.high.s.low = (e + 16383); /* exponent */ 3837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan fb.u.low.all = a << clz; /* mantissa */ 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return fb.f; 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 4237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan#endif /* _ARCH_PPC */ 43