soft-fp.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #ifndef SOFT_FP_H
  2. #define SOFT_FP_H
  3. #include "sfp-machine.h"
  4. #define _FP_WORKBITS 3
  5. #define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
  6. #define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
  7. #define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1)
  8. #define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0)
  9. #ifndef FP_RND_NEAREST
  10. # define FP_RND_NEAREST 0
  11. # define FP_RND_ZERO 1
  12. # define FP_RND_PINF 2
  13. # define FP_RND_MINF 3
  14. #ifndef FP_ROUNDMODE
  15. # define FP_ROUNDMODE FP_RND_NEAREST
  16. #endif
  17. #endif
  18. #define _FP_ROUND_NEAREST(wc, X) \
  19. ({ int __ret = 0; \
  20. int __frac = _FP_FRAC_LOW_##wc(X) & 15; \
  21. if (__frac & 7) { \
  22. __ret = EFLAG_INEXACT; \
  23. if ((__frac & 7) != _FP_WORK_ROUND) \
  24. _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
  25. else if (__frac & _FP_WORK_LSB) \
  26. _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
  27. } \
  28. __ret; \
  29. })
  30. #define _FP_ROUND_ZERO(wc, X) \
  31. ({ int __ret = 0; \
  32. if (_FP_FRAC_LOW_##wc(X) & 7) \
  33. __ret = EFLAG_INEXACT; \
  34. __ret; \
  35. })
  36. #define _FP_ROUND_PINF(wc, X) \
  37. ({ int __ret = EFLAG_INEXACT; \
  38. if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
  39. _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
  40. else __ret = 0; \
  41. __ret; \
  42. })
  43. #define _FP_ROUND_MINF(wc, X) \
  44. ({ int __ret = EFLAG_INEXACT; \
  45. if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
  46. _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
  47. else __ret = 0; \
  48. __ret; \
  49. })
  50. #define _FP_ROUND(wc, X) \
  51. ({ int __ret = 0; \
  52. switch (FP_ROUNDMODE) \
  53. { \
  54. case FP_RND_NEAREST: \
  55. __ret |= _FP_ROUND_NEAREST(wc,X); \
  56. break; \
  57. case FP_RND_ZERO: \
  58. __ret |= _FP_ROUND_ZERO(wc,X); \
  59. break; \
  60. case FP_RND_PINF: \
  61. __ret |= _FP_ROUND_PINF(wc,X); \
  62. break; \
  63. case FP_RND_MINF: \
  64. __ret |= _FP_ROUND_MINF(wc,X); \
  65. break; \
  66. }; \
  67. __ret; \
  68. })
  69. #define FP_CLS_NORMAL 0
  70. #define FP_CLS_ZERO 1
  71. #define FP_CLS_INF 2
  72. #define FP_CLS_NAN 3
  73. #define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y))
  74. #include "op-1.h"
  75. #include "op-2.h"
  76. #include "op-4.h"
  77. #include "op-common.h"
  78. /* Sigh. Silly things longlong.h needs. */
  79. #define UWtype _FP_W_TYPE
  80. #define W_TYPE_SIZE _FP_W_TYPE_SIZE
  81. typedef int SItype __attribute__((mode(SI)));
  82. typedef int DItype __attribute__((mode(DI)));
  83. typedef unsigned int USItype __attribute__((mode(SI)));
  84. typedef unsigned int UDItype __attribute__((mode(DI)));
  85. #if _FP_W_TYPE_SIZE == 32
  86. typedef unsigned int UHWtype __attribute__((mode(HI)));
  87. #elif _FP_W_TYPE_SIZE == 64
  88. typedef USItype UHWtype;
  89. #endif
  90. #endif