fp_fixint_impl.inc 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
  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 float to integer conversion for the
  11. // compiler-rt library.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "fp_lib.h"
  15. static __inline fixint_t __fixint(fp_t a) {
  16. const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
  17. const fixint_t fixint_min = -fixint_max - 1;
  18. // Break a into sign, exponent, significand
  19. const rep_t aRep = toRep(a);
  20. const rep_t aAbs = aRep & absMask;
  21. const fixint_t sign = aRep & signBit ? -1 : 1;
  22. const int exponent = (aAbs >> significandBits) - exponentBias;
  23. const rep_t significand = (aAbs & significandMask) | implicitBit;
  24. // If exponent is negative, the result is zero.
  25. if (exponent < 0)
  26. return 0;
  27. // If the value is too large for the integer type, saturate.
  28. if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)
  29. return sign == 1 ? fixint_max : fixint_min;
  30. // If 0 <= exponent < significandBits, right shift to get the result.
  31. // Otherwise, shift left.
  32. if (exponent < significandBits)
  33. return sign * (significand >> (significandBits - exponent));
  34. else
  35. return sign * ((fixint_t)significand << (exponent - significandBits));
  36. }