ieee_arithmetic.F90 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. ! Implementation of the IEEE_ARITHMETIC standard intrinsic module
  2. ! Copyright (C) 2013-2022 Free Software Foundation, Inc.
  3. ! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
  4. !
  5. ! This file is part of the GNU Fortran runtime library (libgfortran).
  6. !
  7. ! Libgfortran is free software; you can redistribute it and/or
  8. ! modify it under the terms of the GNU General Public
  9. ! License as published by the Free Software Foundation; either
  10. ! version 3 of the License, or (at your option) any later version.
  11. !
  12. ! Libgfortran is distributed in the hope that it will be useful,
  13. ! but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ! GNU General Public License for more details.
  16. !
  17. ! Under Section 7 of GPL version 3, you are granted additional
  18. ! permissions described in the GCC Runtime Library Exception, version
  19. ! 3.1, as published by the Free Software Foundation.
  20. !
  21. ! You should have received a copy of the GNU General Public License and
  22. ! a copy of the GCC Runtime Library Exception along with this program;
  23. ! see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  24. ! <http://www.gnu.org/licenses/>. */
  25. #include "config.h"
  26. #include "kinds.inc"
  27. #include "c99_protos.inc"
  28. #include "fpu-target.inc"
  29. module IEEE_ARITHMETIC
  30. use IEEE_EXCEPTIONS
  31. implicit none
  32. private
  33. ! Every public symbol from IEEE_EXCEPTIONS must be made public here
  34. public :: IEEE_FLAG_TYPE, IEEE_INVALID, IEEE_OVERFLOW, &
  35. IEEE_DIVIDE_BY_ZERO, IEEE_UNDERFLOW, IEEE_INEXACT, IEEE_USUAL, &
  36. IEEE_ALL, IEEE_STATUS_TYPE, IEEE_GET_FLAG, IEEE_GET_HALTING_MODE, &
  37. IEEE_GET_STATUS, IEEE_SET_FLAG, IEEE_SET_HALTING_MODE, &
  38. IEEE_SET_STATUS, IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING
  39. ! Derived types and named constants
  40. type, public :: IEEE_CLASS_TYPE
  41. private
  42. integer :: hidden
  43. end type
  44. type(IEEE_CLASS_TYPE), parameter, public :: &
  45. IEEE_OTHER_VALUE = IEEE_CLASS_TYPE(0), &
  46. IEEE_SIGNALING_NAN = IEEE_CLASS_TYPE(1), &
  47. IEEE_QUIET_NAN = IEEE_CLASS_TYPE(2), &
  48. IEEE_NEGATIVE_INF = IEEE_CLASS_TYPE(3), &
  49. IEEE_NEGATIVE_NORMAL = IEEE_CLASS_TYPE(4), &
  50. IEEE_NEGATIVE_DENORMAL = IEEE_CLASS_TYPE(5), &
  51. IEEE_NEGATIVE_SUBNORMAL= IEEE_CLASS_TYPE(5), &
  52. IEEE_NEGATIVE_ZERO = IEEE_CLASS_TYPE(6), &
  53. IEEE_POSITIVE_ZERO = IEEE_CLASS_TYPE(7), &
  54. IEEE_POSITIVE_DENORMAL = IEEE_CLASS_TYPE(8), &
  55. IEEE_POSITIVE_SUBNORMAL= IEEE_CLASS_TYPE(8), &
  56. IEEE_POSITIVE_NORMAL = IEEE_CLASS_TYPE(9), &
  57. IEEE_POSITIVE_INF = IEEE_CLASS_TYPE(10)
  58. type, public :: IEEE_ROUND_TYPE
  59. private
  60. integer :: hidden
  61. end type
  62. type(IEEE_ROUND_TYPE), parameter, public :: &
  63. IEEE_NEAREST = IEEE_ROUND_TYPE(GFC_FPE_TONEAREST), &
  64. IEEE_TO_ZERO = IEEE_ROUND_TYPE(GFC_FPE_TOWARDZERO), &
  65. IEEE_UP = IEEE_ROUND_TYPE(GFC_FPE_UPWARD), &
  66. IEEE_DOWN = IEEE_ROUND_TYPE(GFC_FPE_DOWNWARD), &
  67. IEEE_OTHER = IEEE_ROUND_TYPE(0)
  68. ! Equality operators on the derived types
  69. ! Note, the FE overloads .eq. to == and .ne. to /=
  70. interface operator (.eq.)
  71. module procedure IEEE_CLASS_TYPE_EQ, IEEE_ROUND_TYPE_EQ
  72. end interface
  73. public :: operator(.eq.)
  74. interface operator (.ne.)
  75. module procedure IEEE_CLASS_TYPE_NE, IEEE_ROUND_TYPE_NE
  76. end interface
  77. public :: operator (.ne.)
  78. ! IEEE_IS_FINITE
  79. interface
  80. elemental logical function _gfortran_ieee_is_finite_4(X)
  81. real(kind=4), intent(in) :: X
  82. end function
  83. elemental logical function _gfortran_ieee_is_finite_8(X)
  84. real(kind=8), intent(in) :: X
  85. end function
  86. #ifdef HAVE_GFC_REAL_10
  87. elemental logical function _gfortran_ieee_is_finite_10(X)
  88. real(kind=10), intent(in) :: X
  89. end function
  90. #endif
  91. #ifdef HAVE_GFC_REAL_16
  92. elemental logical function _gfortran_ieee_is_finite_16(X)
  93. real(kind=16), intent(in) :: X
  94. end function
  95. #endif
  96. end interface
  97. interface IEEE_IS_FINITE
  98. procedure &
  99. #ifdef HAVE_GFC_REAL_16
  100. _gfortran_ieee_is_finite_16, &
  101. #endif
  102. #ifdef HAVE_GFC_REAL_10
  103. _gfortran_ieee_is_finite_10, &
  104. #endif
  105. _gfortran_ieee_is_finite_8, _gfortran_ieee_is_finite_4
  106. end interface
  107. public :: IEEE_IS_FINITE
  108. ! IEEE_IS_NAN
  109. interface
  110. elemental logical function _gfortran_ieee_is_nan_4(X)
  111. real(kind=4), intent(in) :: X
  112. end function
  113. elemental logical function _gfortran_ieee_is_nan_8(X)
  114. real(kind=8), intent(in) :: X
  115. end function
  116. #ifdef HAVE_GFC_REAL_10
  117. elemental logical function _gfortran_ieee_is_nan_10(X)
  118. real(kind=10), intent(in) :: X
  119. end function
  120. #endif
  121. #ifdef HAVE_GFC_REAL_16
  122. elemental logical function _gfortran_ieee_is_nan_16(X)
  123. real(kind=16), intent(in) :: X
  124. end function
  125. #endif
  126. end interface
  127. interface IEEE_IS_NAN
  128. procedure &
  129. #ifdef HAVE_GFC_REAL_16
  130. _gfortran_ieee_is_nan_16, &
  131. #endif
  132. #ifdef HAVE_GFC_REAL_10
  133. _gfortran_ieee_is_nan_10, &
  134. #endif
  135. _gfortran_ieee_is_nan_8, _gfortran_ieee_is_nan_4
  136. end interface
  137. public :: IEEE_IS_NAN
  138. ! IEEE_IS_NEGATIVE
  139. interface
  140. elemental logical function _gfortran_ieee_is_negative_4(X)
  141. real(kind=4), intent(in) :: X
  142. end function
  143. elemental logical function _gfortran_ieee_is_negative_8(X)
  144. real(kind=8), intent(in) :: X
  145. end function
  146. #ifdef HAVE_GFC_REAL_10
  147. elemental logical function _gfortran_ieee_is_negative_10(X)
  148. real(kind=10), intent(in) :: X
  149. end function
  150. #endif
  151. #ifdef HAVE_GFC_REAL_16
  152. elemental logical function _gfortran_ieee_is_negative_16(X)
  153. real(kind=16), intent(in) :: X
  154. end function
  155. #endif
  156. end interface
  157. interface IEEE_IS_NEGATIVE
  158. procedure &
  159. #ifdef HAVE_GFC_REAL_16
  160. _gfortran_ieee_is_negative_16, &
  161. #endif
  162. #ifdef HAVE_GFC_REAL_10
  163. _gfortran_ieee_is_negative_10, &
  164. #endif
  165. _gfortran_ieee_is_negative_8, _gfortran_ieee_is_negative_4
  166. end interface
  167. public :: IEEE_IS_NEGATIVE
  168. ! IEEE_IS_NORMAL
  169. interface
  170. elemental logical function _gfortran_ieee_is_normal_4(X)
  171. real(kind=4), intent(in) :: X
  172. end function
  173. elemental logical function _gfortran_ieee_is_normal_8(X)
  174. real(kind=8), intent(in) :: X
  175. end function
  176. #ifdef HAVE_GFC_REAL_10
  177. elemental logical function _gfortran_ieee_is_normal_10(X)
  178. real(kind=10), intent(in) :: X
  179. end function
  180. #endif
  181. #ifdef HAVE_GFC_REAL_16
  182. elemental logical function _gfortran_ieee_is_normal_16(X)
  183. real(kind=16), intent(in) :: X
  184. end function
  185. #endif
  186. end interface
  187. interface IEEE_IS_NORMAL
  188. procedure &
  189. #ifdef HAVE_GFC_REAL_16
  190. _gfortran_ieee_is_normal_16, &
  191. #endif
  192. #ifdef HAVE_GFC_REAL_10
  193. _gfortran_ieee_is_normal_10, &
  194. #endif
  195. _gfortran_ieee_is_normal_8, _gfortran_ieee_is_normal_4
  196. end interface
  197. public :: IEEE_IS_NORMAL
  198. ! IEEE_COPY_SIGN
  199. #define COPYSIGN_MACRO(A,B) \
  200. elemental real(kind = A) function \
  201. _gfortran_ieee_copy_sign_/**/A/**/_/**/B (X,Y) ; \
  202. real(kind = A), intent(in) :: X ; \
  203. real(kind = B), intent(in) :: Y ; \
  204. end function
  205. interface
  206. #ifdef HAVE_GFC_REAL_16
  207. COPYSIGN_MACRO(16,16)
  208. #ifdef HAVE_GFC_REAL_10
  209. COPYSIGN_MACRO(16,10)
  210. COPYSIGN_MACRO(10,16)
  211. #endif
  212. COPYSIGN_MACRO(16,8)
  213. COPYSIGN_MACRO(16,4)
  214. COPYSIGN_MACRO(8,16)
  215. COPYSIGN_MACRO(4,16)
  216. #endif
  217. #ifdef HAVE_GFC_REAL_10
  218. COPYSIGN_MACRO(10,10)
  219. COPYSIGN_MACRO(10,8)
  220. COPYSIGN_MACRO(10,4)
  221. COPYSIGN_MACRO(8,10)
  222. COPYSIGN_MACRO(4,10)
  223. #endif
  224. COPYSIGN_MACRO(8,8)
  225. COPYSIGN_MACRO(8,4)
  226. COPYSIGN_MACRO(4,8)
  227. COPYSIGN_MACRO(4,4)
  228. end interface
  229. interface IEEE_COPY_SIGN
  230. procedure &
  231. #ifdef HAVE_GFC_REAL_16
  232. _gfortran_ieee_copy_sign_16_16, &
  233. #ifdef HAVE_GFC_REAL_10
  234. _gfortran_ieee_copy_sign_16_10, &
  235. _gfortran_ieee_copy_sign_10_16, &
  236. #endif
  237. _gfortran_ieee_copy_sign_16_8, &
  238. _gfortran_ieee_copy_sign_16_4, &
  239. _gfortran_ieee_copy_sign_8_16, &
  240. _gfortran_ieee_copy_sign_4_16, &
  241. #endif
  242. #ifdef HAVE_GFC_REAL_10
  243. _gfortran_ieee_copy_sign_10_10, &
  244. _gfortran_ieee_copy_sign_10_8, &
  245. _gfortran_ieee_copy_sign_10_4, &
  246. _gfortran_ieee_copy_sign_8_10, &
  247. _gfortran_ieee_copy_sign_4_10, &
  248. #endif
  249. _gfortran_ieee_copy_sign_8_8, &
  250. _gfortran_ieee_copy_sign_8_4, &
  251. _gfortran_ieee_copy_sign_4_8, &
  252. _gfortran_ieee_copy_sign_4_4
  253. end interface
  254. public :: IEEE_COPY_SIGN
  255. ! IEEE_UNORDERED
  256. #define UNORDERED_MACRO(A,B) \
  257. elemental logical function \
  258. _gfortran_ieee_unordered_/**/A/**/_/**/B (X,Y) ; \
  259. real(kind = A), intent(in) :: X ; \
  260. real(kind = B), intent(in) :: Y ; \
  261. end function
  262. interface
  263. #ifdef HAVE_GFC_REAL_16
  264. UNORDERED_MACRO(16,16)
  265. #ifdef HAVE_GFC_REAL_10
  266. UNORDERED_MACRO(16,10)
  267. UNORDERED_MACRO(10,16)
  268. #endif
  269. UNORDERED_MACRO(16,8)
  270. UNORDERED_MACRO(16,4)
  271. UNORDERED_MACRO(8,16)
  272. UNORDERED_MACRO(4,16)
  273. #endif
  274. #ifdef HAVE_GFC_REAL_10
  275. UNORDERED_MACRO(10,10)
  276. UNORDERED_MACRO(10,8)
  277. UNORDERED_MACRO(10,4)
  278. UNORDERED_MACRO(8,10)
  279. UNORDERED_MACRO(4,10)
  280. #endif
  281. UNORDERED_MACRO(8,8)
  282. UNORDERED_MACRO(8,4)
  283. UNORDERED_MACRO(4,8)
  284. UNORDERED_MACRO(4,4)
  285. end interface
  286. interface IEEE_UNORDERED
  287. procedure &
  288. #ifdef HAVE_GFC_REAL_16
  289. _gfortran_ieee_unordered_16_16, &
  290. #ifdef HAVE_GFC_REAL_10
  291. _gfortran_ieee_unordered_16_10, &
  292. _gfortran_ieee_unordered_10_16, &
  293. #endif
  294. _gfortran_ieee_unordered_16_8, &
  295. _gfortran_ieee_unordered_16_4, &
  296. _gfortran_ieee_unordered_8_16, &
  297. _gfortran_ieee_unordered_4_16, &
  298. #endif
  299. #ifdef HAVE_GFC_REAL_10
  300. _gfortran_ieee_unordered_10_10, &
  301. _gfortran_ieee_unordered_10_8, &
  302. _gfortran_ieee_unordered_10_4, &
  303. _gfortran_ieee_unordered_8_10, &
  304. _gfortran_ieee_unordered_4_10, &
  305. #endif
  306. _gfortran_ieee_unordered_8_8, &
  307. _gfortran_ieee_unordered_8_4, &
  308. _gfortran_ieee_unordered_4_8, &
  309. _gfortran_ieee_unordered_4_4
  310. end interface
  311. public :: IEEE_UNORDERED
  312. ! IEEE_LOGB
  313. interface
  314. elemental real(kind=4) function _gfortran_ieee_logb_4 (X)
  315. real(kind=4), intent(in) :: X
  316. end function
  317. elemental real(kind=8) function _gfortran_ieee_logb_8 (X)
  318. real(kind=8), intent(in) :: X
  319. end function
  320. #ifdef HAVE_GFC_REAL_10
  321. elemental real(kind=10) function _gfortran_ieee_logb_10 (X)
  322. real(kind=10), intent(in) :: X
  323. end function
  324. #endif
  325. #ifdef HAVE_GFC_REAL_16
  326. elemental real(kind=16) function _gfortran_ieee_logb_16 (X)
  327. real(kind=16), intent(in) :: X
  328. end function
  329. #endif
  330. end interface
  331. interface IEEE_LOGB
  332. procedure &
  333. #ifdef HAVE_GFC_REAL_16
  334. _gfortran_ieee_logb_16, &
  335. #endif
  336. #ifdef HAVE_GFC_REAL_10
  337. _gfortran_ieee_logb_10, &
  338. #endif
  339. _gfortran_ieee_logb_8, &
  340. _gfortran_ieee_logb_4
  341. end interface
  342. public :: IEEE_LOGB
  343. ! IEEE_NEXT_AFTER
  344. #define NEXT_AFTER_MACRO(A,B) \
  345. elemental real(kind = A) function \
  346. _gfortran_ieee_next_after_/**/A/**/_/**/B (X,Y) ; \
  347. real(kind = A), intent(in) :: X ; \
  348. real(kind = B), intent(in) :: Y ; \
  349. end function
  350. interface
  351. #ifdef HAVE_GFC_REAL_16
  352. NEXT_AFTER_MACRO(16,16)
  353. #ifdef HAVE_GFC_REAL_10
  354. NEXT_AFTER_MACRO(16,10)
  355. NEXT_AFTER_MACRO(10,16)
  356. #endif
  357. NEXT_AFTER_MACRO(16,8)
  358. NEXT_AFTER_MACRO(16,4)
  359. NEXT_AFTER_MACRO(8,16)
  360. NEXT_AFTER_MACRO(4,16)
  361. #endif
  362. #ifdef HAVE_GFC_REAL_10
  363. NEXT_AFTER_MACRO(10,10)
  364. NEXT_AFTER_MACRO(10,8)
  365. NEXT_AFTER_MACRO(10,4)
  366. NEXT_AFTER_MACRO(8,10)
  367. NEXT_AFTER_MACRO(4,10)
  368. #endif
  369. NEXT_AFTER_MACRO(8,8)
  370. NEXT_AFTER_MACRO(8,4)
  371. NEXT_AFTER_MACRO(4,8)
  372. NEXT_AFTER_MACRO(4,4)
  373. end interface
  374. interface IEEE_NEXT_AFTER
  375. procedure &
  376. #ifdef HAVE_GFC_REAL_16
  377. _gfortran_ieee_next_after_16_16, &
  378. #ifdef HAVE_GFC_REAL_10
  379. _gfortran_ieee_next_after_16_10, &
  380. _gfortran_ieee_next_after_10_16, &
  381. #endif
  382. _gfortran_ieee_next_after_16_8, &
  383. _gfortran_ieee_next_after_16_4, &
  384. _gfortran_ieee_next_after_8_16, &
  385. _gfortran_ieee_next_after_4_16, &
  386. #endif
  387. #ifdef HAVE_GFC_REAL_10
  388. _gfortran_ieee_next_after_10_10, &
  389. _gfortran_ieee_next_after_10_8, &
  390. _gfortran_ieee_next_after_10_4, &
  391. _gfortran_ieee_next_after_8_10, &
  392. _gfortran_ieee_next_after_4_10, &
  393. #endif
  394. _gfortran_ieee_next_after_8_8, &
  395. _gfortran_ieee_next_after_8_4, &
  396. _gfortran_ieee_next_after_4_8, &
  397. _gfortran_ieee_next_after_4_4
  398. end interface
  399. public :: IEEE_NEXT_AFTER
  400. ! IEEE_REM
  401. #define REM_MACRO(RES,A,B) \
  402. elemental real(kind = RES) function \
  403. _gfortran_ieee_rem_/**/A/**/_/**/B (X,Y) ; \
  404. real(kind = A), intent(in) :: X ; \
  405. real(kind = B), intent(in) :: Y ; \
  406. end function
  407. interface
  408. #ifdef HAVE_GFC_REAL_16
  409. REM_MACRO(16,16,16)
  410. #ifdef HAVE_GFC_REAL_10
  411. REM_MACRO(16,16,10)
  412. REM_MACRO(16,10,16)
  413. #endif
  414. REM_MACRO(16,16,8)
  415. REM_MACRO(16,16,4)
  416. REM_MACRO(16,8,16)
  417. REM_MACRO(16,4,16)
  418. #endif
  419. #ifdef HAVE_GFC_REAL_10
  420. REM_MACRO(10,10,10)
  421. REM_MACRO(10,10,8)
  422. REM_MACRO(10,10,4)
  423. REM_MACRO(10,8,10)
  424. REM_MACRO(10,4,10)
  425. #endif
  426. REM_MACRO(8,8,8)
  427. REM_MACRO(8,8,4)
  428. REM_MACRO(8,4,8)
  429. REM_MACRO(4,4,4)
  430. end interface
  431. interface IEEE_REM
  432. procedure &
  433. #ifdef HAVE_GFC_REAL_16
  434. _gfortran_ieee_rem_16_16, &
  435. #ifdef HAVE_GFC_REAL_10
  436. _gfortran_ieee_rem_16_10, &
  437. _gfortran_ieee_rem_10_16, &
  438. #endif
  439. _gfortran_ieee_rem_16_8, &
  440. _gfortran_ieee_rem_16_4, &
  441. _gfortran_ieee_rem_8_16, &
  442. _gfortran_ieee_rem_4_16, &
  443. #endif
  444. #ifdef HAVE_GFC_REAL_10
  445. _gfortran_ieee_rem_10_10, &
  446. _gfortran_ieee_rem_10_8, &
  447. _gfortran_ieee_rem_10_4, &
  448. _gfortran_ieee_rem_8_10, &
  449. _gfortran_ieee_rem_4_10, &
  450. #endif
  451. _gfortran_ieee_rem_8_8, &
  452. _gfortran_ieee_rem_8_4, &
  453. _gfortran_ieee_rem_4_8, &
  454. _gfortran_ieee_rem_4_4
  455. end interface
  456. public :: IEEE_REM
  457. ! IEEE_RINT
  458. interface
  459. elemental real(kind=4) function _gfortran_ieee_rint_4 (X)
  460. real(kind=4), intent(in) :: X
  461. end function
  462. elemental real(kind=8) function _gfortran_ieee_rint_8 (X)
  463. real(kind=8), intent(in) :: X
  464. end function
  465. #ifdef HAVE_GFC_REAL_10
  466. elemental real(kind=10) function _gfortran_ieee_rint_10 (X)
  467. real(kind=10), intent(in) :: X
  468. end function
  469. #endif
  470. #ifdef HAVE_GFC_REAL_16
  471. elemental real(kind=16) function _gfortran_ieee_rint_16 (X)
  472. real(kind=16), intent(in) :: X
  473. end function
  474. #endif
  475. end interface
  476. interface IEEE_RINT
  477. procedure &
  478. #ifdef HAVE_GFC_REAL_16
  479. _gfortran_ieee_rint_16, &
  480. #endif
  481. #ifdef HAVE_GFC_REAL_10
  482. _gfortran_ieee_rint_10, &
  483. #endif
  484. _gfortran_ieee_rint_8, _gfortran_ieee_rint_4
  485. end interface
  486. public :: IEEE_RINT
  487. ! IEEE_SCALB
  488. interface
  489. #ifdef HAVE_GFC_INTEGER_16
  490. #ifdef HAVE_GFC_REAL_16
  491. elemental real(kind=16) function _gfortran_ieee_scalb_16_16 (X, I)
  492. real(kind=16), intent(in) :: X
  493. integer(kind=16), intent(in) :: I
  494. end function
  495. #endif
  496. #ifdef HAVE_GFC_REAL_10
  497. elemental real(kind=10) function _gfortran_ieee_scalb_10_16 (X, I)
  498. real(kind=10), intent(in) :: X
  499. integer(kind=16), intent(in) :: I
  500. end function
  501. #endif
  502. elemental real(kind=8) function _gfortran_ieee_scalb_8_16 (X, I)
  503. real(kind=8), intent(in) :: X
  504. integer(kind=16), intent(in) :: I
  505. end function
  506. elemental real(kind=4) function _gfortran_ieee_scalb_4_16 (X, I)
  507. real(kind=4), intent(in) :: X
  508. integer(kind=16), intent(in) :: I
  509. end function
  510. #endif
  511. #ifdef HAVE_GFC_INTEGER_8
  512. #ifdef HAVE_GFC_REAL_16
  513. elemental real(kind=16) function _gfortran_ieee_scalb_16_8 (X, I)
  514. real(kind=16), intent(in) :: X
  515. integer(kind=8), intent(in) :: I
  516. end function
  517. #endif
  518. #ifdef HAVE_GFC_REAL_10
  519. elemental real(kind=10) function _gfortran_ieee_scalb_10_8 (X, I)
  520. real(kind=10), intent(in) :: X
  521. integer(kind=8), intent(in) :: I
  522. end function
  523. #endif
  524. elemental real(kind=8) function _gfortran_ieee_scalb_8_8 (X, I)
  525. real(kind=8), intent(in) :: X
  526. integer(kind=8), intent(in) :: I
  527. end function
  528. elemental real(kind=4) function _gfortran_ieee_scalb_4_8 (X, I)
  529. real(kind=4), intent(in) :: X
  530. integer(kind=8), intent(in) :: I
  531. end function
  532. #endif
  533. #ifdef HAVE_GFC_INTEGER_2
  534. #ifdef HAVE_GFC_REAL_16
  535. elemental real(kind=16) function _gfortran_ieee_scalb_16_2 (X, I)
  536. real(kind=16), intent(in) :: X
  537. integer(kind=2), intent(in) :: I
  538. end function
  539. #endif
  540. #ifdef HAVE_GFC_REAL_10
  541. elemental real(kind=10) function _gfortran_ieee_scalb_10_2 (X, I)
  542. real(kind=10), intent(in) :: X
  543. integer(kind=2), intent(in) :: I
  544. end function
  545. #endif
  546. elemental real(kind=8) function _gfortran_ieee_scalb_8_2 (X, I)
  547. real(kind=8), intent(in) :: X
  548. integer(kind=2), intent(in) :: I
  549. end function
  550. elemental real(kind=4) function _gfortran_ieee_scalb_4_2 (X, I)
  551. real(kind=4), intent(in) :: X
  552. integer(kind=2), intent(in) :: I
  553. end function
  554. #endif
  555. #ifdef HAVE_GFC_INTEGER_1
  556. #ifdef HAVE_GFC_REAL_16
  557. elemental real(kind=16) function _gfortran_ieee_scalb_16_1 (X, I)
  558. real(kind=16), intent(in) :: X
  559. integer(kind=1), intent(in) :: I
  560. end function
  561. #endif
  562. #ifdef HAVE_GFC_REAL_10
  563. elemental real(kind=10) function _gfortran_ieee_scalb_10_1 (X, I)
  564. real(kind=10), intent(in) :: X
  565. integer(kind=1), intent(in) :: I
  566. end function
  567. #endif
  568. elemental real(kind=8) function _gfortran_ieee_scalb_8_1 (X, I)
  569. real(kind=8), intent(in) :: X
  570. integer(kind=1), intent(in) :: I
  571. end function
  572. elemental real(kind=4) function _gfortran_ieee_scalb_4_1 (X, I)
  573. real(kind=4), intent(in) :: X
  574. integer(kind=1), intent(in) :: I
  575. end function
  576. #endif
  577. #ifdef HAVE_GFC_REAL_16
  578. elemental real(kind=16) function _gfortran_ieee_scalb_16_4 (X, I)
  579. real(kind=16), intent(in) :: X
  580. integer, intent(in) :: I
  581. end function
  582. #endif
  583. #ifdef HAVE_GFC_REAL_10
  584. elemental real(kind=10) function _gfortran_ieee_scalb_10_4 (X, I)
  585. real(kind=10), intent(in) :: X
  586. integer, intent(in) :: I
  587. end function
  588. #endif
  589. elemental real(kind=8) function _gfortran_ieee_scalb_8_4 (X, I)
  590. real(kind=8), intent(in) :: X
  591. integer, intent(in) :: I
  592. end function
  593. elemental real(kind=4) function _gfortran_ieee_scalb_4_4 (X, I)
  594. real(kind=4), intent(in) :: X
  595. integer, intent(in) :: I
  596. end function
  597. end interface
  598. interface IEEE_SCALB
  599. procedure &
  600. #ifdef HAVE_GFC_INTEGER_16
  601. #ifdef HAVE_GFC_REAL_16
  602. _gfortran_ieee_scalb_16_16, &
  603. #endif
  604. #ifdef HAVE_GFC_REAL_10
  605. _gfortran_ieee_scalb_10_16, &
  606. #endif
  607. _gfortran_ieee_scalb_8_16, &
  608. _gfortran_ieee_scalb_4_16, &
  609. #endif
  610. #ifdef HAVE_GFC_INTEGER_8
  611. #ifdef HAVE_GFC_REAL_16
  612. _gfortran_ieee_scalb_16_8, &
  613. #endif
  614. #ifdef HAVE_GFC_REAL_10
  615. _gfortran_ieee_scalb_10_8, &
  616. #endif
  617. _gfortran_ieee_scalb_8_8, &
  618. _gfortran_ieee_scalb_4_8, &
  619. #endif
  620. #ifdef HAVE_GFC_INTEGER_2
  621. #ifdef HAVE_GFC_REAL_16
  622. _gfortran_ieee_scalb_16_2, &
  623. #endif
  624. #ifdef HAVE_GFC_REAL_10
  625. _gfortran_ieee_scalb_10_2, &
  626. #endif
  627. _gfortran_ieee_scalb_8_2, &
  628. _gfortran_ieee_scalb_4_2, &
  629. #endif
  630. #ifdef HAVE_GFC_INTEGER_1
  631. #ifdef HAVE_GFC_REAL_16
  632. _gfortran_ieee_scalb_16_1, &
  633. #endif
  634. #ifdef HAVE_GFC_REAL_10
  635. _gfortran_ieee_scalb_10_1, &
  636. #endif
  637. _gfortran_ieee_scalb_8_1, &
  638. _gfortran_ieee_scalb_4_1, &
  639. #endif
  640. #ifdef HAVE_GFC_REAL_16
  641. _gfortran_ieee_scalb_16_4, &
  642. #endif
  643. #ifdef HAVE_GFC_REAL_10
  644. _gfortran_ieee_scalb_10_4, &
  645. #endif
  646. _gfortran_ieee_scalb_8_4, &
  647. _gfortran_ieee_scalb_4_4
  648. end interface
  649. public :: IEEE_SCALB
  650. ! IEEE_VALUE
  651. interface IEEE_VALUE
  652. module procedure &
  653. #ifdef HAVE_GFC_REAL_16
  654. IEEE_VALUE_16, &
  655. #endif
  656. #ifdef HAVE_GFC_REAL_10
  657. IEEE_VALUE_10, &
  658. #endif
  659. IEEE_VALUE_8, IEEE_VALUE_4
  660. end interface
  661. public :: IEEE_VALUE
  662. ! IEEE_CLASS
  663. interface IEEE_CLASS
  664. module procedure &
  665. #ifdef HAVE_GFC_REAL_16
  666. IEEE_CLASS_16, &
  667. #endif
  668. #ifdef HAVE_GFC_REAL_10
  669. IEEE_CLASS_10, &
  670. #endif
  671. IEEE_CLASS_8, IEEE_CLASS_4
  672. end interface
  673. public :: IEEE_CLASS
  674. ! Public declarations for contained procedures
  675. public :: IEEE_GET_ROUNDING_MODE, IEEE_SET_ROUNDING_MODE
  676. public :: IEEE_GET_UNDERFLOW_MODE, IEEE_SET_UNDERFLOW_MODE
  677. public :: IEEE_SELECTED_REAL_KIND
  678. ! IEEE_SUPPORT_ROUNDING
  679. interface IEEE_SUPPORT_ROUNDING
  680. module procedure IEEE_SUPPORT_ROUNDING_4, IEEE_SUPPORT_ROUNDING_8, &
  681. #ifdef HAVE_GFC_REAL_10
  682. IEEE_SUPPORT_ROUNDING_10, &
  683. #endif
  684. #ifdef HAVE_GFC_REAL_16
  685. IEEE_SUPPORT_ROUNDING_16, &
  686. #endif
  687. IEEE_SUPPORT_ROUNDING_NOARG
  688. end interface
  689. public :: IEEE_SUPPORT_ROUNDING
  690. ! Interface to the FPU-specific function
  691. interface
  692. pure integer function support_rounding_helper(flag) &
  693. bind(c, name="_gfortrani_support_fpu_rounding_mode")
  694. integer, intent(in), value :: flag
  695. end function
  696. end interface
  697. ! IEEE_SUPPORT_UNDERFLOW_CONTROL
  698. interface IEEE_SUPPORT_UNDERFLOW_CONTROL
  699. module procedure IEEE_SUPPORT_UNDERFLOW_CONTROL_4, &
  700. IEEE_SUPPORT_UNDERFLOW_CONTROL_8, &
  701. #ifdef HAVE_GFC_REAL_10
  702. IEEE_SUPPORT_UNDERFLOW_CONTROL_10, &
  703. #endif
  704. #ifdef HAVE_GFC_REAL_16
  705. IEEE_SUPPORT_UNDERFLOW_CONTROL_16, &
  706. #endif
  707. IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG
  708. end interface
  709. public :: IEEE_SUPPORT_UNDERFLOW_CONTROL
  710. ! Interface to the FPU-specific function
  711. interface
  712. pure integer function support_underflow_control_helper(kind) &
  713. bind(c, name="_gfortrani_support_fpu_underflow_control")
  714. integer, intent(in), value :: kind
  715. end function
  716. end interface
  717. ! IEEE_SUPPORT_* generic functions
  718. #if defined(HAVE_GFC_REAL_10) && defined(HAVE_GFC_REAL_16)
  719. # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_16, NAME/**/_NOARG
  720. #elif defined(HAVE_GFC_REAL_10)
  721. # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_NOARG
  722. #elif defined(HAVE_GFC_REAL_16)
  723. # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_16, NAME/**/_NOARG
  724. #else
  725. # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_NOARG
  726. #endif
  727. #define SUPPORTGENERIC(NAME) \
  728. interface NAME ; module procedure MACRO1(NAME) ; end interface ; \
  729. public :: NAME
  730. SUPPORTGENERIC(IEEE_SUPPORT_DATATYPE)
  731. SUPPORTGENERIC(IEEE_SUPPORT_DENORMAL)
  732. SUPPORTGENERIC(IEEE_SUPPORT_SUBNORMAL)
  733. SUPPORTGENERIC(IEEE_SUPPORT_DIVIDE)
  734. SUPPORTGENERIC(IEEE_SUPPORT_INF)
  735. SUPPORTGENERIC(IEEE_SUPPORT_IO)
  736. SUPPORTGENERIC(IEEE_SUPPORT_NAN)
  737. SUPPORTGENERIC(IEEE_SUPPORT_SQRT)
  738. SUPPORTGENERIC(IEEE_SUPPORT_STANDARD)
  739. contains
  740. ! Equality operators for IEEE_CLASS_TYPE and IEEE_ROUNDING_MODE
  741. elemental logical function IEEE_CLASS_TYPE_EQ (X, Y) result(res)
  742. implicit none
  743. type(IEEE_CLASS_TYPE), intent(in) :: X, Y
  744. res = (X%hidden == Y%hidden)
  745. end function
  746. elemental logical function IEEE_CLASS_TYPE_NE (X, Y) result(res)
  747. implicit none
  748. type(IEEE_CLASS_TYPE), intent(in) :: X, Y
  749. res = (X%hidden /= Y%hidden)
  750. end function
  751. elemental logical function IEEE_ROUND_TYPE_EQ (X, Y) result(res)
  752. implicit none
  753. type(IEEE_ROUND_TYPE), intent(in) :: X, Y
  754. res = (X%hidden == Y%hidden)
  755. end function
  756. elemental logical function IEEE_ROUND_TYPE_NE (X, Y) result(res)
  757. implicit none
  758. type(IEEE_ROUND_TYPE), intent(in) :: X, Y
  759. res = (X%hidden /= Y%hidden)
  760. end function
  761. ! IEEE_SELECTED_REAL_KIND
  762. integer function IEEE_SELECTED_REAL_KIND (P, R, RADIX) result(res)
  763. implicit none
  764. integer, intent(in), optional :: P, R, RADIX
  765. ! Currently, if IEEE is supported and this module is built, it means
  766. ! all our floating-point types conform to IEEE. Hence, we simply call
  767. ! SELECTED_REAL_KIND.
  768. res = SELECTED_REAL_KIND (P, R, RADIX)
  769. end function
  770. ! IEEE_CLASS
  771. elemental function IEEE_CLASS_4 (X) result(res)
  772. implicit none
  773. real(kind=4), intent(in) :: X
  774. type(IEEE_CLASS_TYPE) :: res
  775. interface
  776. pure integer function _gfortrani_ieee_class_helper_4(val)
  777. real(kind=4), intent(in) :: val
  778. end function
  779. end interface
  780. res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_4(X))
  781. end function
  782. elemental function IEEE_CLASS_8 (X) result(res)
  783. implicit none
  784. real(kind=8), intent(in) :: X
  785. type(IEEE_CLASS_TYPE) :: res
  786. interface
  787. pure integer function _gfortrani_ieee_class_helper_8(val)
  788. real(kind=8), intent(in) :: val
  789. end function
  790. end interface
  791. res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_8(X))
  792. end function
  793. #ifdef HAVE_GFC_REAL_10
  794. elemental function IEEE_CLASS_10 (X) result(res)
  795. implicit none
  796. real(kind=10), intent(in) :: X
  797. type(IEEE_CLASS_TYPE) :: res
  798. interface
  799. pure integer function _gfortrani_ieee_class_helper_10(val)
  800. real(kind=10), intent(in) :: val
  801. end function
  802. end interface
  803. res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_10(X))
  804. end function
  805. #endif
  806. #ifdef HAVE_GFC_REAL_16
  807. elemental function IEEE_CLASS_16 (X) result(res)
  808. implicit none
  809. real(kind=16), intent(in) :: X
  810. type(IEEE_CLASS_TYPE) :: res
  811. interface
  812. pure integer function _gfortrani_ieee_class_helper_16(val)
  813. real(kind=16), intent(in) :: val
  814. end function
  815. end interface
  816. res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_16(X))
  817. end function
  818. #endif
  819. ! IEEE_VALUE
  820. elemental real(kind=4) function IEEE_VALUE_4(X, CLASS) result(res)
  821. real(kind=4), intent(in) :: X
  822. type(IEEE_CLASS_TYPE), intent(in) :: CLASS
  823. interface
  824. pure real(kind=4) function _gfortrani_ieee_value_helper_4(x)
  825. use ISO_C_BINDING, only: C_INT
  826. integer(kind=C_INT), value :: x
  827. end function
  828. end interface
  829. res = _gfortrani_ieee_value_helper_4(CLASS%hidden)
  830. end function
  831. elemental real(kind=8) function IEEE_VALUE_8(X, CLASS) result(res)
  832. real(kind=8), intent(in) :: X
  833. type(IEEE_CLASS_TYPE), intent(in) :: CLASS
  834. interface
  835. pure real(kind=8) function _gfortrani_ieee_value_helper_8(x)
  836. use ISO_C_BINDING, only: C_INT
  837. integer(kind=C_INT), value :: x
  838. end function
  839. end interface
  840. res = _gfortrani_ieee_value_helper_8(CLASS%hidden)
  841. end function
  842. #ifdef HAVE_GFC_REAL_10
  843. elemental real(kind=10) function IEEE_VALUE_10(X, CLASS) result(res)
  844. real(kind=10), intent(in) :: X
  845. type(IEEE_CLASS_TYPE), intent(in) :: CLASS
  846. interface
  847. pure real(kind=10) function _gfortrani_ieee_value_helper_10(x)
  848. use ISO_C_BINDING, only: C_INT
  849. integer(kind=C_INT), value :: x
  850. end function
  851. end interface
  852. res = _gfortrani_ieee_value_helper_10(CLASS%hidden)
  853. end function
  854. #endif
  855. #ifdef HAVE_GFC_REAL_16
  856. elemental real(kind=16) function IEEE_VALUE_16(X, CLASS) result(res)
  857. real(kind=16), intent(in) :: X
  858. type(IEEE_CLASS_TYPE), intent(in) :: CLASS
  859. interface
  860. pure real(kind=16) function _gfortrani_ieee_value_helper_16(x)
  861. use ISO_C_BINDING, only: C_INT
  862. integer(kind=C_INT), value :: x
  863. end function
  864. end interface
  865. res = _gfortrani_ieee_value_helper_16(CLASS%hidden)
  866. end function
  867. #endif
  868. ! IEEE_GET_ROUNDING_MODE
  869. subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE)
  870. implicit none
  871. type(IEEE_ROUND_TYPE), intent(out) :: ROUND_VALUE
  872. interface
  873. integer function helper() &
  874. bind(c, name="_gfortrani_get_fpu_rounding_mode")
  875. end function
  876. end interface
  877. ROUND_VALUE = IEEE_ROUND_TYPE(helper())
  878. end subroutine
  879. ! IEEE_SET_ROUNDING_MODE
  880. subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE)
  881. implicit none
  882. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  883. interface
  884. subroutine helper(val) &
  885. bind(c, name="_gfortrani_set_fpu_rounding_mode")
  886. integer, value :: val
  887. end subroutine
  888. end interface
  889. call helper(ROUND_VALUE%hidden)
  890. end subroutine
  891. ! IEEE_GET_UNDERFLOW_MODE
  892. subroutine IEEE_GET_UNDERFLOW_MODE (GRADUAL)
  893. implicit none
  894. logical, intent(out) :: GRADUAL
  895. interface
  896. integer function helper() &
  897. bind(c, name="_gfortrani_get_fpu_underflow_mode")
  898. end function
  899. end interface
  900. GRADUAL = (helper() /= 0)
  901. end subroutine
  902. ! IEEE_SET_UNDERFLOW_MODE
  903. subroutine IEEE_SET_UNDERFLOW_MODE (GRADUAL)
  904. implicit none
  905. logical, intent(in) :: GRADUAL
  906. interface
  907. subroutine helper(val) &
  908. bind(c, name="_gfortrani_set_fpu_underflow_mode")
  909. integer, value :: val
  910. end subroutine
  911. end interface
  912. call helper(merge(1, 0, GRADUAL))
  913. end subroutine
  914. ! IEEE_SUPPORT_ROUNDING
  915. pure logical function IEEE_SUPPORT_ROUNDING_4 (ROUND_VALUE, X) result(res)
  916. implicit none
  917. real(kind=4), intent(in) :: X
  918. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  919. res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
  920. end function
  921. pure logical function IEEE_SUPPORT_ROUNDING_8 (ROUND_VALUE, X) result(res)
  922. implicit none
  923. real(kind=8), intent(in) :: X
  924. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  925. res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
  926. end function
  927. #ifdef HAVE_GFC_REAL_10
  928. pure logical function IEEE_SUPPORT_ROUNDING_10 (ROUND_VALUE, X) result(res)
  929. implicit none
  930. real(kind=10), intent(in) :: X
  931. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  932. res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
  933. end function
  934. #endif
  935. #ifdef HAVE_GFC_REAL_16
  936. pure logical function IEEE_SUPPORT_ROUNDING_16 (ROUND_VALUE, X) result(res)
  937. implicit none
  938. real(kind=16), intent(in) :: X
  939. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  940. res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
  941. end function
  942. #endif
  943. pure logical function IEEE_SUPPORT_ROUNDING_NOARG (ROUND_VALUE) result(res)
  944. implicit none
  945. type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
  946. res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
  947. end function
  948. ! IEEE_SUPPORT_UNDERFLOW_CONTROL
  949. pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_4 (X) result(res)
  950. implicit none
  951. real(kind=4), intent(in) :: X
  952. res = (support_underflow_control_helper(4) /= 0)
  953. end function
  954. pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_8 (X) result(res)
  955. implicit none
  956. real(kind=8), intent(in) :: X
  957. res = (support_underflow_control_helper(8) /= 0)
  958. end function
  959. #ifdef HAVE_GFC_REAL_10
  960. pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_10 (X) result(res)
  961. implicit none
  962. real(kind=10), intent(in) :: X
  963. res = (support_underflow_control_helper(10) /= 0)
  964. end function
  965. #endif
  966. #ifdef HAVE_GFC_REAL_16
  967. pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_16 (X) result(res)
  968. implicit none
  969. real(kind=16), intent(in) :: X
  970. res = (support_underflow_control_helper(16) /= 0)
  971. end function
  972. #endif
  973. pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG () result(res)
  974. implicit none
  975. res = (support_underflow_control_helper(4) /= 0 &
  976. .and. support_underflow_control_helper(8) /= 0 &
  977. #ifdef HAVE_GFC_REAL_10
  978. .and. support_underflow_control_helper(10) /= 0 &
  979. #endif
  980. #ifdef HAVE_GFC_REAL_16
  981. .and. support_underflow_control_helper(16) /= 0 &
  982. #endif
  983. )
  984. end function
  985. ! IEEE_SUPPORT_* functions
  986. #define SUPPORTMACRO(NAME, INTKIND, VALUE) \
  987. pure logical function NAME/**/_/**/INTKIND (X) result(res) ; \
  988. implicit none ; \
  989. real(INTKIND), intent(in) :: X(..) ; \
  990. res = VALUE ; \
  991. end function
  992. #define SUPPORTMACRO_NOARG(NAME, VALUE) \
  993. pure logical function NAME/**/_NOARG () result(res) ; \
  994. implicit none ; \
  995. res = VALUE ; \
  996. end function
  997. ! IEEE_SUPPORT_DATATYPE
  998. SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,4,.true.)
  999. SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,8,.true.)
  1000. #ifdef HAVE_GFC_REAL_10
  1001. SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,10,.true.)
  1002. #endif
  1003. #ifdef HAVE_GFC_REAL_16
  1004. SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,16,.true.)
  1005. #endif
  1006. SUPPORTMACRO_NOARG(IEEE_SUPPORT_DATATYPE,.true.)
  1007. ! IEEE_SUPPORT_DENORMAL and IEEE_SUPPORT_SUBNORMAL
  1008. SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,4,.true.)
  1009. SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,8,.true.)
  1010. #ifdef HAVE_GFC_REAL_10
  1011. SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,10,.true.)
  1012. #endif
  1013. #ifdef HAVE_GFC_REAL_16
  1014. SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,16,.true.)
  1015. #endif
  1016. SUPPORTMACRO_NOARG(IEEE_SUPPORT_DENORMAL,.true.)
  1017. SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,4,.true.)
  1018. SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,8,.true.)
  1019. #ifdef HAVE_GFC_REAL_10
  1020. SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,10,.true.)
  1021. #endif
  1022. #ifdef HAVE_GFC_REAL_16
  1023. SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,16,.true.)
  1024. #endif
  1025. SUPPORTMACRO_NOARG(IEEE_SUPPORT_SUBNORMAL,.true.)
  1026. ! IEEE_SUPPORT_DIVIDE
  1027. SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,4,.true.)
  1028. SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,8,.true.)
  1029. #ifdef HAVE_GFC_REAL_10
  1030. SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,10,.true.)
  1031. #endif
  1032. #ifdef HAVE_GFC_REAL_16
  1033. SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,16,.true.)
  1034. #endif
  1035. SUPPORTMACRO_NOARG(IEEE_SUPPORT_DIVIDE,.true.)
  1036. ! IEEE_SUPPORT_INF
  1037. SUPPORTMACRO(IEEE_SUPPORT_INF,4,.true.)
  1038. SUPPORTMACRO(IEEE_SUPPORT_INF,8,.true.)
  1039. #ifdef HAVE_GFC_REAL_10
  1040. SUPPORTMACRO(IEEE_SUPPORT_INF,10,.true.)
  1041. #endif
  1042. #ifdef HAVE_GFC_REAL_16
  1043. SUPPORTMACRO(IEEE_SUPPORT_INF,16,.true.)
  1044. #endif
  1045. SUPPORTMACRO_NOARG(IEEE_SUPPORT_INF,.true.)
  1046. ! IEEE_SUPPORT_IO
  1047. SUPPORTMACRO(IEEE_SUPPORT_IO,4,.true.)
  1048. SUPPORTMACRO(IEEE_SUPPORT_IO,8,.true.)
  1049. #ifdef HAVE_GFC_REAL_10
  1050. SUPPORTMACRO(IEEE_SUPPORT_IO,10,.true.)
  1051. #endif
  1052. #ifdef HAVE_GFC_REAL_16
  1053. SUPPORTMACRO(IEEE_SUPPORT_IO,16,.true.)
  1054. #endif
  1055. SUPPORTMACRO_NOARG(IEEE_SUPPORT_IO,.true.)
  1056. ! IEEE_SUPPORT_NAN
  1057. SUPPORTMACRO(IEEE_SUPPORT_NAN,4,.true.)
  1058. SUPPORTMACRO(IEEE_SUPPORT_NAN,8,.true.)
  1059. #ifdef HAVE_GFC_REAL_10
  1060. SUPPORTMACRO(IEEE_SUPPORT_NAN,10,.true.)
  1061. #endif
  1062. #ifdef HAVE_GFC_REAL_16
  1063. SUPPORTMACRO(IEEE_SUPPORT_NAN,16,.true.)
  1064. #endif
  1065. SUPPORTMACRO_NOARG(IEEE_SUPPORT_NAN,.true.)
  1066. ! IEEE_SUPPORT_SQRT
  1067. SUPPORTMACRO(IEEE_SUPPORT_SQRT,4,.true.)
  1068. SUPPORTMACRO(IEEE_SUPPORT_SQRT,8,.true.)
  1069. #ifdef HAVE_GFC_REAL_10
  1070. SUPPORTMACRO(IEEE_SUPPORT_SQRT,10,.true.)
  1071. #endif
  1072. #ifdef HAVE_GFC_REAL_16
  1073. SUPPORTMACRO(IEEE_SUPPORT_SQRT,16,.true.)
  1074. #endif
  1075. SUPPORTMACRO_NOARG(IEEE_SUPPORT_SQRT,.true.)
  1076. ! IEEE_SUPPORT_STANDARD
  1077. SUPPORTMACRO(IEEE_SUPPORT_STANDARD,4,.true.)
  1078. SUPPORTMACRO(IEEE_SUPPORT_STANDARD,8,.true.)
  1079. #ifdef HAVE_GFC_REAL_10
  1080. SUPPORTMACRO(IEEE_SUPPORT_STANDARD,10,.true.)
  1081. #endif
  1082. #ifdef HAVE_GFC_REAL_16
  1083. SUPPORTMACRO(IEEE_SUPPORT_STANDARD,16,.true.)
  1084. #endif
  1085. SUPPORTMACRO_NOARG(IEEE_SUPPORT_STANDARD,.true.)
  1086. end module IEEE_ARITHMETIC