xref: /openbsd/gnu/usr.bin/gcc/gcc/config/s390/fixdfdi.h (revision c87b03e5)
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