]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.c
ArmPkg/ArmSoftFloatLib: switch to new version of softfloat library
[mirror_edk2.git] / ArmPkg / Library / ArmSoftFloatLib / ArmSoftFloatLib.c
CommitLineData
3cc57695
AB
1/*
2 * Copyright (c) 2015 - 2019, Linaro Limited
3 *
4 * SPDX-License-Identifier: BSD-2-Clause-Patent
5 */
6
7#include "platform.h"
8#include <softfloat.h>
9
10/*
11 * On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
12 * hard-float is basically a super set of soft-float. Hard-float requires
13 * all the support routines provided for soft-float, but the compiler may
14 * choose to optimize to not use some of them.
15 *
16 * The AEABI functions uses soft-float calling convention even if the
17 * functions are compiled for hard-float. So where float and double would
18 * have been expected we use aeabi_float_t and aeabi_double_t respectively
19 * instead.
20 */
21typedef uint32_t aeabi_float_t;
22typedef uint64_t aeabi_double_t;
23
24/*
25 * Helpers to convert between float32 and aeabi_float_t, and float64 and
26 * aeabi_double_t used by the AEABI functions below.
27 */
28static aeabi_float_t f32_to_f(float32_t val)
29{
30 return val.v;
31}
32
33static float32_t f32_from_f(aeabi_float_t val)
34{
35 float32_t res;
36
37 res.v = val;
38
39 return res;
40}
41
42static aeabi_double_t f64_to_d(float64_t val)
43{
44 return val.v;
45}
46
47static float64_t f64_from_d(aeabi_double_t val)
48{
49 float64_t res;
50
51 res.v = val;
52
53 return res;
54}
55
56/*
57 * From ARM Run-time ABI for ARM Architecture
58 * ARM IHI 0043D, current through ABI release 2.09
59 *
60 * 4.1.2 The floating-point helper functions
61 */
62
63/*
64 * Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
65 * functions
66 */
67
68aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
69{
70 return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
71}
72
73aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
74{
75 return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
76}
77
78aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
79{
80 return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
81}
82
83
84aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
85{
86 return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
87}
88
89aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
90{
91 return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
92}
93
94/*
95 * Table 3, double precision floating-point comparison helper functions
96 */
97
98int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
99{
100 return f64_eq(f64_from_d(a), f64_from_d(b));
101}
102
103int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
104{
105 return f64_lt(f64_from_d(a), f64_from_d(b));
106}
107
108int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
109{
110 return f64_le(f64_from_d(a), f64_from_d(b));
111}
112
113int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
114{
115 return f64_le(f64_from_d(b), f64_from_d(a));
116}
117
118int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
119{
120 return f64_lt(f64_from_d(b), f64_from_d(a));
121}
122
123/*
124 * Table 4, Standard single precision floating-point arithmetic helper
125 * functions
126 */
127
128aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
129{
130 return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
131}
132
133aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
134{
135 return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
136}
137
138aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
139{
140 return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
141}
142
143aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
144{
145 return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
146}
147
148aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
149{
150 return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
151}
152
153/*
154 * Table 5, Standard single precision floating-point comparison helper
155 * functions
156 */
157
158int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
159{
160 return f32_eq(f32_from_f(a), f32_from_f(b));
161}
162
163int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
164{
165 return f32_lt(f32_from_f(a), f32_from_f(b));
166}
167
168int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
169{
170 return f32_le(f32_from_f(a), f32_from_f(b));
171}
172
173int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
174{
175 return f32_le(f32_from_f(b), f32_from_f(a));
176}
177
178int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
179{
180 return f32_lt(f32_from_f(b), f32_from_f(a));
181}
182
183/*
184 * Table 6, Standard floating-point to integer conversions
185 */
186
187int __aeabi_d2iz(aeabi_double_t a)
188{
189 return f64_to_i32_r_minMag(f64_from_d(a), false);
190}
191
192unsigned __aeabi_d2uiz(aeabi_double_t a)
193{
194 return f64_to_ui32_r_minMag(f64_from_d(a), false);
195}
196
197long long __aeabi_d2lz(aeabi_double_t a)
198{
199 return f64_to_i64_r_minMag(f64_from_d(a), false);
200}
201
202unsigned long long __aeabi_d2ulz(aeabi_double_t a)
203{
204 return f64_to_ui64_r_minMag(f64_from_d(a), false);
205}
206
207int __aeabi_f2iz(aeabi_float_t a)
208{
209 return f32_to_i32_r_minMag(f32_from_f(a), false);
210}
211
212unsigned __aeabi_f2uiz(aeabi_float_t a)
213{
214 return f32_to_ui32_r_minMag(f32_from_f(a), false);
215}
216
217long long __aeabi_f2lz(aeabi_float_t a)
218{
219 return f32_to_i64_r_minMag(f32_from_f(a), false);
220}
221
222unsigned long long __aeabi_f2ulz(aeabi_float_t a)
223{
224 return f32_to_ui64_r_minMag(f32_from_f(a), false);
225}
226
227/*
228 * Table 7, Standard conversions between floating types
229 */
230
231aeabi_float_t __aeabi_d2f(aeabi_double_t a)
232{
233 return f32_to_f(f64_to_f32(f64_from_d(a)));
234}
235
236aeabi_double_t __aeabi_f2d(aeabi_float_t a)
237{
238 return f64_to_d(f32_to_f64(f32_from_f(a)));
239}
240
241/*
242 * Table 8, Standard integer to floating-point conversions
243 */
244
245aeabi_double_t __aeabi_i2d(int a)
246{
247 return f64_to_d(i32_to_f64(a));
248}
249
250aeabi_double_t __aeabi_ui2d(unsigned a)
251{
252 return f64_to_d(ui32_to_f64(a));
253}
254
255aeabi_double_t __aeabi_l2d(long long a)
256{
257 return f64_to_d(i64_to_f64(a));
258}
259
260aeabi_double_t __aeabi_ul2d(unsigned long long a)
261{
262 return f64_to_d(ui64_to_f64(a));
263}
264
265aeabi_float_t __aeabi_i2f(int a)
266{
267 return f32_to_f(i32_to_f32(a));
268}
269
270aeabi_float_t __aeabi_ui2f(unsigned a)
271{
272 return f32_to_f(ui32_to_f32(a));
273}
274
275aeabi_float_t __aeabi_l2f(long long a)
276{
277 return f32_to_f(i64_to_f32(a));
278}
279
280aeabi_float_t __aeabi_ul2f(unsigned long long a)
281{
282 return f32_to_f(ui64_to_f32(a));
283}