]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.c
ArmPkg: Apply uncrustify changes
[mirror_edk2.git] / ArmPkg / Library / ArmSoftFloatLib / 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 */
21 typedef uint32_t aeabi_float_t;
22 typedef 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 */
28 static aeabi_float_t
29 f32_to_f (
30 float32_t val
31 )
32 {
33 return val.v;
34 }
35
36 static float32_t
37 f32_from_f (
38 aeabi_float_t val
39 )
40 {
41 float32_t res;
42
43 res.v = val;
44
45 return res;
46 }
47
48 static aeabi_double_t
49 f64_to_d (
50 float64_t val
51 )
52 {
53 return val.v;
54 }
55
56 static float64_t
57 f64_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 */
79 aeabi_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
88 aeabi_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
97 aeabi_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
106 aeabi_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
115 aeabi_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 */
127 int
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
136 int
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
145 int
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
154 int
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
163 int
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 */
176 aeabi_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
185 aeabi_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
194 aeabi_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
203 aeabi_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
212 aeabi_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 */
225 int
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
234 int
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
243 int
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
252 int
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
261 int
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 */
273 int
274 __aeabi_d2iz (
275 aeabi_double_t a
276 )
277 {
278 return f64_to_i32_r_minMag (f64_from_d (a), false);
279 }
280
281 unsigned
282 __aeabi_d2uiz (
283 aeabi_double_t a
284 )
285 {
286 return f64_to_ui32_r_minMag (f64_from_d (a), false);
287 }
288
289 long 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
297 unsigned 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
305 int
306 __aeabi_f2iz (
307 aeabi_float_t a
308 )
309 {
310 return f32_to_i32_r_minMag (f32_from_f (a), false);
311 }
312
313 unsigned
314 __aeabi_f2uiz (
315 aeabi_float_t a
316 )
317 {
318 return f32_to_ui32_r_minMag (f32_from_f (a), false);
319 }
320
321 long 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
329 unsigned 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 */
340 aeabi_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
348 aeabi_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 */
359 aeabi_double_t
360 __aeabi_i2d (
361 int a
362 )
363 {
364 return f64_to_d (i32_to_f64 (a));
365 }
366
367 aeabi_double_t
368 __aeabi_ui2d (
369 unsigned a
370 )
371 {
372 return f64_to_d (ui32_to_f64 (a));
373 }
374
375 aeabi_double_t
376 __aeabi_l2d (
377 long long a
378 )
379 {
380 return f64_to_d (i64_to_f64 (a));
381 }
382
383 aeabi_double_t
384 __aeabi_ul2d (
385 unsigned long long a
386 )
387 {
388 return f64_to_d (ui64_to_f64 (a));
389 }
390
391 aeabi_float_t
392 __aeabi_i2f (
393 int a
394 )
395 {
396 return f32_to_f (i32_to_f32 (a));
397 }
398
399 aeabi_float_t
400 __aeabi_ui2f (
401 unsigned a
402 )
403 {
404 return f32_to_f (ui32_to_f32 (a));
405 }
406
407 aeabi_float_t
408 __aeabi_l2f (
409 long long a
410 )
411 {
412 return f32_to_f (i64_to_f32 (a));
413 }
414
415 aeabi_float_t
416 __aeabi_ul2f (
417 unsigned long long a
418 )
419 {
420 return f32_to_f (ui64_to_f32 (a));
421 }