1 /* Functions needed for soft-float on riscv-linux. Based on
2 rs6000/ppc64-fp.c with TF types removed.
3
4 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5 2000, 2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation,
6 Inc.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
19
20 Under Section 7 of GPL version 3, you are granted additional
21 permissions described in the GCC Runtime Library Exception, version
22 3.1, as published by the Free Software Foundation.
23
24 You should have received a copy of the GNU General Public License and
25 a copy of the GCC Runtime Library Exception along with this program;
26 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
27 <http://www.gnu.org/licenses/>. */
28
29 #if defined(__riscv64)
30 #include "fp-bit.h"
31
32 extern DItype __fixdfdi (DFtype);
33 extern DItype __fixsfdi (SFtype);
34 extern USItype __fixunsdfsi (DFtype);
35 extern USItype __fixunssfsi (SFtype);
36 extern DFtype __floatdidf (DItype);
37 extern DFtype __floatundidf (UDItype);
38 extern SFtype __floatdisf (DItype);
39 extern SFtype __floatundisf (UDItype);
40
41 static DItype local_fixunssfdi (SFtype);
42 static DItype local_fixunsdfdi (DFtype);
43
44 DItype
__fixdfdi(DFtype a)45 __fixdfdi (DFtype a)
46 {
47 if (a < 0)
48 return - local_fixunsdfdi (-a);
49 return local_fixunsdfdi (a);
50 }
51
52 DItype
__fixsfdi(SFtype a)53 __fixsfdi (SFtype a)
54 {
55 if (a < 0)
56 return - local_fixunssfdi (-a);
57 return local_fixunssfdi (a);
58 }
59
60 USItype
__fixunsdfsi(DFtype a)61 __fixunsdfsi (DFtype a)
62 {
63 if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
64 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
65 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
66 return (SItype) a;
67 }
68
69 USItype
__fixunssfsi(SFtype a)70 __fixunssfsi (SFtype a)
71 {
72 if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
73 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
74 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
75 return (SItype) a;
76 }
77
78 DFtype
__floatdidf(DItype u)79 __floatdidf (DItype u)
80 {
81 DFtype d;
82
83 d = (SItype) (u >> (sizeof (SItype) * 8));
84 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
85 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
86
87 return d;
88 }
89
90 DFtype
__floatundidf(UDItype u)91 __floatundidf (UDItype u)
92 {
93 DFtype d;
94
95 d = (USItype) (u >> (sizeof (SItype) * 8));
96 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
97 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
98
99 return d;
100 }
101
102 SFtype
__floatdisf(DItype u)103 __floatdisf (DItype u)
104 {
105 DFtype f;
106
107 if (53 < (sizeof (DItype) * 8)
108 && 53 > ((sizeof (DItype) * 8) - 53 + 24))
109 {
110 if (! (- ((DItype) 1 << 53) < u
111 && u < ((DItype) 1 << 53)))
112 {
113 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
114 {
115 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
116 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
117 }
118 }
119 }
120 f = (SItype) (u >> (sizeof (SItype) * 8));
121 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
122 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
123
124 return (SFtype) f;
125 }
126
127 SFtype
__floatundisf(UDItype u)128 __floatundisf (UDItype u)
129 {
130 DFtype f;
131
132 if (53 < (sizeof (DItype) * 8)
133 && 53 > ((sizeof (DItype) * 8) - 53 + 24))
134 {
135 if (u >= ((UDItype) 1 << 53))
136 {
137 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
138 {
139 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
140 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
141 }
142 }
143 }
144 f = (USItype) (u >> (sizeof (SItype) * 8));
145 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
146 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
147
148 return (SFtype) f;
149 }
150
151 /* This version is needed to prevent recursion; fixunsdfdi in libgcc
152 calls fixdfdi, which in turn calls calls fixunsdfdi. */
153
154 static DItype
local_fixunsdfdi(DFtype a)155 local_fixunsdfdi (DFtype a)
156 {
157 USItype hi, lo;
158
159 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
160 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
161 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
162 }
163
164 /* This version is needed to prevent recursion; fixunssfdi in libgcc
165 calls fixsfdi, which in turn calls calls fixunssfdi. */
166
167 static DItype
local_fixunssfdi(SFtype original_a)168 local_fixunssfdi (SFtype original_a)
169 {
170 DFtype a = original_a;
171 USItype hi, lo;
172
173 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
174 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
175 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
176 }
177
178 #endif
179