floattisf.c revision 37a6a455466e5b197311771a777ab241e471ed8a
137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- floattisf.c - Implement __floattisf -------------------------------=== 237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * The LLVM Compiler Infrastructure 437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file is distributed under the University of Illinois Open Source 637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * License. See LICENSE.TXT for details. 737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file implements __floattisf for the compiler_rt library. 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#if __x86_64 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include <float.h> 19b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Returns: convert a to a float, rounding toward even. */ 21b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Assumption: float is a IEEE 32 bit floating point type 2337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ti_int is a 128 bit integral type 2437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ 27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarsi_int __clzti2(ti_int a); 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarfloat 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__floattisf(ti_int a) 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == 0) 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0.0F; 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned N = sizeof(ti_int) * CHAR_BIT; 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const ti_int s = a >> (N-1); 37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a = (a ^ s) - s; 3837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan int sd = N - __clzti2(a); /* number of significant digits */ 3937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan int e = sd - 1; /* exponent */ 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sd > FLT_MANT_DIG) 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 4237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 4337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 4437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 12345678901234567890123456 4537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1 = msb 1 bit 4637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * P = bit FLT_MANT_DIG-1 bits to the right of 1 4737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * Q = bit FLT_MANT_DIG bits to the right of 1 4837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * R = "or" of all bits to the right of Q 4937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar switch (sd) 51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case FLT_MANT_DIG + 1: 53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= 1; 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case FLT_MANT_DIG + 2: 56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 57b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar default: 58b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) | 59b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0); 60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar }; 6137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* finish: */ 6237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan a |= (a & 4) != 0; /* Or P into R */ 6337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan ++a; /* round - this step may add a significant bit */ 6437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan a >>= 2; /* dump Q and R */ 6537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ 66b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a & ((tu_int)1 << FLT_MANT_DIG)) 67b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 68b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a >>= 1; 69b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ++e; 70b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 7137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* a is now rounded to FLT_MANT_DIG bits */ 72b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 73b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 74b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 75b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= (FLT_MANT_DIG - sd); 7637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* a is now rounded to FLT_MANT_DIG bits */ 77b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 78b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar float_bits fb; 7937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan fb.u = ((su_int)s & 0x80000000) | /* sign */ 8037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan ((e + 127) << 23) | /* exponent */ 8137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan ((su_int)a & 0x007FFFFF); /* mantissa */ 82b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return fb.f; 83b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 84b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 85b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#endif 86