annotate libgfortran/ieee/ieee_helper.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Helper functions in C for IEEE modules
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2013-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of the GNU Fortran runtime library (libgfortran).
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 Libgfortran is free software; you can redistribute it and/or
kono
parents:
diff changeset
8 modify it under the terms of the GNU General Public
kono
parents:
diff changeset
9 License as published by the Free Software Foundation; either
kono
parents:
diff changeset
10 version 3 of the License, or (at your option) any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 Libgfortran is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 #include "libgfortran.h"
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 /* Prototypes. */
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 extern int ieee_class_helper_4 (GFC_REAL_4 *);
kono
parents:
diff changeset
31 internal_proto(ieee_class_helper_4);
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 extern int ieee_class_helper_8 (GFC_REAL_8 *);
kono
parents:
diff changeset
34 internal_proto(ieee_class_helper_8);
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 #ifdef HAVE_GFC_REAL_10
kono
parents:
diff changeset
37 extern int ieee_class_helper_10 (GFC_REAL_10 *);
kono
parents:
diff changeset
38 internal_proto(ieee_class_helper_10);
kono
parents:
diff changeset
39 #endif
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 #ifdef HAVE_GFC_REAL_16
kono
parents:
diff changeset
42 extern int ieee_class_helper_16 (GFC_REAL_16 *);
kono
parents:
diff changeset
43 internal_proto(ieee_class_helper_16);
kono
parents:
diff changeset
44 #endif
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 /* Enumeration of the possible floating-point types. These values
kono
parents:
diff changeset
47 correspond to the hidden arguments of the IEEE_CLASS_TYPE
kono
parents:
diff changeset
48 derived-type of IEEE_ARITHMETIC. */
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 enum { IEEE_OTHER_VALUE = 0, IEEE_SIGNALING_NAN, IEEE_QUIET_NAN,
kono
parents:
diff changeset
51 IEEE_NEGATIVE_INF, IEEE_NEGATIVE_NORMAL, IEEE_NEGATIVE_DENORMAL,
kono
parents:
diff changeset
52 IEEE_NEGATIVE_ZERO, IEEE_POSITIVE_ZERO, IEEE_POSITIVE_DENORMAL,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
53 IEEE_POSITIVE_NORMAL, IEEE_POSITIVE_INF, IEEE_SUBNORMAL,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
54 IEEE_NEGATIVE_SUBNORMAL, IEEE_POSITIVE_SUBNORMAL };
111
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 #define CLASSMACRO(TYPE) \
kono
parents:
diff changeset
57 int ieee_class_helper_ ## TYPE (GFC_REAL_ ## TYPE *value) \
kono
parents:
diff changeset
58 { \
kono
parents:
diff changeset
59 int res = __builtin_fpclassify (IEEE_QUIET_NAN, IEEE_POSITIVE_INF, \
kono
parents:
diff changeset
60 IEEE_POSITIVE_NORMAL, \
kono
parents:
diff changeset
61 IEEE_POSITIVE_DENORMAL, \
kono
parents:
diff changeset
62 IEEE_POSITIVE_ZERO, *value); \
kono
parents:
diff changeset
63 \
kono
parents:
diff changeset
64 if (__builtin_signbit (*value)) \
kono
parents:
diff changeset
65 { \
kono
parents:
diff changeset
66 if (res == IEEE_POSITIVE_NORMAL) \
kono
parents:
diff changeset
67 return IEEE_NEGATIVE_NORMAL; \
kono
parents:
diff changeset
68 else if (res == IEEE_POSITIVE_DENORMAL) \
kono
parents:
diff changeset
69 return IEEE_NEGATIVE_DENORMAL; \
kono
parents:
diff changeset
70 else if (res == IEEE_POSITIVE_ZERO) \
kono
parents:
diff changeset
71 return IEEE_NEGATIVE_ZERO; \
kono
parents:
diff changeset
72 else if (res == IEEE_POSITIVE_INF) \
kono
parents:
diff changeset
73 return IEEE_NEGATIVE_INF; \
kono
parents:
diff changeset
74 } \
kono
parents:
diff changeset
75 \
kono
parents:
diff changeset
76 if (res == IEEE_QUIET_NAN) \
kono
parents:
diff changeset
77 { \
kono
parents:
diff changeset
78 /* TODO: Handle signaling NaNs */ \
kono
parents:
diff changeset
79 return res; \
kono
parents:
diff changeset
80 } \
kono
parents:
diff changeset
81 \
kono
parents:
diff changeset
82 return res; \
kono
parents:
diff changeset
83 }
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 CLASSMACRO(4)
kono
parents:
diff changeset
86 CLASSMACRO(8)
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 #ifdef HAVE_GFC_REAL_10
kono
parents:
diff changeset
89 CLASSMACRO(10)
kono
parents:
diff changeset
90 #endif
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 #ifdef HAVE_GFC_REAL_16
kono
parents:
diff changeset
93 CLASSMACRO(16)
kono
parents:
diff changeset
94 #endif
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 #define GFC_FPE_ALL (GFC_FPE_INVALID | GFC_FPE_DENORMAL | \
kono
parents:
diff changeset
98 GFC_FPE_ZERO | GFC_FPE_OVERFLOW | \
kono
parents:
diff changeset
99 GFC_FPE_UNDERFLOW | GFC_FPE_INEXACT)
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 /* Functions to save and restore floating-point state, clear and restore
kono
parents:
diff changeset
102 exceptions on procedure entry/exit. The rules we follow are set
kono
parents:
diff changeset
103 in Fortran 2008's 14.3 paragraph 3, note 14.4, 14.4 paragraph 4,
kono
parents:
diff changeset
104 14.5 paragraph 2, and 14.6 paragraph 1. */
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 void ieee_procedure_entry (void *);
kono
parents:
diff changeset
107 export_proto(ieee_procedure_entry);
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 void
kono
parents:
diff changeset
110 ieee_procedure_entry (void *state)
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 /* Save the floating-point state in the space provided by the caller. */
kono
parents:
diff changeset
113 get_fpu_state (state);
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 /* Clear the floating-point exceptions. */
kono
parents:
diff changeset
116 set_fpu_except_flags (0, GFC_FPE_ALL);
kono
parents:
diff changeset
117 }
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 void ieee_procedure_exit (void *);
kono
parents:
diff changeset
121 export_proto(ieee_procedure_exit);
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 void
kono
parents:
diff changeset
124 ieee_procedure_exit (void *state)
kono
parents:
diff changeset
125 {
kono
parents:
diff changeset
126 /* Get the flags currently signaling. */
kono
parents:
diff changeset
127 int flags = get_fpu_except_flags ();
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 /* Restore the floating-point state we had on entry. */
kono
parents:
diff changeset
130 set_fpu_state (state);
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 /* And re-raised the flags that were raised since entry. */
kono
parents:
diff changeset
133 set_fpu_except_flags (flags, 0);
kono
parents:
diff changeset
134 }
kono
parents:
diff changeset
135