_fixdfdi.c revision 1.1.1.1.8.1
1/* Definitions of target machine for GNU compiler, for IBM S/390
2   Copyright (C) 1999-2013 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 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
27#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
28#define EXCESSD		1022
29#define SIGNBIT		0x80000000
30#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
31#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
32#define FRACD_LL(fp)	(fp.ll & (HIDDEND_LL-1))
33#define HIDDEND_LL	((UDItype_x)1 << 52)
34
35typedef int DItype_x __attribute__ ((mode (DI)));
36typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
37typedef int SItype_x __attribute__ ((mode (SI)));
38typedef unsigned int USItype_x __attribute__ ((mode (SI)));
39
40union double_long {
41    double d;
42    struct {
43      SItype_x upper;
44      USItype_x lower;
45    } l;
46    UDItype_x ll;
47};
48
49DItype_x __fixdfdi (double a1);
50
51/* convert double to int */
52DItype_x
53__fixdfdi (double a1)
54{
55    register union double_long dl1;
56    register int exp;
57    register DItype_x l;
58
59    dl1.d = a1;
60
61    /* +/- 0, denormalized */
62
63    if (!EXPD (dl1))
64      return 0;
65
66    exp = EXPD (dl1) - EXCESSD - 53;
67
68    /* number < 1 */
69
70    if (exp < -53)
71      return 0;
72
73    /* NaN */
74
75    if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
76      return 0x8000000000000000ULL;
77
78    /* Number big number & +/- inf */
79
80    if (exp >= 11) {
81	l = (long long)1<<63;
82	if (!SIGND(dl1))
83	    l--;
84	return l;
85    }
86
87    l = MANTD_LL(dl1);
88
89    /* shift down until exp < 12 or l = 0 */
90    if (exp > 0)
91      l <<= exp;
92    else
93      l >>= -exp;
94
95    return (SIGND (dl1) ? -l : l);
96}
97