fixdfdi.h revision 259065
1/* Definitions of target machine for GNU compiler, for IBM S/390
2   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3   Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4                  Ulrich Weigand (uweigand@de.ibm.com).
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA.  */
22
23#ifdef L_fixunstfdi
24
25#define EXPD(fp)	   (((fp.l.i[0]) >> 16) & 0x7FFF)
26#define EXPONENT_BIAS	   16383
27#define MANTISSA_BITS      112
28#define PRECISION          (MANTISSA_BITS + 1)
29#define SIGNBIT		   0x80000000
30#define SIGND(fp)	   ((fp.l.i[0]) & SIGNBIT)
31#define MANTD_HIGH_LL(fp)  ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT)
32#define MANTD_LOW_LL(fp)   (fp.ll[1])
33#define FRACD_ZERO_P(fp)   (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK))
34#define HIGH_LL_FRAC_BITS  48
35#define HIGH_LL_UNIT_BIT   ((UDItype_x)1 << HIGH_LL_FRAC_BITS)
36#define HIGH_LL_FRAC_MASK  (HIGH_LL_UNIT_BIT - 1)
37
38typedef int DItype_x __attribute__ ((mode (DI)));
39typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
40typedef int SItype_x __attribute__ ((mode (SI)));
41typedef unsigned int USItype_x __attribute__ ((mode (SI)));
42
43union double_long {
44  long double d;
45  struct {
46      SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */
47    } l;
48  UDItype_x ll[2];   /* 64 bit parts: 0 upper, 1 lower */
49};
50
51UDItype_x __fixunstfdi (long double a1);
52
53/* convert double to unsigned int */
54UDItype_x
55__fixunstfdi (long double a1)
56{
57    register union double_long dl1;
58    register int exp;
59    register UDItype_x l;
60
61    dl1.d = a1;
62
63    /* +/- 0, denormalized, negative */
64    if (!EXPD (dl1) || SIGND(dl1))
65      return 0;
66
67    /* The exponent - considered the binary point at the right end of
68       the mantissa.  */
69    exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
70
71    /* number < 1: If the mantissa would need to be right-shifted more bits than
72       its size (plus the implied one bit on the left) the result would be
73       zero.  */
74    if (exp <= -PRECISION)
75      return 0;
76
77    /* NaN: All exponent bits set and a nonzero fraction.  */
78    if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
79      return 0x0ULL;
80
81    /* If the upper ll part of the mantissa isn't
82       zeroed out after shifting the number would be to large.  */
83    if (exp >= -HIGH_LL_FRAC_BITS)
84      return 0xFFFFFFFFFFFFFFFFULL;
85
86    exp += HIGH_LL_FRAC_BITS + 1;
87
88    l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
89        | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
90
91    return l >> -exp;
92}
93#define __fixunstfdi ___fixunstfdi
94#endif
95#undef L_fixunstfdi
96
97#ifdef L_fixtfdi
98#define EXPD(fp)	   (((fp.l.i[0]) >> 16) & 0x7FFF)
99#define EXPONENT_BIAS	   16383
100#define MANTISSA_BITS      112
101#define PRECISION          (MANTISSA_BITS + 1)
102#define SIGNBIT		   0x80000000
103#define SIGND(fp)	   ((fp.l.i[0]) & SIGNBIT)
104#define MANTD_HIGH_LL(fp)  ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT)
105#define MANTD_LOW_LL(fp)   (fp.ll[1])
106#define FRACD_ZERO_P(fp)   (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK))
107#define HIGH_LL_FRAC_BITS  48
108#define HIGH_LL_UNIT_BIT   ((UDItype_x)1 << HIGH_LL_FRAC_BITS)
109#define HIGH_LL_FRAC_MASK  (HIGH_LL_UNIT_BIT - 1)
110
111typedef int DItype_x __attribute__ ((mode (DI)));
112typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
113typedef int SItype_x __attribute__ ((mode (SI)));
114typedef unsigned int USItype_x __attribute__ ((mode (SI)));
115
116union double_long {
117  long double d;
118  struct {
119      SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */
120    } l;
121  DItype_x ll[2];   /* 64 bit parts: 0 upper, 1 lower */
122};
123
124DItype_x __fixtfdi (long double a1);
125
126/* convert double to unsigned int */
127DItype_x
128__fixtfdi (long double a1)
129{
130    register union double_long dl1;
131    register int exp;
132    register UDItype_x l;
133
134    dl1.d = a1;
135
136    /* +/- 0, denormalized */
137    if (!EXPD (dl1))
138      return 0;
139
140    /* The exponent - considered the binary point at the right end of
141       the mantissa.  */
142    exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
143
144    /* number < 1: If the mantissa would need to be right-shifted more bits than
145       its size the result would be zero.  */
146    if (exp <= -PRECISION)
147      return 0;
148
149    /* NaN: All exponent bits set and a nonzero fraction.  */
150    if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
151      return 0x8000000000000000ULL;
152
153    /* If the upper ll part of the mantissa isn't
154       zeroed out after shifting the number would be to large.  */
155    if (exp >= -HIGH_LL_FRAC_BITS)
156      {
157	l = (long long)1 << 63; /* long int min */
158	return SIGND (dl1) ? l : l - 1;
159      }
160
161    /* The extra bit is needed for the sign bit.  */
162    exp += HIGH_LL_FRAC_BITS + 1;
163
164    l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
165        | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
166
167    return SIGND (dl1) ? -(l >> -exp) : l >> -exp;
168}
169#define __fixtfdi ___fixtfdi
170#endif
171#undef L_fixtfdi
172
173#ifdef L_fixunsdfdi
174#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
175#define EXCESSD		1022
176#define SIGNBIT		0x80000000
177#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
178#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
179#define FRACD_LL(fp)	(fp.ll & (HIDDEND_LL-1))
180#define HIDDEND_LL	((UDItype_x)1 << 52)
181
182typedef int DItype_x __attribute__ ((mode (DI)));
183typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
184typedef int SItype_x __attribute__ ((mode (SI)));
185typedef unsigned int USItype_x __attribute__ ((mode (SI)));
186
187union double_long {
188    double d;
189    struct {
190      SItype_x upper;
191      USItype_x lower;
192    } l;
193    UDItype_x ll;
194};
195
196UDItype_x __fixunsdfdi (double a1);
197
198/* convert double to unsigned int */
199UDItype_x
200__fixunsdfdi (double a1)
201{
202    register union double_long dl1;
203    register int exp;
204    register UDItype_x l;
205
206    dl1.d = a1;
207
208    /* +/- 0, denormalized, negative */
209
210    if (!EXPD (dl1) || SIGND(dl1))
211      return 0;
212
213    exp = EXPD (dl1) - EXCESSD - 53;
214
215    /* number < 1 */
216
217    if (exp < -53)
218      return 0;
219
220    /* NaN */
221
222    if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
223      return 0x0ULL;
224
225    /* Number big number & + inf */
226
227    if (exp >= 12) {
228      return 0xFFFFFFFFFFFFFFFFULL;
229    }
230
231    l = MANTD_LL(dl1);
232
233    /* shift down until exp < 12 or l = 0 */
234    if (exp > 0)
235      l <<= exp;
236    else
237      l >>= -exp;
238
239    return l;
240}
241#define __fixunsdfdi ___fixunsdfdi
242#endif
243#undef L_fixunsdfdi
244
245#ifdef L_fixdfdi
246#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
247#define EXCESSD		1022
248#define SIGNBIT		0x80000000
249#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
250#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
251#define FRACD_LL(fp)	(fp.ll & (HIDDEND_LL-1))
252#define HIDDEND_LL	((UDItype_x)1 << 52)
253
254typedef int DItype_x __attribute__ ((mode (DI)));
255typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
256typedef int SItype_x __attribute__ ((mode (SI)));
257typedef unsigned int USItype_x __attribute__ ((mode (SI)));
258
259union double_long {
260    double d;
261    struct {
262      SItype_x upper;
263      USItype_x lower;
264    } l;
265    UDItype_x ll;
266};
267
268DItype_x __fixdfdi (double a1);
269
270/* convert double to int */
271DItype_x
272__fixdfdi (double a1)
273{
274    register union double_long dl1;
275    register int exp;
276    register DItype_x l;
277
278    dl1.d = a1;
279
280    /* +/- 0, denormalized */
281
282    if (!EXPD (dl1))
283      return 0;
284
285    exp = EXPD (dl1) - EXCESSD - 53;
286
287    /* number < 1 */
288
289    if (exp < -53)
290      return 0;
291
292    /* NaN */
293
294    if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
295      return 0x8000000000000000ULL;
296
297    /* Number big number & +/- inf */
298
299    if (exp >= 11) {
300	l = (long long)1<<63;
301	if (!SIGND(dl1))
302	    l--;
303	return l;
304    }
305
306    l = MANTD_LL(dl1);
307
308    /* shift down until exp < 12 or l = 0 */
309    if (exp > 0)
310      l <<= exp;
311    else
312      l >>= -exp;
313
314    return (SIGND (dl1) ? -l : l);
315}
316#define __fixdfdi ___fixdfdi
317#endif
318#undef L_fixdfdi
319
320#ifdef L_fixunssfdi
321#define EXP(fp)         (((fp.l) >> 23) & 0xFF)
322#define EXCESS          126
323#define SIGNBIT         0x80000000
324#define SIGN(fp)        ((fp.l) & SIGNBIT)
325#define HIDDEN          (1 << 23)
326#define MANT(fp)        (((fp.l) & 0x7FFFFF) | HIDDEN)
327#define FRAC(fp)        ((fp.l) & 0x7FFFFF)
328
329typedef int DItype_x __attribute__ ((mode (DI)));
330typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
331typedef int SItype_x __attribute__ ((mode (SI)));
332typedef unsigned int USItype_x __attribute__ ((mode (SI)));
333
334union float_long
335  {
336    float f;
337    USItype_x l;
338  };
339
340UDItype_x __fixunssfdi (float a1);
341
342/* convert float to unsigned int */
343UDItype_x
344__fixunssfdi (float a1)
345{
346    register union float_long fl1;
347    register int exp;
348    register UDItype_x l;
349
350    fl1.f = a1;
351
352    /* +/- 0, denormalized, negative */
353
354    if (!EXP (fl1) || SIGN(fl1))
355      return 0;
356
357    exp = EXP (fl1) - EXCESS - 24;
358
359    /* number < 1 */
360
361    if (exp < -24)
362      return 0;
363
364    /* NaN */
365
366    if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
367      return 0x0ULL;
368
369    /* Number big number & + inf */
370
371    if (exp >= 41) {
372      return 0xFFFFFFFFFFFFFFFFULL;
373    }
374
375    l = MANT(fl1);
376
377    if (exp > 0)
378      l <<= exp;
379    else
380      l >>= -exp;
381
382    return l;
383}
384#define __fixunssfdi ___fixunssfdi
385#endif
386#undef L_fixunssfdi
387
388#ifdef L_fixsfdi
389#define EXP(fp)         (((fp.l) >> 23) & 0xFF)
390#define EXCESS          126
391#define SIGNBIT         0x80000000
392#define SIGN(fp)        ((fp.l) & SIGNBIT)
393#define HIDDEN          (1 << 23)
394#define MANT(fp)        (((fp.l) & 0x7FFFFF) | HIDDEN)
395#define FRAC(fp)        ((fp.l) & 0x7FFFFF)
396
397typedef int DItype_x __attribute__ ((mode (DI)));
398typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
399typedef int SItype_x __attribute__ ((mode (SI)));
400typedef unsigned int USItype_x __attribute__ ((mode (SI)));
401
402union float_long
403  {
404    float f;
405    USItype_x l;
406  };
407
408DItype_x __fixsfdi (float a1);
409
410/* convert double to int */
411DItype_x
412__fixsfdi (float a1)
413{
414    register union float_long fl1;
415    register int exp;
416    register DItype_x l;
417
418    fl1.f = a1;
419
420    /* +/- 0, denormalized */
421
422    if (!EXP (fl1))
423      return 0;
424
425    exp = EXP (fl1) - EXCESS - 24;
426
427    /* number < 1 */
428
429    if (exp < -24)
430      return 0;
431
432    /* NaN */
433
434    if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
435      return 0x8000000000000000ULL;
436
437    /* Number big number & +/- inf */
438
439    if (exp >= 40) {
440	l = (long long)1<<63;
441	if (!SIGN(fl1))
442	    l--;
443	return l;
444    }
445
446    l = MANT(fl1);
447
448    if (exp > 0)
449      l <<= exp;
450    else
451      l >>= -exp;
452
453    return (SIGN (fl1) ? -l : l);
454}
455#define __fixsfdi ___fixsfdi
456#endif
457#undef L_fixsfdi
458