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 ****************************************************************************/
34 #include "bid_functions.h"
35 #include "bid_internal.h"
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
44 // #if !DECIMAL_GLOBAL_EXCEPTION_FLAGS
45 // #define _EXC_FLAGS_PARAM , _IDEC_flags *pfpsf
47 // extern _IDEC_flags __bid_IDEC_glbflags;
48 // #define _EXC_FLAGS_PARAM
49 // #define pfpsf &__bid_IDEC_glbflags
52 #if DECIMAL_CALL_BY_REFERENCE
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
59 *pfpsf
= *pfpsf
& ~(*pflagsmask
);
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
68 *pfpsf
= *pfpsf
& ~(flagsmask
);
72 #if DECIMAL_CALL_BY_REFERENCE
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
;
85 __bid_testFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM
) {
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
;
97 #if DECIMAL_CALL_BY_REFERENCE
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
;
112 __bid_testSavedFlags (_IDEC_flags savedflags
, _IDEC_flags flagsmask
) {
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
;
126 #if DECIMAL_CALL_BY_REFERENCE
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
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
154 #if DECIMAL_CALL_BY_REFERENCE
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
;
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
);
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
187 // #if DECIMAL_CALL_BY_REFERENCE
188 // #if !DECIMAL_GLOBAL_ROUNDING
189 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
191 // #define _RND_MODE_PARAM
192 // #define rnd_mode __bid_IDEC_glbround
195 // #if !DECIMAL_GLOBAL_ROUNDING
196 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
198 // #define _RND_MODE_PARAM
199 // #define rnd_mode __bid_IDEC_glbround
203 #if DECIMAL_CALL_BY_REFERENCE
204 #if !DECIMAL_GLOBAL_ROUNDING
205 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
207 __bid_getDecimalRoundingDirection (_IDEC_round
* rounding_mode
209 // returns the current rounding mode
210 *rounding_mode
= *prnd_mode
;
213 // #define _RND_MODE_PARAM
214 // #define rnd_mode __bid_IDEC_glbround
216 __bid_getDecimalRoundingDirection (_IDEC_round
* rounding_mode
218 // returns the current rounding mode
219 *rounding_mode
= rnd_mode
;
223 #if !DECIMAL_GLOBAL_ROUNDING
224 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
226 __bid_getDecimalRoundingDirection (_IDEC_round rnd_mode
) {
227 // returns the current rounding mode
231 // #define _RND_MODE_PARAM
232 // #define rnd_mode __bid_IDEC_glbround
234 __bid_getDecimalRoundingDirection (void) {
235 // returns the current rounding mode
241 #if DECIMAL_CALL_BY_REFERENCE
242 #if !DECIMAL_GLOBAL_ROUNDING
243 // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
245 __bid_setDecimalRoundingDirection (_IDEC_round
* rounding_mode
247 // sets the current rounding mode to the value in *rounding_mode
248 *prnd_mode
= *rounding_mode
;
251 // #define _RND_MODE_PARAM
252 // #define rnd_mode __bid_IDEC_glbround
254 __bid_setDecimalRoundingDirection (_IDEC_round
* rounding_mode
256 // sets the global rounding mode to the value in *rounding_mode
257 rnd_mode
= *rounding_mode
;
261 #if !DECIMAL_GLOBAL_ROUNDING
262 // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
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
);
271 // #define _RND_MODE_PARAM
272 // #define rnd_mode __bid_IDEC_glbround
274 __bid_setDecimalRoundingDirection (_IDEC_round rounding_mode
) {
275 // sets the current rounding mode to the value in rounding_mode;
276 rnd_mode
= rounding_mode
;
281 #if DECIMAL_CALL_BY_REFERENCE
283 __bid_is754 (int *retval
) {
293 #if DECIMAL_CALL_BY_REFERENCE
295 __bid_is754R (int *retval
) {
300 __bid_is754R (void) {