floattixf.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* ===-- floattixf.c - Implement __floattixf -------------------------------===
  2. *
  3. * The LLVM Compiler Infrastructure
  4. *
  5. * This file is dual licensed under the MIT and the University of Illinois Open
  6. * Source Licenses. See LICENSE.TXT for details.
  7. *
  8. * ===----------------------------------------------------------------------===
  9. *
  10. * This file implements __floattixf for the compiler_rt library.
  11. *
  12. * ===----------------------------------------------------------------------===
  13. */
  14. #include "int_lib.h"
  15. #ifdef CRT_HAS_128BIT
  16. /* Returns: convert a to a long double, rounding toward even. */
  17. /* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits
  18. * ti_int is a 128 bit integral type
  19. */
  20. /* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
  21. * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
  22. */
  23. COMPILER_RT_ABI long double
  24. __floattixf(ti_int a)
  25. {
  26. if (a == 0)
  27. return 0.0;
  28. const unsigned N = sizeof(ti_int) * CHAR_BIT;
  29. const ti_int s = a >> (N-1);
  30. a = (a ^ s) - s;
  31. int sd = N - __clzti2(a); /* number of significant digits */
  32. int e = sd - 1; /* exponent */
  33. if (sd > LDBL_MANT_DIG)
  34. {
  35. /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
  36. * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
  37. * 12345678901234567890123456
  38. * 1 = msb 1 bit
  39. * P = bit LDBL_MANT_DIG-1 bits to the right of 1
  40. * Q = bit LDBL_MANT_DIG bits to the right of 1
  41. * R = "or" of all bits to the right of Q
  42. */
  43. switch (sd)
  44. {
  45. case LDBL_MANT_DIG + 1:
  46. a <<= 1;
  47. break;
  48. case LDBL_MANT_DIG + 2:
  49. break;
  50. default:
  51. a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |
  52. ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);
  53. };
  54. /* finish: */
  55. a |= (a & 4) != 0; /* Or P into R */
  56. ++a; /* round - this step may add a significant bit */
  57. a >>= 2; /* dump Q and R */
  58. /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */
  59. if (a & ((tu_int)1 << LDBL_MANT_DIG))
  60. {
  61. a >>= 1;
  62. ++e;
  63. }
  64. /* a is now rounded to LDBL_MANT_DIG bits */
  65. }
  66. else
  67. {
  68. a <<= (LDBL_MANT_DIG - sd);
  69. /* a is now rounded to LDBL_MANT_DIG bits */
  70. }
  71. long_double_bits fb;
  72. fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */
  73. (e + 16383); /* exponent */
  74. fb.u.low.all = (du_int)a; /* mantissa */
  75. return fb.f;
  76. }
  77. #endif /* CRT_HAS_128BIT */