Merged with libbbid branch at revision 126349.
[gcc.git] / libgcc / config / libbid / bid_flag_operations.c
1 /* Copyright (C) 2007 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
17 executable.)
18
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
27 02110-1301, USA. */
28
29 /*****************************************************************************
30 * Non-computational Operations on Flags:
31 ****************************************************************************/
32
33 #include "bid_conf.h"
34 #include "bid_functions.h"
35 #include "bid_internal.h"
36
37 // Note the following definitions from bid_conf.h: if the status flags are
38 // global, they have a fixed name recognized by the library functions:
39 // __bid_IDEC_glbflags; pfpsf, defined as &__bid_IDEC_glbflags, can be used instead; no
40 // argument is passed for the status flags to the library functions; if the
41 // status flags are local then they are passed as an arument, always by
42 // reference, to the library functions
43 //
44 // #if !DECIMAL_GLOBAL_EXCEPTION_FLAGS
45 // #define _EXC_FLAGS_PARAM , _IDEC_flags *pfpsf
46 // #else
47 // extern _IDEC_flags __bid_IDEC_glbflags;
48 // #define _EXC_FLAGS_PARAM
49 // #define pfpsf &__bid_IDEC_glbflags
50 // #endif
51
52 #if DECIMAL_CALL_BY_REFERENCE
53 void
54 __bid_lowerFlags (_IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
55 // *pflagsmask is the logical OR of the flags to be cleared, e.g.
56 // *pflagsmask =INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
57 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R
58 // exception flags
59 *pfpsf = *pfpsf & ~(*pflagsmask);
60 }
61 #else
62 void
63 __bid_lowerFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
64 // flagsmask is the logical OR of the flags to be cleared, e.g.
65 // flagsmask = INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
66 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R
67 // exception flags
68 *pfpsf = *pfpsf & ~(flagsmask);
69 }
70 #endif
71
72 #if DECIMAL_CALL_BY_REFERENCE
73 void
74 __bid_testFlags (_IDEC_flags * praised,
75 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
76 // *praised is a pointer to the result, i.e. the logical OR of the flags
77 // selected by *pflagsmask that are set; e.g. if
78 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
79 // and only the invalid and inexact flags are raised (set) then upon return
80 // *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
81 *praised = *pfpsf & *pflagsmask;
82 }
83 #else
84 _IDEC_flags
85 __bid_testFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
86 _IDEC_flags raised;
87 // the raturn value raised is the logical OR of the flags
88 // selected by flagsmask, that are set; e.g. if
89 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
90 // only the invalid and inexact flags are raised (set) then the return value
91 // is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
92 raised = *pfpsf & flagsmask;
93 return (raised);
94 }
95 #endif
96
97 #if DECIMAL_CALL_BY_REFERENCE
98 void
99 __bid_testSavedFlags (_IDEC_flags * praised, _IDEC_flags * psavedflags,
100 _IDEC_flags * pflagsmask) {
101 // *praised is a pointer to the result, i.e. the logical OR of the flags
102 // selected by *pflagsmask that are set in *psavedflags; e.g. if
103 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
104 // and only the invalid and inexact flags are raised (set) in *psavedflags
105 // then upon return *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
106 // Note that the flags could be saved in a global variable, but this function
107 // would still expect that value as an argument passed by reference
108 *praised = *psavedflags & *pflagsmask;
109 }
110 #else
111 _IDEC_flags
112 __bid_testSavedFlags (_IDEC_flags savedflags, _IDEC_flags flagsmask) {
113 _IDEC_flags raised;
114 // the raturn value raised is the logical OR of the flags
115 // selected by flagsmask, that are set in savedflags; e.g. if
116 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
117 // only the invalid and inexact flags are raised (set) in savedflags
118 // then the return value is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
119 // Note that the flags could be saved in a global variable, but this function
120 // would still expect that value as an argument passed by value
121 raised = savedflags & flagsmask;
122 return (raised);
123 }
124 #endif
125
126 #if DECIMAL_CALL_BY_REFERENCE
127 void
128 __bid_restoreFlags (_IDEC_flags * pflagsvalues,
129 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
130 // restore the status flags selected by *pflagsmask to the values speciafied
131 // (as a logical OR) in *pflagsvalues; e.g. if
132 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
133 // and only the invalid and inexact flags are raised (set) in *pflagsvalues
134 // then upon return the invalid status flag will be set, the underflow status
135 // flag will be clear, and the inexact status flag will be set
136 *pfpsf = *pfpsf & ~(*pflagsmask); // clear flags that have to be restored
137 *pfpsf = *pfpsf | (*pflagsvalues & *pflagsmask); // restore flags
138 }
139 #else
140 void
141 __bid_restoreFlags (_IDEC_flags flagsvalues,
142 _IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
143 // restore the status flags selected by flagsmask to the values speciafied
144 // (as a logical OR) in flagsvalues; e.g. if
145 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
146 // and only the invalid and inexact flags are raised (set) in flagsvalues
147 // then upon return the invalid status flag will be set, the underflow status
148 // flag will be clear, and the inexact status flag will be set
149 *pfpsf = *pfpsf & ~flagsmask; // clear flags that have to be restored
150 *pfpsf = *pfpsf | (flagsvalues & flagsmask); // restore flags
151 }
152 #endif
153
154 #if DECIMAL_CALL_BY_REFERENCE
155 void
156 __bid_saveFlags (_IDEC_flags * pflagsvalues,
157 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
158 // return in *pflagsvalues the status flags specified (as a logical OR) in
159 // *pflagsmask; e.g. if
160 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
161 // and only the invalid and inexact flags are raised (set) in the status word,
162 // then upon return the value in *pflagsvalues will have the invalid status
163 // flag set, the underflow status flag clear, and the inexact status flag set
164 *pflagsvalues = *pfpsf & *pflagsmask;
165 }
166 #else
167 _IDEC_flags
168 __bid_saveFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
169 _IDEC_flags flagsvalues;
170 // return the status flags specified (as a logical OR) in flagsmask; e.g. if
171 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
172 // and only the invalid and inexact flags are raised (set) in the status word,
173 // then the return value will have the invalid status flag set, the
174 // underflow status flag clear, and the inexact status flag set
175 flagsvalues = *pfpsf & flagsmask;
176 return (flagsvalues);
177 }
178 #endif
179
180 // Note the following definitions from bid_conf.h (rearranged): if the rounding
181 // mode is global, it has a fixed name recognized by the library functions:
182 // __bid_IDEC_glbround; rnd_mode, defined as &__bid_IDEC_glbround, can be used instead; no
183 // argument is passed for the rounding mode to the library functions; if the
184 // rounding mode is local then it is passed as an arument, by reference or by
185 // value, to the library functions
186 //
187 // #if DECIMAL_CALL_BY_REFERENCE
188 // #if !DECIMAL_GLOBAL_ROUNDING
189 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
190 // #else
191 // #define _RND_MODE_PARAM
192 // #define rnd_mode __bid_IDEC_glbround
193 // #endif
194 // #else
195 // #if !DECIMAL_GLOBAL_ROUNDING
196 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
197 // #else
198 // #define _RND_MODE_PARAM
199 // #define rnd_mode __bid_IDEC_glbround
200 // #endif
201 // #endif
202
203 #if DECIMAL_CALL_BY_REFERENCE
204 #if !DECIMAL_GLOBAL_ROUNDING
205 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
206 void
207 __bid_getDecimalRoundingDirection (_IDEC_round * rounding_mode
208 _RND_MODE_PARAM) {
209 // returns the current rounding mode
210 *rounding_mode = *prnd_mode;
211 }
212 #else
213 // #define _RND_MODE_PARAM
214 // #define rnd_mode __bid_IDEC_glbround
215 void
216 __bid_getDecimalRoundingDirection (_IDEC_round * rounding_mode
217 _RND_MODE_PARAM) {
218 // returns the current rounding mode
219 *rounding_mode = rnd_mode;
220 }
221 #endif
222 #else
223 #if !DECIMAL_GLOBAL_ROUNDING
224 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
225 _IDEC_round
226 __bid_getDecimalRoundingDirection (_IDEC_round rnd_mode) {
227 // returns the current rounding mode
228 return (rnd_mode);
229 }
230 #else
231 // #define _RND_MODE_PARAM
232 // #define rnd_mode __bid_IDEC_glbround
233 _IDEC_round
234 __bid_getDecimalRoundingDirection (void) {
235 // returns the current rounding mode
236 return (rnd_mode);
237 }
238 #endif
239 #endif
240
241 #if DECIMAL_CALL_BY_REFERENCE
242 #if !DECIMAL_GLOBAL_ROUNDING
243 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
244 void
245 __bid_setDecimalRoundingDirection (_IDEC_round * rounding_mode
246 _RND_MODE_PARAM) {
247 // sets the current rounding mode to the value in *rounding_mode
248 *prnd_mode = *rounding_mode;
249 }
250 #else
251 // #define _RND_MODE_PARAM
252 // #define rnd_mode __bid_IDEC_glbround
253 void
254 __bid_setDecimalRoundingDirection (_IDEC_round * rounding_mode
255 _RND_MODE_PARAM) {
256 // sets the global rounding mode to the value in *rounding_mode
257 rnd_mode = *rounding_mode;
258 }
259 #endif
260 #else
261 #if !DECIMAL_GLOBAL_ROUNDING
262 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
263 _IDEC_round
264 __bid_setDecimalRoundingDirection (_IDEC_round rounding_mode) {
265 // sets the current rounding mode to the value in rounding_mode;
266 // however, when arguments are passed by value and the rounding mode
267 // is a local variable, this is not of any use
268 return (rounding_mode);
269 }
270 #else
271 // #define _RND_MODE_PARAM
272 // #define rnd_mode __bid_IDEC_glbround
273 void
274 __bid_setDecimalRoundingDirection (_IDEC_round rounding_mode) {
275 // sets the current rounding mode to the value in rounding_mode;
276 rnd_mode = rounding_mode;
277 }
278 #endif
279 #endif
280
281 #if DECIMAL_CALL_BY_REFERENCE
282 void
283 __bid_is754 (int *retval) {
284 *retval = 0;
285 }
286 #else
287 int
288 __bid_is754 (void) {
289 return 0;
290 }
291 #endif
292
293 #if DECIMAL_CALL_BY_REFERENCE
294 void
295 __bid_is754R (int *retval) {
296 *retval = 1;
297 }
298 #else
299 int
300 __bid_is754R (void) {
301 return 1;
302 }
303 #endif