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