soft-fp.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* Software floating-point emulation.
  2. Copyright (C) 1997-2017 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Richard Henderson (rth@cygnus.com),
  5. Jakub Jelinek (jj@ultra.linux.cz),
  6. David S. Miller (davem@redhat.com) and
  7. Peter Maydell (pmaydell@chiark.greenend.org.uk).
  8. The GNU C Library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public
  10. License as published by the Free Software Foundation; either
  11. version 2.1 of the License, or (at your option) any later version.
  12. In addition to the permissions in the GNU Lesser General Public
  13. License, the Free Software Foundation gives you unlimited
  14. permission to link the compiled version of this file into
  15. combinations with other programs, and to distribute those
  16. combinations without any restriction coming from the use of this
  17. file. (The Lesser General Public License restrictions do apply in
  18. other respects; for example, they cover modification of the file,
  19. and distribution when not linked into a combine executable.)
  20. The GNU C Library is distributed in the hope that it will be useful,
  21. but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. Lesser General Public License for more details.
  24. You should have received a copy of the GNU Lesser General Public
  25. License along with the GNU C Library; if not, see
  26. <http://www.gnu.org/licenses/>. */
  27. #ifndef SOFT_FP_H
  28. #define SOFT_FP_H 1
  29. #include "sfp-machine.h"
  30. /* Allow sfp-machine to have its own byte order definitions. */
  31. #ifndef __BYTE_ORDER
  32. # ifdef _LIBC
  33. # include <endian.h>
  34. # else
  35. # error "endianness not defined by sfp-machine.h"
  36. # endif
  37. #endif
  38. /* For unreachable default cases in switch statements over bitwise OR
  39. of FP_CLS_* values. */
  40. #if (defined __GNUC__ \
  41. && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
  42. # define _FP_UNREACHABLE __builtin_unreachable ()
  43. #else
  44. # define _FP_UNREACHABLE abort ()
  45. #endif
  46. #if ((defined __GNUC__ \
  47. && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) \
  48. || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
  49. # define _FP_STATIC_ASSERT(expr, msg) \
  50. _Static_assert ((expr), msg)
  51. #else
  52. # define _FP_STATIC_ASSERT(expr, msg) \
  53. extern int (*__Static_assert_function (void)) \
  54. [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
  55. #endif
  56. /* In the Linux kernel, some architectures have a single function that
  57. uses different kinds of unpacking and packing depending on the
  58. instruction being emulated, meaning it is not readily visible to
  59. the compiler that variables from _FP_DECL and _FP_FRAC_DECL_*
  60. macros are only used in cases where they were initialized. */
  61. #ifdef __KERNEL__
  62. # define _FP_ZERO_INIT = 0
  63. #else
  64. # define _FP_ZERO_INIT
  65. #endif
  66. #define _FP_WORKBITS 3
  67. #define _FP_WORK_LSB ((_FP_W_TYPE) 1 << 3)
  68. #define _FP_WORK_ROUND ((_FP_W_TYPE) 1 << 2)
  69. #define _FP_WORK_GUARD ((_FP_W_TYPE) 1 << 1)
  70. #define _FP_WORK_STICKY ((_FP_W_TYPE) 1 << 0)
  71. #ifndef FP_RND_NEAREST
  72. # define FP_RND_NEAREST 0
  73. # define FP_RND_ZERO 1
  74. # define FP_RND_PINF 2
  75. # define FP_RND_MINF 3
  76. #endif
  77. #ifndef FP_ROUNDMODE
  78. # define FP_ROUNDMODE FP_RND_NEAREST
  79. #endif
  80. /* By default don't care about exceptions. */
  81. #ifndef FP_EX_INVALID
  82. # define FP_EX_INVALID 0
  83. #endif
  84. #ifndef FP_EX_OVERFLOW
  85. # define FP_EX_OVERFLOW 0
  86. #endif
  87. #ifndef FP_EX_UNDERFLOW
  88. # define FP_EX_UNDERFLOW 0
  89. #endif
  90. #ifndef FP_EX_DIVZERO
  91. # define FP_EX_DIVZERO 0
  92. #endif
  93. #ifndef FP_EX_INEXACT
  94. # define FP_EX_INEXACT 0
  95. #endif
  96. #ifndef FP_EX_DENORM
  97. # define FP_EX_DENORM 0
  98. #endif
  99. /* Sub-exceptions of "invalid". */
  100. /* Signaling NaN operand. */
  101. #ifndef FP_EX_INVALID_SNAN
  102. # define FP_EX_INVALID_SNAN 0
  103. #endif
  104. /* Inf * 0. */
  105. #ifndef FP_EX_INVALID_IMZ
  106. # define FP_EX_INVALID_IMZ 0
  107. #endif
  108. /* fma (Inf, 0, c). */
  109. #ifndef FP_EX_INVALID_IMZ_FMA
  110. # define FP_EX_INVALID_IMZ_FMA 0
  111. #endif
  112. /* Inf - Inf. */
  113. #ifndef FP_EX_INVALID_ISI
  114. # define FP_EX_INVALID_ISI 0
  115. #endif
  116. /* 0 / 0. */
  117. #ifndef FP_EX_INVALID_ZDZ
  118. # define FP_EX_INVALID_ZDZ 0
  119. #endif
  120. /* Inf / Inf. */
  121. #ifndef FP_EX_INVALID_IDI
  122. # define FP_EX_INVALID_IDI 0
  123. #endif
  124. /* sqrt (negative). */
  125. #ifndef FP_EX_INVALID_SQRT
  126. # define FP_EX_INVALID_SQRT 0
  127. #endif
  128. /* Invalid conversion to integer. */
  129. #ifndef FP_EX_INVALID_CVI
  130. # define FP_EX_INVALID_CVI 0
  131. #endif
  132. /* Invalid comparison. */
  133. #ifndef FP_EX_INVALID_VC
  134. # define FP_EX_INVALID_VC 0
  135. #endif
  136. /* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the
  137. struct layout variant used for structures where bit-fields are used
  138. to access specific parts of binary floating-point numbers. This is
  139. required for systems where the default ABI uses struct layout with
  140. differences in how consecutive bit-fields are laid out from the
  141. default expected by soft-fp. */
  142. #ifndef _FP_STRUCT_LAYOUT
  143. # define _FP_STRUCT_LAYOUT
  144. #endif
  145. #ifdef _FP_DECL_EX
  146. # define FP_DECL_EX \
  147. int _fex = 0; \
  148. _FP_DECL_EX
  149. #else
  150. # define FP_DECL_EX int _fex = 0
  151. #endif
  152. /* Initialize any machine-specific state used in FP_ROUNDMODE,
  153. FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */
  154. #ifndef FP_INIT_ROUNDMODE
  155. # define FP_INIT_ROUNDMODE do {} while (0)
  156. #endif
  157. /* Initialize any machine-specific state used in
  158. FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */
  159. #ifndef FP_INIT_TRAPPING_EXCEPTIONS
  160. # define FP_INIT_TRAPPING_EXCEPTIONS FP_INIT_ROUNDMODE
  161. #endif
  162. /* Initialize any machine-specific state used in
  163. FP_HANDLE_EXCEPTIONS. */
  164. #ifndef FP_INIT_EXCEPTIONS
  165. # define FP_INIT_EXCEPTIONS FP_INIT_TRAPPING_EXCEPTIONS
  166. #endif
  167. #ifndef FP_HANDLE_EXCEPTIONS
  168. # define FP_HANDLE_EXCEPTIONS do {} while (0)
  169. #endif
  170. /* Whether to flush subnormal inputs to zero with the same sign. */
  171. #ifndef FP_DENORM_ZERO
  172. # define FP_DENORM_ZERO 0
  173. #endif
  174. #ifndef FP_INHIBIT_RESULTS
  175. /* By default we write the results always.
  176. sfp-machine may override this and e.g.
  177. check if some exceptions are unmasked
  178. and inhibit it in such a case. */
  179. # define FP_INHIBIT_RESULTS 0
  180. #endif
  181. #define FP_SET_EXCEPTION(ex) \
  182. _fex |= (ex)
  183. #define FP_CUR_EXCEPTIONS \
  184. (_fex)
  185. #ifndef FP_TRAPPING_EXCEPTIONS
  186. # define FP_TRAPPING_EXCEPTIONS 0
  187. #endif
  188. /* A file using soft-fp may define FP_NO_EXCEPTIONS before including
  189. soft-fp.h to indicate that, although a macro used there could raise
  190. exceptions, or do rounding and potentially thereby raise
  191. exceptions, for some arguments, for the particular arguments used
  192. in that file no exceptions or rounding can occur. Such a file
  193. should not itself use macros relating to handling exceptions and
  194. rounding modes; this is only for indirect uses (in particular, in
  195. _FP_FROM_INT and the macros it calls). */
  196. #ifdef FP_NO_EXCEPTIONS
  197. # undef FP_SET_EXCEPTION
  198. # define FP_SET_EXCEPTION(ex) do {} while (0)
  199. # undef FP_CUR_EXCEPTIONS
  200. # define FP_CUR_EXCEPTIONS 0
  201. # undef FP_TRAPPING_EXCEPTIONS
  202. # define FP_TRAPPING_EXCEPTIONS 0
  203. # undef FP_ROUNDMODE
  204. # define FP_ROUNDMODE FP_RND_ZERO
  205. # undef _FP_TININESS_AFTER_ROUNDING
  206. # define _FP_TININESS_AFTER_ROUNDING 0
  207. #endif
  208. /* A file using soft-fp may define FP_NO_EXACT_UNDERFLOW before
  209. including soft-fp.h to indicate that, although a macro used there
  210. could allow for the case of exact underflow requiring the underflow
  211. exception to be raised if traps are enabled, for the particular
  212. arguments used in that file no exact underflow can occur. */
  213. #ifdef FP_NO_EXACT_UNDERFLOW
  214. # undef FP_TRAPPING_EXCEPTIONS
  215. # define FP_TRAPPING_EXCEPTIONS 0
  216. #endif
  217. #define _FP_ROUND_NEAREST(wc, X) \
  218. do \
  219. { \
  220. if ((_FP_FRAC_LOW_##wc (X) & 15) != _FP_WORK_ROUND) \
  221. _FP_FRAC_ADDI_##wc (X, _FP_WORK_ROUND); \
  222. } \
  223. while (0)
  224. #define _FP_ROUND_ZERO(wc, X) (void) 0
  225. #define _FP_ROUND_PINF(wc, X) \
  226. do \
  227. { \
  228. if (!X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \
  229. _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \
  230. } \
  231. while (0)
  232. #define _FP_ROUND_MINF(wc, X) \
  233. do \
  234. { \
  235. if (X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \
  236. _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \
  237. } \
  238. while (0)
  239. #define _FP_ROUND(wc, X) \
  240. do \
  241. { \
  242. if (_FP_FRAC_LOW_##wc (X) & 7) \
  243. { \
  244. FP_SET_EXCEPTION (FP_EX_INEXACT); \
  245. switch (FP_ROUNDMODE) \
  246. { \
  247. case FP_RND_NEAREST: \
  248. _FP_ROUND_NEAREST (wc, X); \
  249. break; \
  250. case FP_RND_ZERO: \
  251. _FP_ROUND_ZERO (wc, X); \
  252. break; \
  253. case FP_RND_PINF: \
  254. _FP_ROUND_PINF (wc, X); \
  255. break; \
  256. case FP_RND_MINF: \
  257. _FP_ROUND_MINF (wc, X); \
  258. break; \
  259. } \
  260. } \
  261. } \
  262. while (0)
  263. #define FP_CLS_NORMAL 0
  264. #define FP_CLS_ZERO 1
  265. #define FP_CLS_INF 2
  266. #define FP_CLS_NAN 3
  267. #define _FP_CLS_COMBINE(x, y) (((x) << 2) | (y))
  268. #include "op-1.h"
  269. #include "op-2.h"
  270. #include "op-4.h"
  271. #include "op-8.h"
  272. #include "op-common.h"
  273. /* Sigh. Silly things longlong.h needs. */
  274. #define UWtype _FP_W_TYPE
  275. #define W_TYPE_SIZE _FP_W_TYPE_SIZE
  276. typedef int QItype __attribute__ ((mode (QI)));
  277. typedef int SItype __attribute__ ((mode (SI)));
  278. typedef int DItype __attribute__ ((mode (DI)));
  279. typedef unsigned int UQItype __attribute__ ((mode (QI)));
  280. typedef unsigned int USItype __attribute__ ((mode (SI)));
  281. typedef unsigned int UDItype __attribute__ ((mode (DI)));
  282. #if _FP_W_TYPE_SIZE == 32
  283. typedef unsigned int UHWtype __attribute__ ((mode (HI)));
  284. #elif _FP_W_TYPE_SIZE == 64
  285. typedef USItype UHWtype;
  286. #endif
  287. #ifndef CMPtype
  288. # define CMPtype int
  289. #endif
  290. #define SI_BITS (__CHAR_BIT__ * (int) sizeof (SItype))
  291. #define DI_BITS (__CHAR_BIT__ * (int) sizeof (DItype))
  292. #ifndef umul_ppmm
  293. # include "longlong.h"
  294. #endif
  295. #endif /* !SOFT_FP_H */