Merge -r 127928:132243 from trunk
[official-gcc.git] / libgcc / config / libbid / bid_flag_operations.c
blobd025e635f88cd87f829d4a48d737d452184f82ee
1 /* Copyright (C) 2007 Free Software Foundation, Inc.
3 This file is part of GCC.
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.
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.)
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.
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. */
29 /*****************************************************************************
30 * Non-computational Operations on Flags:
31 ****************************************************************************/
33 #include "bid_internal.h"
35 // Note the following definitions from bid_conf.h: if the status flags are
36 // global, they have a fixed name recognized by the library functions:
37 // _IDEC_glbflags; pfpsf, defined as &_IDEC_glbflags, can be used instead; no
38 // argument is passed for the status flags to the library functions; if the
39 // status flags are local then they are passed as an arument, always by
40 // reference, to the library functions
42 // #if !DECIMAL_GLOBAL_EXCEPTION_FLAGS
43 // #define _EXC_FLAGS_PARAM , _IDEC_flags *pfpsf
44 // #else
45 // extern _IDEC_flags _IDEC_glbflags;
46 // #define _EXC_FLAGS_PARAM
47 // #define pfpsf &_IDEC_glbflags
48 // #endif
50 #if DECIMAL_CALL_BY_REFERENCE
51 void
52 signalException (_IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
53 // *pflagsmask is the logical OR of the flags to be set, e.g.
54 // *pflagsmask =INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
55 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to set all five IEEE 754R
56 // exception flags
57 *pfpsf = *pfpsf | (*pflagsmask & BID_IEEE_FLAGS);
59 #else
60 void
61 signalException (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
62 // flagsmask is the logical OR of the flags to be set, e.g.
63 // flagsmask = INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
64 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to set all five IEEE 754R
65 // exception flags
66 *pfpsf = *pfpsf | (flagsmask & BID_IEEE_FLAGS);
68 #endif
70 #if DECIMAL_CALL_BY_REFERENCE
71 void
72 lowerFlags (_IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
73 // *pflagsmask is the logical OR of the flags to be cleared, e.g.
74 // *pflagsmask =INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
75 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R
76 // exception flags
77 *pfpsf = *pfpsf & ~(*pflagsmask & BID_IEEE_FLAGS);
79 #else
80 void
81 lowerFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
82 // flagsmask is the logical OR of the flags to be cleared, e.g.
83 // flagsmask = INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
84 // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R
85 // exception flags
86 *pfpsf = *pfpsf & ~(flagsmask & BID_IEEE_FLAGS);
88 #endif
90 #if DECIMAL_CALL_BY_REFERENCE
91 void
92 testFlags (_IDEC_flags * praised,
93 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
94 // *praised is a pointer to the result, i.e. the logical OR of the flags
95 // selected by *pflagsmask that are set; e.g. if
96 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
97 // and only the invalid and inexact flags are raised (set) then upon return
98 // *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
99 *praised = *pfpsf & (*pflagsmask & BID_IEEE_FLAGS);
101 #else
102 _IDEC_flags
103 testFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
104 _IDEC_flags raised;
105 // the raturn value raised is the logical OR of the flags
106 // selected by flagsmask, that are set; e.g. if
107 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
108 // only the invalid and inexact flags are raised (set) then the return value
109 // is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
110 raised = *pfpsf & (flagsmask & BID_IEEE_FLAGS);
111 return (raised);
113 #endif
115 #if DECIMAL_CALL_BY_REFERENCE
116 void
117 testSavedFlags (_IDEC_flags * praised, _IDEC_flags * psavedflags,
118 _IDEC_flags * pflagsmask) {
119 // *praised is a pointer to the result, i.e. the logical OR of the flags
120 // selected by *pflagsmask that are set in *psavedflags; e.g. if
121 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
122 // and only the invalid and inexact flags are raised (set) in *psavedflags
123 // then upon return *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
124 // Note that the flags could be saved in a global variable, but this function
125 // would still expect that value as an argument passed by reference
126 *praised = *psavedflags & (*pflagsmask & BID_IEEE_FLAGS);
128 #else
129 _IDEC_flags
130 testSavedFlags (_IDEC_flags savedflags, _IDEC_flags flagsmask) {
131 _IDEC_flags raised;
132 // the raturn value raised is the logical OR of the flags
133 // selected by flagsmask, that are set in savedflags; e.g. if
134 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
135 // only the invalid and inexact flags are raised (set) in savedflags
136 // then the return value is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
137 // Note that the flags could be saved in a global variable, but this function
138 // would still expect that value as an argument passed by value
139 raised = savedflags & (flagsmask & BID_IEEE_FLAGS);
140 return (raised);
142 #endif
144 #if DECIMAL_CALL_BY_REFERENCE
145 void
146 restoreFlags (_IDEC_flags * pflagsvalues,
147 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
148 // restore the status flags selected by *pflagsmask to the values speciafied
149 // (as a logical OR) in *pflagsvalues; e.g. if
150 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
151 // and only the invalid and inexact flags are raised (set) in *pflagsvalues
152 // then upon return the invalid status flag will be set, the underflow status
153 // flag will be clear, and the inexact status flag will be set
154 *pfpsf = *pfpsf & ~(*pflagsmask & BID_IEEE_FLAGS);
155 // clear flags that have to be restored
156 *pfpsf = *pfpsf | (*pflagsvalues & (*pflagsmask & BID_IEEE_FLAGS));
157 // restore flags
159 #else
160 void
161 restoreFlags (_IDEC_flags flagsvalues,
162 _IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
163 // restore the status flags selected by flagsmask to the values speciafied
164 // (as a logical OR) in flagsvalues; e.g. if
165 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
166 // and only the invalid and inexact flags are raised (set) in flagsvalues
167 // then upon return the invalid status flag will be set, the underflow status
168 // flag will be clear, and the inexact status flag will be set
169 *pfpsf = *pfpsf & ~(flagsmask & BID_IEEE_FLAGS);
170 // clear flags that have to be restored
171 *pfpsf = *pfpsf | (flagsvalues & (flagsmask & BID_IEEE_FLAGS));
172 // restore flags
174 #endif
176 #if DECIMAL_CALL_BY_REFERENCE
177 void
178 saveFlags (_IDEC_flags * pflagsvalues,
179 _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
180 // return in *pflagsvalues the status flags specified (as a logical OR) in
181 // *pflagsmask; e.g. if
182 // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
183 // and only the invalid and inexact flags are raised (set) in the status word,
184 // then upon return the value in *pflagsvalues will have the invalid status
185 // flag set, the underflow status flag clear, and the inexact status flag set
186 *pflagsvalues = *pfpsf & (*pflagsmask & BID_IEEE_FLAGS);
188 #else
189 _IDEC_flags
190 saveFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
191 _IDEC_flags flagsvalues;
192 // return the status flags specified (as a logical OR) in flagsmask; e.g. if
193 // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
194 // and only the invalid and inexact flags are raised (set) in the status word,
195 // then the return value will have the invalid status flag set, the
196 // underflow status flag clear, and the inexact status flag set
197 flagsvalues = *pfpsf & (flagsmask & BID_IEEE_FLAGS);
198 return (flagsvalues);
200 #endif
202 // Note the following definitions from bid_conf.h (rearranged): if the rounding
203 // mode is global, it has a fixed name recognized by the library functions:
204 // _IDEC_glbround; rnd_mode, defined as &_IDEC_glbround, can be used instead; no
205 // argument is passed for the rounding mode to the library functions; if the
206 // rounding mode is local then it is passed as an arument, by reference or by
207 // value, to the library functions
209 // #if DECIMAL_CALL_BY_REFERENCE
210 // #if !DECIMAL_GLOBAL_ROUNDING
211 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
212 // #else
213 // #define _RND_MODE_PARAM
214 // #define rnd_mode _IDEC_glbround
215 // #endif
216 // #else
217 // #if !DECIMAL_GLOBAL_ROUNDING
218 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
219 // #else
220 // #define _RND_MODE_PARAM
221 // #define rnd_mode _IDEC_glbround
222 // #endif
223 // #endif
225 #if DECIMAL_CALL_BY_REFERENCE
226 #if !DECIMAL_GLOBAL_ROUNDING
227 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
228 void
229 getDecimalRoundingDirection (_IDEC_round * rounding_mode
230 _RND_MODE_PARAM) {
231 // returns the current rounding mode
232 *rounding_mode = *prnd_mode;
234 #else
235 // #define _RND_MODE_PARAM
236 // #define rnd_mode _IDEC_glbround
237 void
238 getDecimalRoundingDirection (_IDEC_round * rounding_mode
239 _RND_MODE_PARAM) {
240 // returns the current rounding mode
241 *rounding_mode = rnd_mode;
243 #endif
244 #else
245 #if !DECIMAL_GLOBAL_ROUNDING
246 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
247 _IDEC_round
248 getDecimalRoundingDirection (_IDEC_round rnd_mode) {
249 // returns the current rounding mode
250 return (rnd_mode);
252 #else
253 // #define _RND_MODE_PARAM
254 // #define rnd_mode _IDEC_glbround
255 _IDEC_round
256 getDecimalRoundingDirection (void) {
257 // returns the current rounding mode
258 return (rnd_mode);
260 #endif
261 #endif
263 #if DECIMAL_CALL_BY_REFERENCE
264 #if !DECIMAL_GLOBAL_ROUNDING
265 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
266 void
267 setDecimalRoundingDirection (_IDEC_round * rounding_mode
268 _RND_MODE_PARAM) {
269 // sets the current rounding mode to the value in *rounding_mode, if valid
270 if (*rounding_mode == ROUNDING_TO_NEAREST ||
271 *rounding_mode == ROUNDING_DOWN ||
272 *rounding_mode == ROUNDING_UP ||
273 *rounding_mode == ROUNDING_TO_ZERO ||
274 *rounding_mode == ROUNDING_TIES_AWAY) {
275 *prnd_mode = *rounding_mode;
278 #else
279 // #define _RND_MODE_PARAM
280 // #define rnd_mode _IDEC_glbround
281 void
282 setDecimalRoundingDirection (_IDEC_round * rounding_mode
284 // sets the global rounding mode to the value in *rounding_mode, if valid
285 if (*rounding_mode == ROUNDING_TO_NEAREST ||
286 *rounding_mode == ROUNDING_DOWN ||
287 *rounding_mode == ROUNDING_UP ||
288 *rounding_mode == ROUNDING_TO_ZERO ||
289 *rounding_mode == ROUNDING_TIES_AWAY) {
290 rnd_mode = *rounding_mode;
293 #endif
294 #else
295 #if !DECIMAL_GLOBAL_ROUNDING
296 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
297 _IDEC_round
298 setDecimalRoundingDirection (_IDEC_round rounding_mode _RND_MODE_PARAM) {
299 // sets the current rounding mode to the value in rounding_mode;
300 // however, when arguments are passed by value and the rounding mode
301 // is a local variable, this is not of any use
302 if (rounding_mode == ROUNDING_TO_NEAREST ||
303 rounding_mode == ROUNDING_DOWN ||
304 rounding_mode == ROUNDING_UP ||
305 rounding_mode == ROUNDING_TO_ZERO ||
306 rounding_mode == ROUNDING_TIES_AWAY) {
307 return (rounding_mode);
309 return (rnd_mode);
311 #else
312 // #define _RND_MODE_PARAM
313 // #define rnd_mode _IDEC_glbround
314 void
315 setDecimalRoundingDirection (_IDEC_round rounding_mode) {
316 // sets the current rounding mode to the value in rounding_mode, if valid;
317 if (rounding_mode == ROUNDING_TO_NEAREST ||
318 rounding_mode == ROUNDING_DOWN ||
319 rounding_mode == ROUNDING_UP ||
320 rounding_mode == ROUNDING_TO_ZERO ||
321 rounding_mode == ROUNDING_TIES_AWAY) {
322 rnd_mode = rounding_mode;
325 #endif
326 #endif
328 #if DECIMAL_CALL_BY_REFERENCE
329 void
330 is754 (int *retval) {
331 *retval = 0;
333 #else
335 is754 (void) {
336 return 0;
338 #endif
340 #if DECIMAL_CALL_BY_REFERENCE
341 void
342 is754R (int *retval) {
343 *retval = 1;
345 #else
347 is754R (void) {
348 return 1;
350 #endif