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
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
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
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
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
45 // extern _IDEC_flags _IDEC_glbflags;
46 // #define _EXC_FLAGS_PARAM
47 // #define pfpsf &_IDEC_glbflags
50 #if DECIMAL_CALL_BY_REFERENCE
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
57 *pfpsf
= *pfpsf
| (*pflagsmask
& BID_IEEE_FLAGS
);
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
66 *pfpsf
= *pfpsf
| (flagsmask
& BID_IEEE_FLAGS
);
70 #if DECIMAL_CALL_BY_REFERENCE
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
77 *pfpsf
= *pfpsf
& ~(*pflagsmask
& BID_IEEE_FLAGS
);
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
86 *pfpsf
= *pfpsf
& ~(flagsmask
& BID_IEEE_FLAGS
);
90 #if DECIMAL_CALL_BY_REFERENCE
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
);
103 testFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM
) {
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
);
115 #if DECIMAL_CALL_BY_REFERENCE
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
);
130 testSavedFlags (_IDEC_flags savedflags
, _IDEC_flags flagsmask
) {
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
);
144 #if DECIMAL_CALL_BY_REFERENCE
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
));
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
));
176 #if DECIMAL_CALL_BY_REFERENCE
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
);
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
);
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
213 // #define _RND_MODE_PARAM
214 // #define rnd_mode _IDEC_glbround
217 // #if !DECIMAL_GLOBAL_ROUNDING
218 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
220 // #define _RND_MODE_PARAM
221 // #define rnd_mode _IDEC_glbround
225 #if DECIMAL_CALL_BY_REFERENCE
226 #if !DECIMAL_GLOBAL_ROUNDING
227 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
229 getDecimalRoundingDirection (_IDEC_round
* rounding_mode
231 // returns the current rounding mode
232 *rounding_mode
= *prnd_mode
;
235 // #define _RND_MODE_PARAM
236 // #define rnd_mode _IDEC_glbround
238 getDecimalRoundingDirection (_IDEC_round
* rounding_mode
240 // returns the current rounding mode
241 *rounding_mode
= rnd_mode
;
245 #if !DECIMAL_GLOBAL_ROUNDING
246 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
248 getDecimalRoundingDirection (_IDEC_round rnd_mode
) {
249 // returns the current rounding mode
253 // #define _RND_MODE_PARAM
254 // #define rnd_mode _IDEC_glbround
256 getDecimalRoundingDirection (void) {
257 // returns the current rounding mode
263 #if DECIMAL_CALL_BY_REFERENCE
264 #if !DECIMAL_GLOBAL_ROUNDING
265 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
267 setDecimalRoundingDirection (_IDEC_round
* rounding_mode
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
;
279 // #define _RND_MODE_PARAM
280 // #define rnd_mode _IDEC_glbround
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
;
295 #if !DECIMAL_GLOBAL_ROUNDING
296 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
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
);
312 // #define _RND_MODE_PARAM
313 // #define rnd_mode _IDEC_glbround
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
;
328 #if DECIMAL_CALL_BY_REFERENCE
330 is754 (int *retval
) {
340 #if DECIMAL_CALL_BY_REFERENCE
342 is754R (int *retval
) {