fixunsxfti.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /* ===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------===
  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 __fixunsxfti for the compiler_rt library.
  11. *
  12. * ===----------------------------------------------------------------------===
  13. */
  14. #include "int_lib.h"
  15. #ifdef CRT_HAS_128BIT
  16. /* Returns: convert a to a unsigned long long, rounding toward zero.
  17. * Negative values all become zero.
  18. */
  19. /* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
  20. * tu_int is a 128 bit integral type
  21. * value in long double is representable in tu_int or is negative
  22. */
  23. /* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
  24. * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
  25. */
  26. COMPILER_RT_ABI tu_int
  27. __fixunsxfti(long double a)
  28. {
  29. long_double_bits fb;
  30. fb.f = a;
  31. int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
  32. if (e < 0 || (fb.u.high.s.low & 0x00008000))
  33. return 0;
  34. if ((unsigned)e > sizeof(tu_int) * CHAR_BIT)
  35. return ~(tu_int)0;
  36. tu_int r = fb.u.low.all;
  37. if (e > 63)
  38. r <<= (e - 63);
  39. else
  40. r >>= (63 - e);
  41. return r;
  42. }
  43. #endif /* CRT_HAS_128BIT */