1/* Definitions of target machine for GNU compiler, for IBM S/390
2   Copyright (C) 1999, 2000, 2001, 2007, 2008 and 2009
3   Free Software Foundation, Inc.
4   Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5                  Ulrich Weigand (uweigand@de.ibm.com).
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17for more details.
18
19Under Section 7 of GPL version 3, you are granted additional
20permissions described in the GCC Runtime Library Exception, version
213.1, as published by the Free Software Foundation.
22
23You should have received a copy of the GNU General Public License and
24a copy of the GCC Runtime Library Exception along with this program;
25see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
26<http://www.gnu.org/licenses/>.  */
27
28#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
29#define EXCESSD		1022
30#define SIGNBIT		0x80000000
31#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
32#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
33#define FRACD_LL(fp)	(fp.ll & (HIDDEND_LL-1))
34#define HIDDEND_LL	((UDItype_x)1 << 52)
35
36typedef int DItype_x __attribute__ ((mode (DI)));
37typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
38typedef int SItype_x __attribute__ ((mode (SI)));
39typedef unsigned int USItype_x __attribute__ ((mode (SI)));
40
41union double_long {
42    double d;
43    struct {
44      SItype_x upper;
45      USItype_x lower;
46    } l;
47    UDItype_x ll;
48};
49
50UDItype_x __fixunsdfdi (double a1);
51
52/* convert double to unsigned int */
53UDItype_x
54__fixunsdfdi (double a1)
55{
56    register union double_long dl1;
57    register int exp;
58    register UDItype_x l;
59
60    dl1.d = a1;
61
62    /* +/- 0, denormalized, negative */
63
64    if (!EXPD (dl1) || SIGND(dl1))
65      return 0;
66
67    exp = EXPD (dl1) - EXCESSD - 53;
68
69    /* number < 1 */
70
71    if (exp < -53)
72      return 0;
73
74    /* NaN */
75
76    if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
77      return 0x0ULL;
78
79    /* Number big number & + inf */
80
81    if (exp >= 12) {
82      return 0xFFFFFFFFFFFFFFFFULL;
83    }
84
85    l = MANTD_LL(dl1);
86
87    /* shift down until exp < 12 or l = 0 */
88    if (exp > 0)
89      l <<= exp;
90    else
91      l >>= -exp;
92
93    return l;
94}
95