FPTruncateMode.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /* Copyright 2001-4 tim goetze <tim@quitte.de> -- see 'COPYING'. */
  2. /* Sets the FP rounding mode to 'truncate' in the constructor
  3. * and loads the previous FP conrol word in the destructor.
  4. *
  5. * By directly using the machine instruction to convert float to int
  6. * we avoid the performance hit that loading the control word twice for
  7. * every (int) cast causes on i386.
  8. *
  9. * On other architectures this is a no-op.
  10. */
  11. #ifndef _DSP_FP_TRUNCATE_MODE_H_
  12. #define _DSP_FP_TRUNCATE_MODE_H_
  13. #ifdef __i386__
  14. #define fstcw(i) \
  15. __asm__ __volatile__ ("fstcw %0" : "=m" (i))
  16. #define fldcw(i) \
  17. __asm__ __volatile__ ("fldcw %0" : : "m" (i))
  18. /* gcc chokes on __volatile__ sometimes. */
  19. #define fistp(f,i) \
  20. __asm__ ("fistpl %0" : "=m" (i) : "t" (f) : "st")
  21. #else /* ! __i386__ */
  22. #include <cstdint>
  23. inline void fistp(float f, int32_t& i) { i = static_cast<int32_t>(f); }
  24. #endif
  25. namespace DSP {
  26. class FPTruncateMode
  27. {
  28. public:
  29. #ifdef __i386__
  30. int cw0; /* fp control word */
  31. FPTruncateMode()
  32. {
  33. fstcw (cw0);
  34. const int cw1 = cw0 | 0xC00;
  35. fldcw (cw1);
  36. }
  37. ~FPTruncateMode()
  38. {
  39. fldcw (cw0);
  40. }
  41. #else
  42. // Avoid warnings about unused variables
  43. FPTruncateMode() { (void)0; }
  44. ~FPTruncateMode() { (void)0; }
  45. #endif
  46. };
  47. } /* namespace DSP */
  48. #endif /* _DSP_FP_TRUNCATE_MODE_H_ */