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
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 #ifdef L_fixunsdfdi
24 #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
25 #define EXCESSD 1022
26 #define SIGNBIT 0x80000000
27 #define SIGND(fp) ((fp.l.upper) & SIGNBIT)
28 #define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
29 #define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
30 #define HIDDEND_LL ((UDItype_x)1 << 52)
31
32 typedef int DItype_x __attribute__ ((mode (DI)));
33 typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
34 typedef int SItype_x __attribute__ ((mode (SI)));
35 typedef unsigned int USItype_x __attribute__ ((mode (SI)));
36
37 union double_long {
38 double d;
39 struct {
40 SItype_x upper;
41 USItype_x lower;
42 } l;
43 UDItype_x ll;
44 };
45
46 UDItype_x __fixunsdfdi (double a1);
47
48 /* convert double to unsigned int */
49 UDItype_x
__fixunsdfdi(double a1)50 __fixunsdfdi (double a1)
51 {
52 register union double_long dl1;
53 register int exp;
54 register UDItype_x l;
55
56 dl1.d = a1;
57
58 /* +/- 0, denormalized, negativ */
59
60 if (!EXPD (dl1) || SIGND(dl1))
61 return 0;
62
63 exp = EXPD (dl1) - EXCESSD - 53;
64
65 /* number < 1 */
66
67 if (exp < -53)
68 return 0;
69
70 /* NaN */
71
72 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
73 return 0x0ULL;
74
75 /* Number big number & + inf */
76
77 if (exp >= 12) {
78 return 0xFFFFFFFFFFFFFFFFULL;
79 }
80
81 l = MANTD_LL(dl1);
82
83 /* shift down until exp < 12 or l = 0 */
84 if (exp > 0)
85 l <<= exp;
86 else
87 l >>= -exp;
88
89 return l;
90 }
91 #define __fixunsdfdi ___fixunsdfdi
92 #endif
93 #undef L_fixunsdfdi
94
95 #ifdef L_fixdfdi
96 #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
97 #define EXCESSD 1022
98 #define SIGNBIT 0x80000000
99 #define SIGND(fp) ((fp.l.upper) & SIGNBIT)
100 #define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
101 #define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
102 #define HIDDEND_LL ((UDItype_x)1 << 52)
103
104 typedef int DItype_x __attribute__ ((mode (DI)));
105 typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
106 typedef int SItype_x __attribute__ ((mode (SI)));
107 typedef unsigned int USItype_x __attribute__ ((mode (SI)));
108
109 union double_long {
110 double d;
111 struct {
112 SItype_x upper;
113 USItype_x lower;
114 } l;
115 UDItype_x ll;
116 };
117
118 DItype_x __fixdfdi (double a1);
119
120 /* convert double to int */
121 DItype_x
__fixdfdi(double a1)122 __fixdfdi (double a1)
123 {
124 register union double_long dl1;
125 register int exp;
126 register DItype_x l;
127
128 dl1.d = a1;
129
130 /* +/- 0, denormalized */
131
132 if (!EXPD (dl1))
133 return 0;
134
135 exp = EXPD (dl1) - EXCESSD - 53;
136
137 /* number < 1 */
138
139 if (exp < -53)
140 return 0;
141
142 /* NaN */
143
144 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
145 return 0x8000000000000000ULL;
146
147 /* Number big number & +/- inf */
148
149 if (exp >= 11) {
150 l = (long long)1<<63;
151 if (!SIGND(dl1))
152 l--;
153 return l;
154 }
155
156 l = MANTD_LL(dl1);
157
158 /* shift down until exp < 12 or l = 0 */
159 if (exp > 0)
160 l <<= exp;
161 else
162 l >>= -exp;
163
164 return (SIGND (dl1) ? -l : l);
165 }
166 #define __fixdfdi ___fixdfdi
167 #endif
168 #undef L_fixdfdi
169
170 #ifdef L_fixunssfdi
171 #define EXP(fp) (((fp.l) >> 23) & 0xFF)
172 #define EXCESS 126
173 #define SIGNBIT 0x80000000
174 #define SIGN(fp) ((fp.l) & SIGNBIT)
175 #define HIDDEN (1 << 23)
176 #define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
177 #define FRAC(fp) ((fp.l) & 0x7FFFFF)
178
179 typedef int DItype_x __attribute__ ((mode (DI)));
180 typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
181 typedef int SItype_x __attribute__ ((mode (SI)));
182 typedef unsigned int USItype_x __attribute__ ((mode (SI)));
183
184 union float_long
185 {
186 float f;
187 USItype_x l;
188 };
189
190 UDItype_x __fixunssfdi (float a1);
191
192 /* convert float to unsigned int */
193 UDItype_x
__fixunssfdi(float a1)194 __fixunssfdi (float a1)
195 {
196 register union float_long fl1;
197 register int exp;
198 register UDItype_x l;
199
200 fl1.f = a1;
201
202 /* +/- 0, denormalized, negativ */
203
204 if (!EXP (fl1) || SIGN(fl1))
205 return 0;
206
207 exp = EXP (fl1) - EXCESS - 24;
208
209 /* number < 1 */
210
211 if (exp < -24)
212 return 0;
213
214 /* NaN */
215
216 if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
217 return 0x0ULL;
218
219 /* Number big number & + inf */
220
221 if (exp >= 41) {
222 return 0xFFFFFFFFFFFFFFFFULL;
223 }
224
225 l = MANT(fl1);
226
227 if (exp > 0)
228 l <<= exp;
229 else
230 l >>= -exp;
231
232 return l;
233 }
234 #define __fixunssfdi ___fixunssfdi
235 #endif
236 #undef L_fixunssfdi
237
238 #ifdef L_fixsfdi
239 #define EXP(fp) (((fp.l) >> 23) & 0xFF)
240 #define EXCESS 126
241 #define SIGNBIT 0x80000000
242 #define SIGN(fp) ((fp.l) & SIGNBIT)
243 #define HIDDEN (1 << 23)
244 #define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
245 #define FRAC(fp) ((fp.l) & 0x7FFFFF)
246
247 typedef int DItype_x __attribute__ ((mode (DI)));
248 typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
249 typedef int SItype_x __attribute__ ((mode (SI)));
250 typedef unsigned int USItype_x __attribute__ ((mode (SI)));
251
252 union float_long
253 {
254 float f;
255 USItype_x l;
256 };
257
258 DItype_x __fixsfdi (float a1);
259
260 /* convert double to int */
261 DItype_x
__fixsfdi(float a1)262 __fixsfdi (float a1)
263 {
264 register union float_long fl1;
265 register int exp;
266 register DItype_x l;
267
268 fl1.f = a1;
269
270 /* +/- 0, denormalized */
271
272 if (!EXP (fl1))
273 return 0;
274
275 exp = EXP (fl1) - EXCESS - 24;
276
277 /* number < 1 */
278
279 if (exp < -24)
280 return 0;
281
282 /* NaN */
283
284 if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
285 return 0x8000000000000000ULL;
286
287 /* Number big number & +/- inf */
288
289 if (exp >= 40) {
290 l = (long long)1<<63;
291 if (!SIGN(fl1))
292 l--;
293 return l;
294 }
295
296 l = MANT(fl1);
297
298 if (exp > 0)
299 l <<= exp;
300 else
301 l >>= -exp;
302
303 return (SIGN (fl1) ? -l : l);
304 }
305 #define __fixsfdi ___fixsfdi
306 #endif
307 #undef L_fixsfdi
308
309