TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmSoftFloatLib.c
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
29f32_to_f (
30 float32_t val
31 )
32{
33 return val.v;
34}
35
36static float32_t
37f32_from_f (
38 aeabi_float_t val
39 )
40{
41 float32_t res;
42
43 res.v = val;
44
45 return res;
46}
47
48static aeabi_double_t
49f64_to_d (
50 float64_t val
51 )
52{
53 return val.v;
54}
55
56static float64_t
57f64_from_d (
58 aeabi_double_t val
59 )
60{
61 float64_t res;
62
63 res.v = val;
64
65 return res;
66}
67
68/*
69 * From ARM Run-time ABI for ARM Architecture
70 * ARM IHI 0043D, current through ABI release 2.09
71 *
72 * 4.1.2 The floating-point helper functions
73 */
74
75/*
76 * Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
77 * functions
78 */
79aeabi_double_t
80__aeabi_dadd (
81 aeabi_double_t a,
82 aeabi_double_t b
83 )
84{
85 return f64_to_d (f64_add (f64_from_d (a), f64_from_d (b)));
86}
87
88aeabi_double_t
89__aeabi_ddiv (
90 aeabi_double_t a,
91 aeabi_double_t b
92 )
93{
94 return f64_to_d (f64_div (f64_from_d (a), f64_from_d (b)));
95}
96
97aeabi_double_t
98__aeabi_dmul (
99 aeabi_double_t a,
100 aeabi_double_t b
101 )
102{
103 return f64_to_d (f64_mul (f64_from_d (a), f64_from_d (b)));
104}
105
106aeabi_double_t
107__aeabi_drsub (
108 aeabi_double_t a,
109 aeabi_double_t b
110 )
111{
112 return f64_to_d (f64_sub (f64_from_d (b), f64_from_d (a)));
113}
114
115aeabi_double_t
116__aeabi_dsub (
117 aeabi_double_t a,
118 aeabi_double_t b
119 )
120{
121 return f64_to_d (f64_sub (f64_from_d (a), f64_from_d (b)));
122}
123
124/*
125 * Table 3, double precision floating-point comparison helper functions
126 */
127int
128__aeabi_dcmpeq (
129 aeabi_double_t a,
130 aeabi_double_t b
131 )
132{
133 return f64_eq (f64_from_d (a), f64_from_d (b));
134}
135
136int
137__aeabi_dcmplt (
138 aeabi_double_t a,
139 aeabi_double_t b
140 )
141{
142 return f64_lt (f64_from_d (a), f64_from_d (b));
143}
144
145int
146__aeabi_dcmple (
147 aeabi_double_t a,
148 aeabi_double_t b
149 )
150{
151 return f64_le (f64_from_d (a), f64_from_d (b));
152}
153
154int
155__aeabi_dcmpge (
156 aeabi_double_t a,
157 aeabi_double_t b
158 )
159{
160 return f64_le (f64_from_d (b), f64_from_d (a));
161}
162
163int
164__aeabi_dcmpgt (
165 aeabi_double_t a,
166 aeabi_double_t b
167 )
168{
169 return f64_lt (f64_from_d (b), f64_from_d (a));
170}
171
172/*
173 * Table 4, Standard single precision floating-point arithmetic helper
174 * functions
175 */
176aeabi_float_t
177__aeabi_fadd (
178 aeabi_float_t a,
179 aeabi_float_t b
180 )
181{
182 return f32_to_f (f32_add (f32_from_f (a), f32_from_f (b)));
183}
184
185aeabi_float_t
186__aeabi_fdiv (
187 aeabi_float_t a,
188 aeabi_float_t b
189 )
190{
191 return f32_to_f (f32_div (f32_from_f (a), f32_from_f (b)));
192}
193
194aeabi_float_t
195__aeabi_fmul (
196 aeabi_float_t a,
197 aeabi_float_t b
198 )
199{
200 return f32_to_f (f32_mul (f32_from_f (a), f32_from_f (b)));
201}
202
203aeabi_float_t
204__aeabi_frsub (
205 aeabi_float_t a,
206 aeabi_float_t b
207 )
208{
209 return f32_to_f (f32_sub (f32_from_f (b), f32_from_f (a)));
210}
211
212aeabi_float_t
213__aeabi_fsub (
214 aeabi_float_t a,
215 aeabi_float_t b
216 )
217{
218 return f32_to_f (f32_sub (f32_from_f (a), f32_from_f (b)));
219}
220
221/*
222 * Table 5, Standard single precision floating-point comparison helper
223 * functions
224 */
225int
226__aeabi_fcmpeq (
227 aeabi_float_t a,
228 aeabi_float_t b
229 )
230{
231 return f32_eq (f32_from_f (a), f32_from_f (b));
232}
233
234int
235__aeabi_fcmplt (
236 aeabi_float_t a,
237 aeabi_float_t b
238 )
239{
240 return f32_lt (f32_from_f (a), f32_from_f (b));
241}
242
243int
244__aeabi_fcmple (
245 aeabi_float_t a,
246 aeabi_float_t b
247 )
248{
249 return f32_le (f32_from_f (a), f32_from_f (b));
250}
251
252int
253__aeabi_fcmpge (
254 aeabi_float_t a,
255 aeabi_float_t b
256 )
257{
258 return f32_le (f32_from_f (b), f32_from_f (a));
259}
260
261int
262__aeabi_fcmpgt (
263 aeabi_float_t a,
264 aeabi_float_t b
265 )
266{
267 return f32_lt (f32_from_f (b), f32_from_f (a));
268}
269
270/*
271 * Table 6, Standard floating-point to integer conversions
272 */
273int
274__aeabi_d2iz (
275 aeabi_double_t a
276 )
277{
278 return f64_to_i32_r_minMag (f64_from_d (a), false);
279}
280
281unsigned
282__aeabi_d2uiz (
283 aeabi_double_t a
284 )
285{
286 return f64_to_ui32_r_minMag (f64_from_d (a), false);
287}
288
289long long
290__aeabi_d2lz (
291 aeabi_double_t a
292 )
293{
294 return f64_to_i64_r_minMag (f64_from_d (a), false);
295}
296
297unsigned long long
298__aeabi_d2ulz (
299 aeabi_double_t a
300 )
301{
302 return f64_to_ui64_r_minMag (f64_from_d (a), false);
303}
304
305int
306__aeabi_f2iz (
307 aeabi_float_t a
308 )
309{
310 return f32_to_i32_r_minMag (f32_from_f (a), false);
311}
312
313unsigned
314__aeabi_f2uiz (
315 aeabi_float_t a
316 )
317{
318 return f32_to_ui32_r_minMag (f32_from_f (a), false);
319}
320
321long long
322__aeabi_f2lz (
323 aeabi_float_t a
324 )
325{
326 return f32_to_i64_r_minMag (f32_from_f (a), false);
327}
328
329unsigned long long
330__aeabi_f2ulz (
331 aeabi_float_t a
332 )
333{
334 return f32_to_ui64_r_minMag (f32_from_f (a), false);
335}
336
337/*
338 * Table 7, Standard conversions between floating types
339 */
340aeabi_float_t
341__aeabi_d2f (
342 aeabi_double_t a
343 )
344{
345 return f32_to_f (f64_to_f32 (f64_from_d (a)));
346}
347
348aeabi_double_t
349__aeabi_f2d (
350 aeabi_float_t a
351 )
352{
353 return f64_to_d (f32_to_f64 (f32_from_f (a)));
354}
355
356/*
357 * Table 8, Standard integer to floating-point conversions
358 */
359aeabi_double_t
360__aeabi_i2d (
361 int a
362 )
363{
364 return f64_to_d (i32_to_f64 (a));
365}
366
367aeabi_double_t
368__aeabi_ui2d (
369 unsigned a
370 )
371{
372 return f64_to_d (ui32_to_f64 (a));
373}
374
375aeabi_double_t
376__aeabi_l2d (
377 long long a
378 )
379{
380 return f64_to_d (i64_to_f64 (a));
381}
382
383aeabi_double_t
384__aeabi_ul2d (
385 unsigned long long a
386 )
387{
388 return f64_to_d (ui64_to_f64 (a));
389}
390
391aeabi_float_t
392__aeabi_i2f (
393 int a
394 )
395{
396 return f32_to_f (i32_to_f32 (a));
397}
398
399aeabi_float_t
400__aeabi_ui2f (
401 unsigned a
402 )
403{
404 return f32_to_f (ui32_to_f32 (a));
405}
406
407aeabi_float_t
408__aeabi_l2f (
409 long long a
410 )
411{
412 return f32_to_f (i64_to_f32 (a));
413}
414
415aeabi_float_t
416__aeabi_ul2f (
417 unsigned long long a
418 )
419{
420 return f32_to_f (ui64_to_f32 (a));
421}