1/* Functions needed for soft-float on powerpc64-linux, copied from
2   libgcc2.c with macros expanded to force the use of specific types.
3
4   Copyright (C) 1989-2020 Free Software Foundation, Inc.
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#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__)
28#define TMODES
29#include "fp-bit.h"
30
31extern DItype __fixtfdi (TFtype);
32extern DItype __fixdfdi (DFtype);
33extern DItype __fixsfdi (SFtype);
34extern USItype __fixunsdfsi (DFtype);
35extern USItype __fixunssfsi (SFtype);
36extern TFtype __floatditf (DItype);
37extern TFtype __floatunditf (UDItype);
38extern DFtype __floatdidf (DItype);
39extern DFtype __floatundidf (UDItype);
40extern SFtype __floatdisf (DItype);
41extern SFtype __floatundisf (UDItype);
42extern DItype __fixunstfdi (TFtype);
43
44static DItype local_fixunssfdi (SFtype);
45static DItype local_fixunsdfdi (DFtype);
46
47DItype
48__fixtfdi (TFtype a)
49{
50  if (a < 0)
51    return - __fixunstfdi (-a);
52  return __fixunstfdi (a);
53}
54
55DItype
56__fixdfdi (DFtype a)
57{
58  if (a < 0)
59    return - local_fixunsdfdi (-a);
60  return local_fixunsdfdi (a);
61}
62
63DItype
64__fixsfdi (SFtype a)
65{
66  if (a < 0)
67    return - local_fixunssfdi (-a);
68  return local_fixunssfdi (a);
69}
70
71USItype
72__fixunsdfsi (DFtype a)
73{
74  if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
75    return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
76                       - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
77  return (SItype) a;
78}
79
80USItype
81__fixunssfsi (SFtype a)
82{
83  if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
84    return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
85                       - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
86  return (SItype) a;
87}
88
89TFtype
90__floatditf (DItype u)
91{
92  DFtype dh, dl;
93
94  dh = (SItype) (u >> (sizeof (SItype) * 8));
95  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
96  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
97
98  return (TFtype) dh + (TFtype) dl;
99}
100
101TFtype
102__floatunditf (UDItype u)
103{
104  DFtype dh, dl;
105
106  dh = (USItype) (u >> (sizeof (SItype) * 8));
107  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
108  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
109
110  return (TFtype) dh + (TFtype) dl;
111}
112
113DFtype
114__floatdidf (DItype u)
115{
116  DFtype d;
117
118  d = (SItype) (u >> (sizeof (SItype) * 8));
119  d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
120  d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
121
122  return d;
123}
124
125DFtype
126__floatundidf (UDItype u)
127{
128  DFtype d;
129
130  d = (USItype) (u >> (sizeof (SItype) * 8));
131  d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
132  d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
133
134  return d;
135}
136
137SFtype
138__floatdisf (DItype u)
139{
140  DFtype f;
141
142  if (53 < (sizeof (DItype) * 8)
143      && 53 > ((sizeof (DItype) * 8) - 53 + 24))
144    {
145      if (! (- ((DItype) 1 << 53) < u
146             && u < ((DItype) 1 << 53)))
147        {
148          if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
149            {
150              u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
151              u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
152            }
153        }
154    }
155  f = (SItype) (u >> (sizeof (SItype) * 8));
156  f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
157  f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
158
159  return (SFtype) f;
160}
161
162SFtype
163__floatundisf (UDItype u)
164{
165  DFtype f;
166
167  if (53 < (sizeof (DItype) * 8)
168      && 53 > ((sizeof (DItype) * 8) - 53 + 24))
169    {
170      if (u >= ((UDItype) 1 << 53))
171        {
172          if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
173            {
174              u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
175              u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
176            }
177        }
178    }
179  f = (USItype) (u >> (sizeof (SItype) * 8));
180  f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
181  f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
182
183  return (SFtype) f;
184}
185
186DItype
187__fixunstfdi (TFtype a)
188{
189  if (a < 0)
190    return 0;
191
192  /* Compute high word of result, as a flonum.  */
193  const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
194  /* Convert that to fixed (but not to DItype!),
195     and shift it into the high word.  */
196  UDItype v = (USItype) b;
197  v <<= (sizeof (SItype) * 8);
198  /* Remove high part from the TFtype, leaving the low part as flonum.  */
199  a -= (TFtype) v;
200  /* Convert that to fixed (but not to DItype!) and add it in.
201     Sometimes A comes out negative.  This is significant, since
202     A has more bits than a long int does.  */
203  if (a < 0)
204    v -= (USItype) (-a);
205  else
206    v += (USItype) a;
207  return v;
208}
209
210/* This version is needed to prevent recursion; fixunsdfdi in libgcc
211   calls fixdfdi, which in turn calls calls fixunsdfdi.  */
212
213static DItype
214local_fixunsdfdi (DFtype a)
215{
216  USItype hi, lo;
217
218  hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
219  lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
220  return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
221}
222
223/* This version is needed to prevent recursion; fixunssfdi in libgcc
224   calls fixsfdi, which in turn calls calls fixunssfdi.  */
225
226static DItype
227local_fixunssfdi (SFtype original_a)
228{
229  DFtype a = original_a;
230  USItype hi, lo;
231
232  hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
233  lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
234  return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
235}
236
237#endif /* __powerpc64__ */
238