]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/s390/32/_fixunsdfdi.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / s390 / 32 / _fixunsdfdi.c
CommitLineData
81dd9fd7 1/* Definitions of target machine for GNU compiler, for IBM S/390
a5544970 2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
81dd9fd7
AK
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 3, 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
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
26
bbf391db
AK
27#ifndef __s390x__
28
81dd9fd7 29#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
ce245ec6
AK
30#define EXPONENT_BIAS 1023
31#define MANTISSA_BITS 52
32#define PRECISION (MANTISSA_BITS + 1)
81dd9fd7 33#define SIGNBIT 0x80000000
ce245ec6 34#define SIGN(fp) ((fp.l.upper) & SIGNBIT)
81dd9fd7
AK
35#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
36#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
37#define HIDDEND_LL ((UDItype_x)1 << 52)
38
39typedef int DItype_x __attribute__ ((mode (DI)));
40typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
41typedef int SItype_x __attribute__ ((mode (SI)));
42typedef unsigned int USItype_x __attribute__ ((mode (SI)));
43
44union double_long {
45 double d;
46 struct {
47 SItype_x upper;
48 USItype_x lower;
49 } l;
50 UDItype_x ll;
51};
52
ce245ec6
AK
53static __inline__ void
54fexceptdiv (float d, float e)
55{
56 __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
57}
58
81dd9fd7
AK
59UDItype_x __fixunsdfdi (double a1);
60
61/* convert double to unsigned int */
62UDItype_x
63__fixunsdfdi (double a1)
64{
65 register union double_long dl1;
66 register int exp;
67 register UDItype_x l;
68
69 dl1.d = a1;
70
ce245ec6
AK
71 /* +/- 0, denormalized */
72 if (!EXPD (dl1))
81dd9fd7
AK
73 return 0;
74
ce245ec6
AK
75 /* Negative. */
76 if (SIGN (dl1))
77 {
78 /* Value is <= -1.0
79 C99 Annex F.4 requires an "invalid" exception to be thrown. */
80 if (EXPD (dl1) >= EXPONENT_BIAS)
81 fexceptdiv (0.0, 0.0);
82 return 0;
83 }
84
85 exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
81dd9fd7
AK
86
87 /* number < 1 */
88
ce245ec6 89 if (exp < -PRECISION)
81dd9fd7
AK
90 return 0;
91
92 /* NaN */
93
94 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
ce245ec6
AK
95 {
96 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */
97 fexceptdiv (0.0, 0.0);
98 return 0x0ULL;
99 }
81dd9fd7
AK
100
101 /* Number big number & + inf */
102
ce245ec6
AK
103 if (exp >= 12)
104 {
105 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */
106 fexceptdiv (0.0, 0.0);
107 return 0xFFFFFFFFFFFFFFFFULL;
108 }
81dd9fd7
AK
109
110 l = MANTD_LL(dl1);
111
112 /* shift down until exp < 12 or l = 0 */
113 if (exp > 0)
114 l <<= exp;
115 else
116 l >>= -exp;
117
118 return l;
119}
bbf391db 120#endif /* !__s390x__ */