sfp-machine.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Configure soft-fp for building sqrtf128. Based on sfp-machine.h in
  2. libgcc, with soft-float and other irrelevant parts removed. */
  3. /* The type of the result of a floating point comparison. This must
  4. match `__libgcc_cmp_return__' in GCC for the target. */
  5. typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
  6. #define CMPtype __gcc_CMPtype
  7. #ifdef __x86_64__
  8. # define _FP_W_TYPE_SIZE 64
  9. # define _FP_W_TYPE unsigned long long
  10. # define _FP_WS_TYPE signed long long
  11. # define _FP_I_TYPE long long
  12. typedef int TItype __attribute__ ((mode (TI)));
  13. typedef unsigned int UTItype __attribute__ ((mode (TI)));
  14. # define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
  15. # define _FP_MUL_MEAT_Q(R,X,Y) \
  16. _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
  17. # define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
  18. # define _FP_NANFRAC_S _FP_QNANBIT_S
  19. # define _FP_NANFRAC_D _FP_QNANBIT_D
  20. # define _FP_NANFRAC_E _FP_QNANBIT_E, 0
  21. # define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
  22. # define FP_EX_SHIFT 7
  23. # define _FP_DECL_EX \
  24. unsigned int _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
  25. # define FP_RND_NEAREST 0
  26. # define FP_RND_ZERO 0x6000
  27. # define FP_RND_PINF 0x4000
  28. # define FP_RND_MINF 0x2000
  29. # define FP_RND_MASK 0x6000
  30. # define FP_INIT_ROUNDMODE \
  31. do { \
  32. __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_fcw)); \
  33. } while (0)
  34. #else
  35. # define _FP_W_TYPE_SIZE 32
  36. # define _FP_W_TYPE unsigned int
  37. # define _FP_WS_TYPE signed int
  38. # define _FP_I_TYPE int
  39. # define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
  40. __asm__ ("add{l} {%11,%3|%3,%11}\n\t" \
  41. "adc{l} {%9,%2|%2,%9}\n\t" \
  42. "adc{l} {%7,%1|%1,%7}\n\t" \
  43. "adc{l} {%5,%0|%0,%5}" \
  44. : "=r" ((USItype) (r3)), \
  45. "=&r" ((USItype) (r2)), \
  46. "=&r" ((USItype) (r1)), \
  47. "=&r" ((USItype) (r0)) \
  48. : "%0" ((USItype) (x3)), \
  49. "g" ((USItype) (y3)), \
  50. "%1" ((USItype) (x2)), \
  51. "g" ((USItype) (y2)), \
  52. "%2" ((USItype) (x1)), \
  53. "g" ((USItype) (y1)), \
  54. "%3" ((USItype) (x0)), \
  55. "g" ((USItype) (y0)))
  56. # define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
  57. __asm__ ("add{l} {%8,%2|%2,%8}\n\t" \
  58. "adc{l} {%6,%1|%1,%6}\n\t" \
  59. "adc{l} {%4,%0|%0,%4}" \
  60. : "=r" ((USItype) (r2)), \
  61. "=&r" ((USItype) (r1)), \
  62. "=&r" ((USItype) (r0)) \
  63. : "%0" ((USItype) (x2)), \
  64. "g" ((USItype) (y2)), \
  65. "%1" ((USItype) (x1)), \
  66. "g" ((USItype) (y1)), \
  67. "%2" ((USItype) (x0)), \
  68. "g" ((USItype) (y0)))
  69. # define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
  70. __asm__ ("sub{l} {%11,%3|%3,%11}\n\t" \
  71. "sbb{l} {%9,%2|%2,%9}\n\t" \
  72. "sbb{l} {%7,%1|%1,%7}\n\t" \
  73. "sbb{l} {%5,%0|%0,%5}" \
  74. : "=r" ((USItype) (r3)), \
  75. "=&r" ((USItype) (r2)), \
  76. "=&r" ((USItype) (r1)), \
  77. "=&r" ((USItype) (r0)) \
  78. : "0" ((USItype) (x3)), \
  79. "g" ((USItype) (y3)), \
  80. "1" ((USItype) (x2)), \
  81. "g" ((USItype) (y2)), \
  82. "2" ((USItype) (x1)), \
  83. "g" ((USItype) (y1)), \
  84. "3" ((USItype) (x0)), \
  85. "g" ((USItype) (y0)))
  86. # define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
  87. __asm__ ("sub{l} {%8,%2|%2,%8}\n\t" \
  88. "sbb{l} {%6,%1|%1,%6}\n\t" \
  89. "sbb{l} {%4,%0|%0,%4}" \
  90. : "=r" ((USItype) (r2)), \
  91. "=&r" ((USItype) (r1)), \
  92. "=&r" ((USItype) (r0)) \
  93. : "0" ((USItype) (x2)), \
  94. "g" ((USItype) (y2)), \
  95. "1" ((USItype) (x1)), \
  96. "g" ((USItype) (y1)), \
  97. "2" ((USItype) (x0)), \
  98. "g" ((USItype) (y0)))
  99. # define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
  100. __asm__ ("add{l} {%4,%3|%3,%4}\n\t" \
  101. "adc{l} {$0,%2|%2,0}\n\t" \
  102. "adc{l} {$0,%1|%1,0}\n\t" \
  103. "adc{l} {$0,%0|%0,0}" \
  104. : "+r" ((USItype) (x3)), \
  105. "+&r" ((USItype) (x2)), \
  106. "+&r" ((USItype) (x1)), \
  107. "+&r" ((USItype) (x0)) \
  108. : "g" ((USItype) (i)))
  109. # define _FP_MUL_MEAT_S(R,X,Y) \
  110. _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
  111. # define _FP_MUL_MEAT_D(R,X,Y) \
  112. _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
  113. # define _FP_MUL_MEAT_Q(R,X,Y) \
  114. _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
  115. # define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
  116. # define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
  117. # define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
  118. # define _FP_NANFRAC_S _FP_QNANBIT_S
  119. # define _FP_NANFRAC_D _FP_QNANBIT_D, 0
  120. /* Even if XFmode is 12byte, we have to pad it to
  121. 16byte since soft-fp emulation is done in 16byte. */
  122. # define _FP_NANFRAC_E _FP_QNANBIT_E, 0, 0, 0
  123. # define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
  124. # define FP_EX_SHIFT 0
  125. # define _FP_DECL_EX \
  126. unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
  127. # define FP_RND_NEAREST 0
  128. # define FP_RND_ZERO 0xc00
  129. # define FP_RND_PINF 0x800
  130. # define FP_RND_MINF 0x400
  131. # define FP_RND_MASK 0xc00
  132. # define FP_INIT_ROUNDMODE \
  133. do { \
  134. __asm__ __volatile__ ("fnstcw\t%0" : "=m" (_fcw)); \
  135. } while (0)
  136. #endif
  137. #define _FP_KEEPNANFRACP 1
  138. #define _FP_QNANNEGATEDP 0
  139. #define _FP_NANSIGN_S 1
  140. #define _FP_NANSIGN_D 1
  141. #define _FP_NANSIGN_E 1
  142. #define _FP_NANSIGN_Q 1
  143. /* Here is something Intel misdesigned: the specs don't define
  144. the case where we have two NaNs with same mantissas, but
  145. different sign. Different operations pick up different NaNs. */
  146. #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
  147. do { \
  148. if (_FP_FRAC_GT_##wc(X, Y) \
  149. || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
  150. { \
  151. R##_s = X##_s; \
  152. _FP_FRAC_COPY_##wc(R,X); \
  153. } \
  154. else \
  155. { \
  156. R##_s = Y##_s; \
  157. _FP_FRAC_COPY_##wc(R,Y); \
  158. } \
  159. R##_c = FP_CLS_NAN; \
  160. } while (0)
  161. #define FP_EX_INVALID 0x01
  162. #define FP_EX_DENORM 0x02
  163. #define FP_EX_DIVZERO 0x04
  164. #define FP_EX_OVERFLOW 0x08
  165. #define FP_EX_UNDERFLOW 0x10
  166. #define FP_EX_INEXACT 0x20
  167. #define FP_EX_ALL \
  168. (FP_EX_INVALID | FP_EX_DENORM | FP_EX_DIVZERO | FP_EX_OVERFLOW \
  169. | FP_EX_UNDERFLOW | FP_EX_INEXACT)
  170. void __sfp_handle_exceptions (int);
  171. #define FP_HANDLE_EXCEPTIONS \
  172. do { \
  173. if (__builtin_expect (_fex, 0)) \
  174. __sfp_handle_exceptions (_fex); \
  175. } while (0);
  176. #define FP_TRAPPING_EXCEPTIONS ((~_fcw >> FP_EX_SHIFT) & FP_EX_ALL)
  177. #define FP_ROUNDMODE (_fcw & FP_RND_MASK)
  178. #define _FP_TININESS_AFTER_ROUNDING 1