1117395Skan/* Functions needed for soft-float on powerpc64-linux, copied from
2117395Skan   libgcc2.c with macros expanded to force the use of specific types.
3117395Skan
4117395Skan   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5169689Skan   2000, 2001, 2002, 2003, 2004, 2006  Free Software Foundation, Inc.
6117395Skan
7117395SkanThis file is part of GCC.
8117395Skan
9117395SkanGCC is free software; you can redistribute it and/or modify it under
10117395Skanthe terms of the GNU General Public License as published by the Free
11117395SkanSoftware Foundation; either version 2, or (at your option) any later
12117395Skanversion.
13117395Skan
14117395SkanIn addition to the permissions in the GNU General Public License, the
15117395SkanFree Software Foundation gives you unlimited permission to link the
16117395Skancompiled version of this file into combinations with other programs,
17117395Skanand to distribute those combinations without any restriction coming
18117395Skanfrom the use of this file.  (The General Public License restrictions
19117395Skando apply in other respects; for example, they cover modification of
20117395Skanthe file, and distribution when not linked into a combine
21117395Skanexecutable.)
22117395Skan
23117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
24117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
25117395SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26117395Skanfor more details.
27117395Skan
28117395SkanYou should have received a copy of the GNU General Public License
29117395Skanalong with GCC; see the file COPYING.  If not, write to the Free
30169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
31169689Skan02110-1301, USA.  */
32117395Skan
33169689Skan#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__)
34169689Skan#define TMODES
35132718Skan#include "config/fp-bit.h"
36117395Skan
37132718Skanextern DItype __fixtfdi (TFtype);
38117395Skanextern DItype __fixdfdi (DFtype);
39117395Skanextern DItype __fixsfdi (SFtype);
40117395Skanextern USItype __fixunsdfsi (DFtype);
41117395Skanextern USItype __fixunssfsi (SFtype);
42132718Skanextern TFtype __floatditf (DItype);
43169689Skanextern TFtype __floatunditf (UDItype);
44117395Skanextern DFtype __floatdidf (DItype);
45169689Skanextern DFtype __floatundidf (UDItype);
46117395Skanextern SFtype __floatdisf (DItype);
47169689Skanextern SFtype __floatundisf (UDItype);
48132718Skanextern DItype __fixunstfdi (TFtype);
49117395Skan
50117395Skanstatic DItype local_fixunssfdi (SFtype);
51117395Skanstatic DItype local_fixunsdfdi (DFtype);
52117395Skan
53117395SkanDItype
54132718Skan__fixtfdi (TFtype a)
55132718Skan{
56132718Skan  if (a < 0)
57132718Skan    return - __fixunstfdi (-a);
58132718Skan  return __fixunstfdi (a);
59132718Skan}
60132718Skan
61132718SkanDItype
62117395Skan__fixdfdi (DFtype a)
63117395Skan{
64117395Skan  if (a < 0)
65117395Skan    return - local_fixunsdfdi (-a);
66117395Skan  return local_fixunsdfdi (a);
67117395Skan}
68117395Skan
69117395SkanDItype
70117395Skan__fixsfdi (SFtype a)
71117395Skan{
72117395Skan  if (a < 0)
73117395Skan    return - local_fixunssfdi (-a);
74117395Skan  return local_fixunssfdi (a);
75117395Skan}
76117395Skan
77117395SkanUSItype
78117395Skan__fixunsdfsi (DFtype a)
79117395Skan{
80117395Skan  if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
81117395Skan    return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
82117395Skan                       - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
83117395Skan  return (SItype) a;
84117395Skan}
85117395Skan
86117395SkanUSItype
87117395Skan__fixunssfsi (SFtype a)
88117395Skan{
89117395Skan  if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
90117395Skan    return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
91117395Skan                       - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
92117395Skan  return (SItype) a;
93117395Skan}
94117395Skan
95132718SkanTFtype
96132718Skan__floatditf (DItype u)
97132718Skan{
98132718Skan  DFtype dh, dl;
99132718Skan
100132718Skan  dh = (SItype) (u >> (sizeof (SItype) * 8));
101132718Skan  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
102132718Skan  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
103132718Skan
104132718Skan  return (TFtype) dh + (TFtype) dl;
105132718Skan}
106132718Skan
107169689SkanTFtype
108169689Skan__floatunditf (UDItype u)
109169689Skan{
110169689Skan  DFtype dh, dl;
111169689Skan
112169689Skan  dh = (USItype) (u >> (sizeof (SItype) * 8));
113169689Skan  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
114169689Skan  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
115169689Skan
116169689Skan  return (TFtype) dh + (TFtype) dl;
117169689Skan}
118169689Skan
119117395SkanDFtype
120117395Skan__floatdidf (DItype u)
121117395Skan{
122117395Skan  DFtype d;
123117395Skan
124117395Skan  d = (SItype) (u >> (sizeof (SItype) * 8));
125132718Skan  d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
126117395Skan  d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
127117395Skan
128117395Skan  return d;
129117395Skan}
130117395Skan
131169689SkanDFtype
132169689Skan__floatundidf (UDItype u)
133169689Skan{
134169689Skan  DFtype d;
135169689Skan
136169689Skan  d = (USItype) (u >> (sizeof (SItype) * 8));
137169689Skan  d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
138169689Skan  d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
139169689Skan
140169689Skan  return d;
141169689Skan}
142169689Skan
143117395SkanSFtype
144117395Skan__floatdisf (DItype u)
145117395Skan{
146117395Skan  DFtype f;
147117395Skan
148117395Skan  if (53 < (sizeof (DItype) * 8)
149117395Skan      && 53 > ((sizeof (DItype) * 8) - 53 + 24))
150117395Skan    {
151117395Skan      if (! (- ((DItype) 1 << 53) < u
152117395Skan             && u < ((DItype) 1 << 53)))
153117395Skan        {
154117395Skan          if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
155117395Skan            {
156117395Skan              u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
157117395Skan              u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
158117395Skan            }
159117395Skan        }
160117395Skan    }
161117395Skan  f = (SItype) (u >> (sizeof (SItype) * 8));
162132718Skan  f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
163117395Skan  f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
164117395Skan
165117395Skan  return (SFtype) f;
166117395Skan}
167117395Skan
168169689SkanSFtype
169169689Skan__floatundisf (UDItype u)
170169689Skan{
171169689Skan  DFtype f;
172169689Skan
173169689Skan  if (53 < (sizeof (DItype) * 8)
174169689Skan      && 53 > ((sizeof (DItype) * 8) - 53 + 24))
175169689Skan    {
176169689Skan      if (u >= ((UDItype) 1 << 53))
177169689Skan        {
178169689Skan          if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
179169689Skan            {
180169689Skan              u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
181169689Skan              u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
182169689Skan            }
183169689Skan        }
184169689Skan    }
185169689Skan  f = (USItype) (u >> (sizeof (SItype) * 8));
186169689Skan  f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
187169689Skan  f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
188169689Skan
189169689Skan  return (SFtype) f;
190169689Skan}
191169689Skan
192132718SkanDItype
193132718Skan__fixunstfdi (TFtype a)
194132718Skan{
195132718Skan  if (a < 0)
196132718Skan    return 0;
197132718Skan
198132718Skan  /* Compute high word of result, as a flonum.  */
199132718Skan  const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
200132718Skan  /* Convert that to fixed (but not to DItype!),
201132718Skan     and shift it into the high word.  */
202132718Skan  UDItype v = (USItype) b;
203132718Skan  v <<= (sizeof (SItype) * 8);
204132718Skan  /* Remove high part from the TFtype, leaving the low part as flonum.  */
205132718Skan  a -= (TFtype) v;
206132718Skan  /* Convert that to fixed (but not to DItype!) and add it in.
207132718Skan     Sometimes A comes out negative.  This is significant, since
208132718Skan     A has more bits than a long int does.  */
209132718Skan  if (a < 0)
210132718Skan    v -= (USItype) (-a);
211132718Skan  else
212132718Skan    v += (USItype) a;
213132718Skan  return v;
214132718Skan}
215132718Skan
216117395Skan/* This version is needed to prevent recursion; fixunsdfdi in libgcc
217117395Skan   calls fixdfdi, which in turn calls calls fixunsdfdi.  */
218117395Skan
219117395Skanstatic DItype
220117395Skanlocal_fixunsdfdi (DFtype a)
221117395Skan{
222117395Skan  USItype hi, lo;
223117395Skan
224117395Skan  hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
225117395Skan  lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
226117395Skan  return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
227117395Skan}
228117395Skan
229117395Skan/* This version is needed to prevent recursion; fixunssfdi in libgcc
230117395Skan   calls fixsfdi, which in turn calls calls fixunssfdi.  */
231117395Skan
232117395Skanstatic DItype
233117395Skanlocal_fixunssfdi (SFtype original_a)
234117395Skan{
235117395Skan  DFtype a = original_a;
236117395Skan  USItype hi, lo;
237117395Skan
238117395Skan  hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
239117395Skan  lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
240117395Skan  return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
241117395Skan}
242117395Skan
243117395Skan#endif /* __powerpc64__ */
244