sfp-machine.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* Decide whether to use 64 or 32-bit types to do the emulation. If we are
  2. doing IEEE-128 with VSX, use 64-bit emulation even if we are compiling for a
  3. 32-bit target. */
  4. #if defined(_ARCH_PPC64) || defined(__VSX__) || defined(__FLOAT128__)
  5. #define _FP_W_TYPE_SIZE 64
  6. #define _FP_W_TYPE unsigned long long
  7. #define _FP_WS_TYPE signed long long
  8. #define _FP_I_TYPE long long
  9. #ifdef _ARCH_PPC64
  10. typedef int TItype __attribute__ ((mode (TI)));
  11. typedef unsigned int UTItype __attribute__ ((mode (TI)));
  12. #define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
  13. #endif
  14. #else /* 32-bits */
  15. #define _FP_W_TYPE_SIZE 32
  16. #define _FP_W_TYPE unsigned int
  17. #define _FP_WS_TYPE signed int
  18. #define _FP_I_TYPE int
  19. #endif /* 32-bits */
  20. /* The type of the result of a floating point comparison. This must
  21. match `__libgcc_cmp_return__' in GCC for the target. */
  22. typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
  23. #define CMPtype __gcc_CMPtype
  24. #define _FP_MUL_MEAT_S(R,X,Y) \
  25. _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
  26. #if (_FP_W_TYPE_SIZE==64)
  27. #define _FP_MUL_MEAT_D(R,X,Y) \
  28. _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
  29. #define _FP_MUL_MEAT_Q(R,X,Y) \
  30. _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
  31. #else
  32. #define _FP_MUL_MEAT_D(R,X,Y) \
  33. _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
  34. #define _FP_MUL_MEAT_Q(R,X,Y) \
  35. _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
  36. #endif
  37. #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
  38. #if (_FP_W_TYPE_SIZE==64)
  39. #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
  40. #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
  41. #else
  42. #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
  43. #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
  44. #endif
  45. #define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
  46. #if (_FP_W_TYPE_SIZE==64)
  47. #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
  48. #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
  49. #else
  50. #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
  51. #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
  52. #endif
  53. #define _FP_NANSIGN_S 0
  54. #define _FP_NANSIGN_D 0
  55. #define _FP_NANSIGN_Q 0
  56. #define _FP_KEEPNANFRACP 1
  57. #define _FP_QNANNEGATEDP 0
  58. /* Someone please check this. */
  59. #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
  60. do { \
  61. if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
  62. && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
  63. { \
  64. R##_s = Y##_s; \
  65. _FP_FRAC_COPY_##wc(R,Y); \
  66. } \
  67. else \
  68. { \
  69. R##_s = X##_s; \
  70. _FP_FRAC_COPY_##wc(R,X); \
  71. } \
  72. R##_c = FP_CLS_NAN; \
  73. } while (0)
  74. #define _FP_TININESS_AFTER_ROUNDING 0
  75. #define __LITTLE_ENDIAN 1234
  76. #define __BIG_ENDIAN 4321
  77. #if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
  78. # if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
  79. # error "Both BIG_ENDIAN and LITTLE_ENDIAN defined!"
  80. # endif
  81. # define __BYTE_ORDER __BIG_ENDIAN
  82. #else
  83. # if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
  84. # define __BYTE_ORDER __LITTLE_ENDIAN
  85. # else
  86. # error "Cannot determine current byte order"
  87. # endif
  88. #endif
  89. /* Only provide exception support if we have hardware floating point using
  90. floating point registers and we can execute the mtfsf instruction. This
  91. would only be true if we are using the emulation routines for IEEE 128-bit
  92. floating point on pre-ISA 3.0 machines without the IEEE 128-bit floating
  93. point support. */
  94. #ifdef __FLOAT128__
  95. #define ISA_BIT(x) (1LL << (63 - x))
  96. /* Use the same bits of the FPSCR. */
  97. # define FP_EX_INVALID ISA_BIT(34)
  98. # define FP_EX_OVERFLOW ISA_BIT(35)
  99. # define FP_EX_UNDERFLOW ISA_BIT(36)
  100. # define FP_EX_DIVZERO ISA_BIT(37)
  101. # define FP_EX_INEXACT ISA_BIT(38)
  102. # define FP_EX_ALL (FP_EX_INVALID | FP_EX_OVERFLOW \
  103. | FP_EX_UNDERFLOW | FP_EX_DIVZERO \
  104. | FP_EX_INEXACT)
  105. void __sfp_handle_exceptions (int);
  106. # define FP_HANDLE_EXCEPTIONS \
  107. do { \
  108. if (__builtin_expect (_fex, 0)) \
  109. __sfp_handle_exceptions (_fex); \
  110. } while (0)
  111. /* The FP_EX_* bits track whether the exception has occurred. This macro
  112. must set the FP_EX_* bits of those exceptions which are configured to
  113. trap. The FPSCR bit which indicates this is 22 ISA bits above the
  114. respective FP_EX_* bit. Note, the ISA labels bits from msb to lsb,
  115. so 22 ISA bits above is 22 bits below when counted from the lsb. */
  116. # define FP_TRAPPING_EXCEPTIONS ((_fpscr.i << 22) & FP_EX_ALL)
  117. # define FP_RND_NEAREST 0x0
  118. # define FP_RND_ZERO 0x1
  119. # define FP_RND_PINF 0x2
  120. # define FP_RND_MINF 0x3
  121. # define FP_RND_MASK 0x3
  122. # define _FP_DECL_EX \
  123. union { unsigned long long i; double d; } _fpscr __attribute__ ((unused)) = \
  124. { .i = FP_RND_NEAREST }
  125. #define FP_INIT_ROUNDMODE \
  126. do { \
  127. __asm__ __volatile__ ("mffs %0" \
  128. : "=f" (_fpscr.d)); \
  129. } while (0)
  130. # define FP_ROUNDMODE (_fpscr.i & FP_RND_MASK)
  131. #endif /* !__FLOAT128__ */
  132. /* Define ALIASNAME as a strong alias for NAME. */
  133. # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
  134. # define _strong_alias(name, aliasname) \
  135. extern __typeof (name) aliasname __attribute__ ((alias (#name)));