]>
Commit | Line | Data |
---|---|---|
e9a25f70 | 1 | /* Definitions of floating-point access for GNU compiler. |
af841dbd JL |
2 | Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998, |
3 | 1999, 2000 Free Software Foundation, Inc. | |
0694b47c | 4 | |
1322177d | 5 | This file is part of GCC. |
0694b47c | 6 | |
1322177d LB |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 2, or (at your option) any later | |
10 | version. | |
0694b47c | 11 | |
1322177d LB |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
0694b47c RS |
16 | |
17 | You should have received a copy of the GNU General Public License | |
1322177d LB |
18 | along with GCC; see the file COPYING. If not, write to the Free |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
0694b47c | 21 | |
88657302 RH |
22 | #ifndef GCC_REAL_H |
23 | #define GCC_REAL_H | |
0694b47c RS |
24 | |
25 | /* Define codes for all the float formats that we know of. */ | |
26 | #define UNKNOWN_FLOAT_FORMAT 0 | |
27 | #define IEEE_FLOAT_FORMAT 1 | |
28 | #define VAX_FLOAT_FORMAT 2 | |
fd76a739 | 29 | #define IBM_FLOAT_FORMAT 3 |
f5963e61 | 30 | #define C4X_FLOAT_FORMAT 4 |
0694b47c RS |
31 | |
32 | /* Default to IEEE float if not specified. Nearly all machines use it. */ | |
33 | ||
34 | #ifndef TARGET_FLOAT_FORMAT | |
35 | #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT | |
36 | #endif | |
37 | ||
38 | #ifndef HOST_FLOAT_FORMAT | |
39 | #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT | |
40 | #endif | |
41 | ||
23c108af SE |
42 | #ifndef INTEL_EXTENDED_IEEE_FORMAT |
43 | #define INTEL_EXTENDED_IEEE_FORMAT 0 | |
44 | #endif | |
45 | ||
0694b47c RS |
46 | #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT |
47 | #define REAL_INFINITY | |
48 | #endif | |
49 | ||
91d61207 RK |
50 | /* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined |
51 | in the header files, then this implies the word-endianness is the same as | |
52 | for integers. */ | |
53 | ||
54 | /* This is defined 0 or 1, like WORDS_BIG_ENDIAN. */ | |
55 | #ifndef FLOAT_WORDS_BIG_ENDIAN | |
56 | #define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN | |
57 | #endif | |
58 | ||
59 | /* This is defined 0 or 1, unlike HOST_WORDS_BIG_ENDIAN. */ | |
60 | #ifndef HOST_FLOAT_WORDS_BIG_ENDIAN | |
61 | #ifdef HOST_WORDS_BIG_ENDIAN | |
62 | #define HOST_FLOAT_WORDS_BIG_ENDIAN 1 | |
63 | #else | |
64 | #define HOST_FLOAT_WORDS_BIG_ENDIAN 0 | |
65 | #endif | |
66 | #endif | |
67 | ||
fd76a739 RS |
68 | /* Defining REAL_ARITHMETIC invokes a floating point emulator |
69 | that can produce a target machine format differing by more | |
70 | than just endian-ness from the host's format. The emulator | |
71 | is also used to support extended real XFmode. */ | |
72 | #ifndef LONG_DOUBLE_TYPE_SIZE | |
73 | #define LONG_DOUBLE_TYPE_SIZE 64 | |
74 | #endif | |
18171048 SM |
75 | /* MAX_LONG_DOUBLE_TYPE_SIZE is a constant tested by #if. |
76 | LONG_DOUBLE_TYPE_SIZE can vary at compiler run time. | |
77 | So long as macros like REAL_VALUE_TO_TARGET_LONG_DOUBLE cannot | |
78 | vary too, however, then XFmode and TFmode long double | |
79 | cannot both be supported at the same time. */ | |
4710d3eb JJ |
80 | #ifndef MAX_LONG_DOUBLE_TYPE_SIZE |
81 | #define MAX_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE | |
82 | #endif | |
83 | #if (MAX_LONG_DOUBLE_TYPE_SIZE == 96) || (MAX_LONG_DOUBLE_TYPE_SIZE == 128) | |
7bb5d01e JW |
84 | #ifndef REAL_ARITHMETIC |
85 | #define REAL_ARITHMETIC | |
86 | #endif | |
87 | #endif | |
88 | #ifdef REAL_ARITHMETIC | |
fd76a739 RS |
89 | /* **** Start of software floating point emulator interface macros **** */ |
90 | ||
91 | /* Support 80-bit extended real XFmode if LONG_DOUBLE_TYPE_SIZE | |
92 | has been defined to be 96 in the tm.h machine file. */ | |
4710d3eb | 93 | #if (MAX_LONG_DOUBLE_TYPE_SIZE == 96) |
fd76a739 RS |
94 | #define REAL_IS_NOT_DOUBLE |
95 | #define REAL_ARITHMETIC | |
96 | typedef struct { | |
97 | HOST_WIDE_INT r[(11 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; | |
98 | } realvaluetype; | |
99 | #define REAL_VALUE_TYPE realvaluetype | |
100 | ||
101 | #else /* no XFmode support */ | |
102 | ||
4710d3eb | 103 | #if (MAX_LONG_DOUBLE_TYPE_SIZE == 128) |
7bb5d01e JW |
104 | |
105 | #define REAL_IS_NOT_DOUBLE | |
106 | #define REAL_ARITHMETIC | |
107 | typedef struct { | |
108 | HOST_WIDE_INT r[(19 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; | |
109 | } realvaluetype; | |
110 | #define REAL_VALUE_TYPE realvaluetype | |
111 | ||
112 | #else /* not TFmode */ | |
113 | ||
fd76a739 RS |
114 | #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT |
115 | /* If no XFmode support, then a REAL_VALUE_TYPE is 64 bits wide | |
116 | but it is not necessarily a host machine double. */ | |
117 | #define REAL_IS_NOT_DOUBLE | |
118 | typedef struct { | |
119 | HOST_WIDE_INT r[(7 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; | |
120 | } realvaluetype; | |
121 | #define REAL_VALUE_TYPE realvaluetype | |
122 | #else | |
123 | /* If host and target formats are compatible, then a REAL_VALUE_TYPE | |
124 | is actually a host machine double. */ | |
125 | #define REAL_VALUE_TYPE double | |
126 | #endif | |
7bb5d01e JW |
127 | |
128 | #endif /* no TFmode support */ | |
fd76a739 RS |
129 | #endif /* no XFmode support */ |
130 | ||
770ae6cc | 131 | extern unsigned int significand_size PARAMS ((enum machine_mode)); |
84f9b8e9 | 132 | |
fd76a739 | 133 | /* If emulation has been enabled by defining REAL_ARITHMETIC or by |
7bb5d01e | 134 | setting LONG_DOUBLE_TYPE_SIZE to 96 or 128, then define macros so that |
fd76a739 RS |
135 | they invoke emulator functions. This will succeed only if the machine |
136 | files have been updated to use these macros in place of any | |
137 | references to host machine `double' or `float' types. */ | |
138 | #ifdef REAL_ARITHMETIC | |
139 | #undef REAL_ARITHMETIC | |
140 | #define REAL_ARITHMETIC(value, code, d1, d2) \ | |
141 | earith (&(value), (code), &(d1), &(d2)) | |
142 | ||
fca04441 | 143 | /* Declare functions in real.c. */ |
13536812 | 144 | extern void earith PARAMS ((REAL_VALUE_TYPE *, int, |
fca04441 | 145 | REAL_VALUE_TYPE *, REAL_VALUE_TYPE *)); |
13536812 KG |
146 | extern REAL_VALUE_TYPE etrunci PARAMS ((REAL_VALUE_TYPE)); |
147 | extern REAL_VALUE_TYPE etruncui PARAMS ((REAL_VALUE_TYPE)); | |
13536812 KG |
148 | extern REAL_VALUE_TYPE ereal_negate PARAMS ((REAL_VALUE_TYPE)); |
149 | extern HOST_WIDE_INT efixi PARAMS ((REAL_VALUE_TYPE)); | |
150 | extern unsigned HOST_WIDE_INT efixui PARAMS ((REAL_VALUE_TYPE)); | |
151 | extern void ereal_from_int PARAMS ((REAL_VALUE_TYPE *, | |
7efc32fd RK |
152 | HOST_WIDE_INT, HOST_WIDE_INT, |
153 | enum machine_mode)); | |
13536812 | 154 | extern void ereal_from_uint PARAMS ((REAL_VALUE_TYPE *, |
fca04441 | 155 | unsigned HOST_WIDE_INT, |
7efc32fd RK |
156 | unsigned HOST_WIDE_INT, |
157 | enum machine_mode)); | |
13536812 | 158 | extern void ereal_to_int PARAMS ((HOST_WIDE_INT *, HOST_WIDE_INT *, |
fca04441 | 159 | REAL_VALUE_TYPE)); |
13536812 KG |
160 | extern REAL_VALUE_TYPE ereal_ldexp PARAMS ((REAL_VALUE_TYPE, int)); |
161 | ||
162 | extern void etartdouble PARAMS ((REAL_VALUE_TYPE, long *)); | |
163 | extern void etarldouble PARAMS ((REAL_VALUE_TYPE, long *)); | |
164 | extern void etardouble PARAMS ((REAL_VALUE_TYPE, long *)); | |
165 | extern long etarsingle PARAMS ((REAL_VALUE_TYPE)); | |
166 | extern void ereal_to_decimal PARAMS ((REAL_VALUE_TYPE, char *)); | |
167 | extern int ereal_cmp PARAMS ((REAL_VALUE_TYPE, REAL_VALUE_TYPE)); | |
168 | extern int ereal_isneg PARAMS ((REAL_VALUE_TYPE)); | |
169 | extern REAL_VALUE_TYPE ereal_unto_float PARAMS ((long)); | |
170 | extern REAL_VALUE_TYPE ereal_unto_double PARAMS ((long *)); | |
171 | extern REAL_VALUE_TYPE ereal_from_float PARAMS ((HOST_WIDE_INT)); | |
172 | extern REAL_VALUE_TYPE ereal_from_double PARAMS ((HOST_WIDE_INT *)); | |
fd76a739 RS |
173 | |
174 | #define REAL_VALUES_EQUAL(x, y) (ereal_cmp ((x), (y)) == 0) | |
175 | /* true if x < y : */ | |
265b1bae | 176 | #define REAL_VALUES_LESS(x, y) (ereal_cmp ((x), (y)) == -1) |
fd76a739 RS |
177 | #define REAL_VALUE_LDEXP(x, n) ereal_ldexp (x, n) |
178 | ||
179 | /* These return REAL_VALUE_TYPE: */ | |
180 | #define REAL_VALUE_RNDZINT(x) (etrunci (x)) | |
181 | #define REAL_VALUE_UNSIGNED_RNDZINT(x) (etruncui (x)) | |
fd76a739 RS |
182 | #define REAL_VALUE_TRUNCATE(mode, x) real_value_truncate (mode, x) |
183 | ||
91d61207 | 184 | /* These return HOST_WIDE_INT: */ |
7bb5d01e JW |
185 | /* Convert a floating-point value to integer, rounding toward zero. */ |
186 | #define REAL_VALUE_FIX(x) (efixi (x)) | |
187 | /* Convert a floating-point value to unsigned integer, rounding | |
188 | toward zero. */ | |
189 | #define REAL_VALUE_UNSIGNED_FIX(x) (efixui (x)) | |
fd76a739 | 190 | |
6f4d7222 UD |
191 | /* Convert ASCII string S to floating point in mode M. |
192 | Decimal input uses ATOF. Hexadecimal uses HTOF. */ | |
c5c76735 JL |
193 | #define REAL_VALUE_ATOF(s,m) ereal_atof(s,m) |
194 | #define REAL_VALUE_HTOF(s,m) ereal_atof(s,m) | |
6f4d7222 | 195 | |
fd76a739 RS |
196 | #define REAL_VALUE_NEGATE ereal_negate |
197 | ||
198 | #define REAL_VALUE_MINUS_ZERO(x) \ | |
199 | ((ereal_cmp (x, dconst0) == 0) && (ereal_isneg (x) != 0 )) | |
200 | ||
201 | #define REAL_VALUE_TO_INT ereal_to_int | |
91d61207 RK |
202 | |
203 | /* Here the cast to HOST_WIDE_INT sign-extends arguments such as ~0. */ | |
7efc32fd RK |
204 | #define REAL_VALUE_FROM_INT(d, lo, hi, mode) \ |
205 | ereal_from_int (&d, (HOST_WIDE_INT) (lo), (HOST_WIDE_INT) (hi), mode) | |
91d61207 | 206 | |
7efc32fd RK |
207 | #define REAL_VALUE_FROM_UNSIGNED_INT(d, lo, hi, mode) \ |
208 | ereal_from_uint (&d, lo, hi, mode) | |
fd76a739 RS |
209 | |
210 | /* IN is a REAL_VALUE_TYPE. OUT is an array of longs. */ | |
23c108af | 211 | #if (INTEL_EXTENDED_IEEE_FORMAT != 0) && (MAX_LONG_DOUBLE_TYPE_SIZE == 128) |
3f622353 RH |
212 | #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) (etarldouble ((IN), (OUT))) |
213 | #else | |
5dc6aef5 JH |
214 | #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) \ |
215 | (LONG_DOUBLE_TYPE_SIZE == 64 ? etardouble ((IN), (OUT)) \ | |
216 | : LONG_DOUBLE_TYPE_SIZE == 96 ? etarldouble ((IN), (OUT)) \ | |
217 | : LONG_DOUBLE_TYPE_SIZE == 128 ? etartdouble ((IN), (OUT)) \ | |
218 | : abort()) | |
3f622353 | 219 | #endif |
fd76a739 | 220 | #define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) (etardouble ((IN), (OUT))) |
7bb5d01e | 221 | |
fd76a739 RS |
222 | /* IN is a REAL_VALUE_TYPE. OUT is a long. */ |
223 | #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) ((OUT) = etarsingle ((IN))) | |
7bb5d01e | 224 | |
7bb6fbd1 JL |
225 | /* Inverse of REAL_VALUE_TO_TARGET_DOUBLE. */ |
226 | #define REAL_VALUE_UNTO_TARGET_DOUBLE(d) (ereal_unto_double (d)) | |
227 | ||
228 | /* Inverse of REAL_VALUE_TO_TARGET_SINGLE. */ | |
229 | #define REAL_VALUE_UNTO_TARGET_SINGLE(f) (ereal_unto_float (f)) | |
230 | ||
403cd5d7 RK |
231 | /* d is an array of HOST_WIDE_INT that holds a double precision |
232 | value in the target computer's floating point format. */ | |
7bb5d01e JW |
233 | #define REAL_VALUE_FROM_TARGET_DOUBLE(d) (ereal_from_double (d)) |
234 | ||
403cd5d7 | 235 | /* f is a HOST_WIDE_INT containing a single precision target float value. */ |
543758c6 | 236 | #define REAL_VALUE_FROM_TARGET_SINGLE(f) (ereal_from_float (f)) |
fd76a739 RS |
237 | |
238 | /* Conversions to decimal ASCII string. */ | |
239 | #define REAL_VALUE_TO_DECIMAL(r, fmt, s) (ereal_to_decimal (r, s)) | |
240 | ||
241 | #endif /* REAL_ARITHMETIC defined */ | |
242 | ||
243 | /* **** End of software floating point emulator interface macros **** */ | |
7bb5d01e | 244 | #else /* No XFmode or TFmode and REAL_ARITHMETIC not defined */ |
fd76a739 RS |
245 | |
246 | /* old interface */ | |
0694b47c RS |
247 | #ifdef REAL_ARITHMETIC |
248 | /* Defining REAL_IS_NOT_DOUBLE breaks certain initializations | |
249 | when REAL_ARITHMETIC etc. are not defined. */ | |
250 | ||
251 | /* Now see if the host and target machines use the same format. | |
252 | If not, define REAL_IS_NOT_DOUBLE (even if we end up representing | |
253 | reals as doubles because we have no better way in this cross compiler.) | |
254 | This turns off various optimizations that can happen when we know the | |
255 | compiler's float format matches the target's float format. | |
256 | */ | |
257 | #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT | |
258 | #define REAL_IS_NOT_DOUBLE | |
259 | #ifndef REAL_VALUE_TYPE | |
fd76a739 RS |
260 | typedef struct { |
261 | HOST_WIDE_INT r[sizeof (double)/sizeof (HOST_WIDE_INT)]; | |
262 | } realvaluetype; | |
263 | #define REAL_VALUE_TYPE realvaluetype | |
0694b47c RS |
264 | #endif /* no REAL_VALUE_TYPE */ |
265 | #endif /* formats differ */ | |
266 | #endif /* 0 */ | |
267 | ||
fd76a739 RS |
268 | #endif /* emulator not used */ |
269 | ||
0694b47c RS |
270 | /* If we are not cross-compiling, use a `double' to represent the |
271 | floating-point value. Otherwise, use some other type | |
272 | (probably a struct containing an array of longs). */ | |
273 | #ifndef REAL_VALUE_TYPE | |
274 | #define REAL_VALUE_TYPE double | |
275 | #else | |
276 | #define REAL_IS_NOT_DOUBLE | |
277 | #endif | |
278 | ||
f9250555 RS |
279 | #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT |
280 | ||
281 | /* Convert a type `double' value in host format first to a type `float' | |
282 | value in host format and then to a single type `long' value which | |
283 | is the bitwise equivalent of the `float' value. */ | |
fd76a739 | 284 | #ifndef REAL_VALUE_TO_TARGET_SINGLE |
800d5c9e RH |
285 | #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \ |
286 | do { \ | |
287 | union { \ | |
288 | float f; \ | |
289 | HOST_WIDE_INT l; \ | |
290 | } u; \ | |
291 | if (sizeof(HOST_WIDE_INT) < sizeof(float)) \ | |
292 | abort(); \ | |
293 | u.l = 0; \ | |
294 | u.f = (IN); \ | |
295 | (OUT) = u.l; \ | |
296 | } while (0) | |
fd76a739 | 297 | #endif |
f9250555 RS |
298 | |
299 | /* Convert a type `double' value in host format to a pair of type `long' | |
300 | values which is its bitwise equivalent, but put the two words into | |
301 | proper word order for the target. */ | |
fd76a739 | 302 | #ifndef REAL_VALUE_TO_TARGET_DOUBLE |
f9250555 | 303 | #define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \ |
800d5c9e RH |
304 | do { \ |
305 | union { \ | |
306 | REAL_VALUE_TYPE f; \ | |
307 | HOST_WIDE_INT l[2]; \ | |
308 | } u; \ | |
309 | if (sizeof(HOST_WIDE_INT) * 2 < sizeof(REAL_VALUE_TYPE)) \ | |
310 | abort(); \ | |
311 | u.l[0] = u.l[1] = 0; \ | |
312 | u.f = (IN); \ | |
313 | if (HOST_FLOAT_WORDS_BIG_ENDIAN == FLOAT_WORDS_BIG_ENDIAN) \ | |
314 | (OUT)[0] = u.l[0], (OUT)[1] = u.l[1]; \ | |
315 | else \ | |
316 | (OUT)[1] = u.l[0], (OUT)[0] = u.l[1]; \ | |
317 | } while (0) | |
fd76a739 | 318 | #endif |
f9250555 RS |
319 | #endif /* HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT */ |
320 | ||
fd76a739 RS |
321 | /* In this configuration, double and long double are the same. */ |
322 | #ifndef REAL_VALUE_TO_TARGET_LONG_DOUBLE | |
323 | #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(a, b) REAL_VALUE_TO_TARGET_DOUBLE (a, b) | |
324 | #endif | |
325 | ||
41c9120b PE |
326 | /* Compare two floating-point objects for bitwise identity. |
327 | This is not the same as comparing for equality on IEEE hosts: | |
328 | -0.0 equals 0.0 but they are not identical, and conversely | |
329 | two NaNs might be identical but they cannot be equal. */ | |
330 | #define REAL_VALUES_IDENTICAL(x, y) \ | |
2e09e75a | 331 | (!memcmp ((char *) &(x), (char *) &(y), sizeof (REAL_VALUE_TYPE))) |
41c9120b | 332 | |
0694b47c RS |
333 | /* Compare two floating-point values for equality. */ |
334 | #ifndef REAL_VALUES_EQUAL | |
fd76a739 | 335 | #define REAL_VALUES_EQUAL(x, y) ((x) == (y)) |
0694b47c RS |
336 | #endif |
337 | ||
338 | /* Compare two floating-point values for less than. */ | |
339 | #ifndef REAL_VALUES_LESS | |
fd76a739 | 340 | #define REAL_VALUES_LESS(x, y) ((x) < (y)) |
0694b47c RS |
341 | #endif |
342 | ||
fd76a739 RS |
343 | /* Truncate toward zero to an integer floating-point value. */ |
344 | #ifndef REAL_VALUE_RNDZINT | |
345 | #define REAL_VALUE_RNDZINT(x) ((double) ((int) (x))) | |
0694b47c RS |
346 | #endif |
347 | ||
fd76a739 RS |
348 | /* Truncate toward zero to an unsigned integer floating-point value. */ |
349 | #ifndef REAL_VALUE_UNSIGNED_RNDZINT | |
350 | #define REAL_VALUE_UNSIGNED_RNDZINT(x) ((double) ((unsigned int) (x))) | |
0694b47c RS |
351 | #endif |
352 | ||
7bb5d01e | 353 | /* Convert a floating-point value to integer, rounding toward zero. */ |
0694b47c RS |
354 | #ifndef REAL_VALUE_FIX |
355 | #define REAL_VALUE_FIX(x) ((int) (x)) | |
356 | #endif | |
357 | ||
7bb5d01e JW |
358 | /* Convert a floating-point value to unsigned integer, rounding |
359 | toward zero. */ | |
0694b47c RS |
360 | #ifndef REAL_VALUE_UNSIGNED_FIX |
361 | #define REAL_VALUE_UNSIGNED_FIX(x) ((unsigned int) (x)) | |
362 | #endif | |
363 | ||
364 | /* Scale X by Y powers of 2. */ | |
365 | #ifndef REAL_VALUE_LDEXP | |
fd76a739 | 366 | #define REAL_VALUE_LDEXP(x, y) ldexp (x, y) |
cbd3488b | 367 | extern double ldexp PARAMS ((double, int)); |
0694b47c RS |
368 | #endif |
369 | ||
370 | /* Convert the string X to a floating-point value. */ | |
371 | #ifndef REAL_VALUE_ATOF | |
fd76a739 RS |
372 | #if 1 |
373 | /* Use real.c to convert decimal numbers to binary, ... */ | |
fd76a739 | 374 | #define REAL_VALUE_ATOF(x, s) ereal_atof (x, s) |
6f4d7222 UD |
375 | /* Could use ereal_atof here for hexadecimal floats too, but real_hex_to_f |
376 | is OK and it uses faster native fp arithmetic. */ | |
377 | /* #define REAL_VALUE_HTOF(x, s) ereal_atof (x, s) */ | |
fd76a739 RS |
378 | #else |
379 | /* ... or, if you like the host computer's atof, go ahead and use it: */ | |
380 | #define REAL_VALUE_ATOF(x, s) atof (x) | |
0694b47c RS |
381 | #if defined (MIPSEL) || defined (MIPSEB) |
382 | /* MIPS compiler can't handle parens around the function name. | |
383 | This problem *does not* appear to be connected with any | |
384 | macro definition for atof. It does not seem there is one. */ | |
385 | extern double atof (); | |
386 | #else | |
387 | extern double (atof) (); | |
388 | #endif | |
389 | #endif | |
fd76a739 | 390 | #endif |
0694b47c | 391 | |
6f4d7222 UD |
392 | /* Hexadecimal floating constant input for use with host computer's |
393 | fp arithmetic. */ | |
394 | #ifndef REAL_VALUE_HTOF | |
08c148a8 NB |
395 | extern REAL_VALUE_TYPE real_hex_to_f PARAMS ((const char *, |
396 | enum machine_mode)); | |
6f4d7222 UD |
397 | #define REAL_VALUE_HTOF(s,m) real_hex_to_f(s,m) |
398 | #endif | |
399 | ||
0694b47c RS |
400 | /* Negate the floating-point value X. */ |
401 | #ifndef REAL_VALUE_NEGATE | |
402 | #define REAL_VALUE_NEGATE(x) (- (x)) | |
403 | #endif | |
404 | ||
405 | /* Truncate the floating-point value X to mode MODE. This is correct only | |
406 | for the most common case where the host and target have objects of the same | |
407 | size and where `float' is SFmode. */ | |
408 | ||
5352b11a | 409 | /* Don't use REAL_VALUE_TRUNCATE directly--always call real_value_truncate. */ |
13536812 | 410 | extern REAL_VALUE_TYPE real_value_truncate PARAMS ((enum machine_mode, |
c5c76735 | 411 | REAL_VALUE_TYPE)); |
5352b11a | 412 | |
0694b47c RS |
413 | #ifndef REAL_VALUE_TRUNCATE |
414 | #define REAL_VALUE_TRUNCATE(mode, x) \ | |
161ca48c RS |
415 | (GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \ |
416 | ? (float) (x) : (x)) | |
0694b47c RS |
417 | #endif |
418 | ||
419 | /* Determine whether a floating-point value X is infinite. */ | |
420 | #ifndef REAL_VALUE_ISINF | |
421 | #define REAL_VALUE_ISINF(x) (target_isinf (x)) | |
422 | #endif | |
423 | ||
3dd4b517 TW |
424 | /* Determine whether a floating-point value X is a NaN. */ |
425 | #ifndef REAL_VALUE_ISNAN | |
426 | #define REAL_VALUE_ISNAN(x) (target_isnan (x)) | |
427 | #endif | |
428 | ||
11030a60 RS |
429 | /* Determine whether a floating-point value X is negative. */ |
430 | #ifndef REAL_VALUE_NEGATIVE | |
431 | #define REAL_VALUE_NEGATIVE(x) (target_negative (x)) | |
432 | #endif | |
433 | ||
0694b47c RS |
434 | /* Determine whether a floating-point value X is minus 0. */ |
435 | #ifndef REAL_VALUE_MINUS_ZERO | |
11030a60 | 436 | #define REAL_VALUE_MINUS_ZERO(x) ((x) == 0 && REAL_VALUE_NEGATIVE (x)) |
0694b47c RS |
437 | #endif |
438 | \f | |
439 | /* Constant real values 0, 1, 2, and -1. */ | |
440 | ||
441 | extern REAL_VALUE_TYPE dconst0; | |
442 | extern REAL_VALUE_TYPE dconst1; | |
443 | extern REAL_VALUE_TYPE dconst2; | |
444 | extern REAL_VALUE_TYPE dconstm1; | |
445 | ||
446 | /* Union type used for extracting real values from CONST_DOUBLEs | |
447 | or putting them in. */ | |
448 | ||
449 | union real_extract | |
450 | { | |
451 | REAL_VALUE_TYPE d; | |
3245eea0 | 452 | HOST_WIDE_INT i[sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT)]; |
0694b47c RS |
453 | }; |
454 | ||
e9576d2c | 455 | /* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */ |
0694b47c RS |
456 | /* Function to return a real value (not a tree node) |
457 | from a given integer constant. */ | |
e9576d2c | 458 | union tree_node; |
13536812 | 459 | REAL_VALUE_TYPE real_value_from_int_cst PARAMS ((union tree_node *, |
e9576d2c | 460 | union tree_node *)); |
0694b47c RS |
461 | |
462 | #define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \ | |
463 | do { union real_extract u; \ | |
4e135bdd | 464 | memcpy (&u, &CONST_DOUBLE_LOW ((from)), sizeof u); \ |
0694b47c RS |
465 | to = u.d; } while (0) |
466 | ||
467 | /* Return a CONST_DOUBLE with value R and mode M. */ | |
468 | ||
fd76a739 | 469 | #define CONST_DOUBLE_FROM_REAL_VALUE(r, m) immed_real_const_1 (r, m) |
13536812 | 470 | extern struct rtx_def *immed_real_const_1 PARAMS ((REAL_VALUE_TYPE, |
fca04441 RK |
471 | enum machine_mode)); |
472 | ||
fd76a739 RS |
473 | |
474 | /* Convert a floating point value `r', that can be interpreted | |
475 | as a host machine float or double, to a decimal ASCII string `s' | |
476 | using printf format string `fmt'. */ | |
477 | #ifndef REAL_VALUE_TO_DECIMAL | |
478 | #define REAL_VALUE_TO_DECIMAL(r, fmt, s) (sprintf (s, fmt, r)) | |
479 | #endif | |
0694b47c | 480 | |
ebc8186b | 481 | /* Replace R by 1/R in the given machine mode, if the result is exact. */ |
13536812 KG |
482 | extern int exact_real_inverse PARAMS ((enum machine_mode, REAL_VALUE_TYPE *)); |
483 | extern int target_isnan PARAMS ((REAL_VALUE_TYPE)); | |
484 | extern int target_isinf PARAMS ((REAL_VALUE_TYPE)); | |
485 | extern int target_negative PARAMS ((REAL_VALUE_TYPE)); | |
486 | extern void debug_real PARAMS ((REAL_VALUE_TYPE)); | |
68896bf9 | 487 | extern REAL_VALUE_TYPE ereal_atof PARAMS ((const char *, enum machine_mode)); |
ebc8186b | 488 | |
88657302 | 489 | #endif /* ! GCC_REAL_H */ |