]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.c
42bed7700c9927f457dfddfe4c09063c2f0d2a61
2 * Copyright (c) 2015 - 2019, Linaro Limited
4 * SPDX-License-Identifier: BSD-2-Clause-Patent
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.
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
21 typedef uint32_t aeabi_float_t
;
22 typedef uint64_t aeabi_double_t
;
25 * Helpers to convert between float32 and aeabi_float_t, and float64 and
26 * aeabi_double_t used by the AEABI functions below.
28 static aeabi_float_t
f32_to_f(float32_t val
)
33 static float32_t
f32_from_f(aeabi_float_t val
)
42 static aeabi_double_t
f64_to_d(float64_t val
)
47 static float64_t
f64_from_d(aeabi_double_t val
)
57 * From ARM Run-time ABI for ARM Architecture
58 * ARM IHI 0043D, current through ABI release 2.09
60 * 4.1.2 The floating-point helper functions
64 * Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
68 aeabi_double_t
__aeabi_dadd(aeabi_double_t a
, aeabi_double_t b
)
70 return f64_to_d(f64_add(f64_from_d(a
), f64_from_d(b
)));
73 aeabi_double_t
__aeabi_ddiv(aeabi_double_t a
, aeabi_double_t b
)
75 return f64_to_d(f64_div(f64_from_d(a
), f64_from_d(b
)));
78 aeabi_double_t
__aeabi_dmul(aeabi_double_t a
, aeabi_double_t b
)
80 return f64_to_d(f64_mul(f64_from_d(a
), f64_from_d(b
)));
84 aeabi_double_t
__aeabi_drsub(aeabi_double_t a
, aeabi_double_t b
)
86 return f64_to_d(f64_sub(f64_from_d(b
), f64_from_d(a
)));
89 aeabi_double_t
__aeabi_dsub(aeabi_double_t a
, aeabi_double_t b
)
91 return f64_to_d(f64_sub(f64_from_d(a
), f64_from_d(b
)));
95 * Table 3, double precision floating-point comparison helper functions
98 int __aeabi_dcmpeq(aeabi_double_t a
, aeabi_double_t b
)
100 return f64_eq(f64_from_d(a
), f64_from_d(b
));
103 int __aeabi_dcmplt(aeabi_double_t a
, aeabi_double_t b
)
105 return f64_lt(f64_from_d(a
), f64_from_d(b
));
108 int __aeabi_dcmple(aeabi_double_t a
, aeabi_double_t b
)
110 return f64_le(f64_from_d(a
), f64_from_d(b
));
113 int __aeabi_dcmpge(aeabi_double_t a
, aeabi_double_t b
)
115 return f64_le(f64_from_d(b
), f64_from_d(a
));
118 int __aeabi_dcmpgt(aeabi_double_t a
, aeabi_double_t b
)
120 return f64_lt(f64_from_d(b
), f64_from_d(a
));
124 * Table 4, Standard single precision floating-point arithmetic helper
128 aeabi_float_t
__aeabi_fadd(aeabi_float_t a
, aeabi_float_t b
)
130 return f32_to_f(f32_add(f32_from_f(a
), f32_from_f(b
)));
133 aeabi_float_t
__aeabi_fdiv(aeabi_float_t a
, aeabi_float_t b
)
135 return f32_to_f(f32_div(f32_from_f(a
), f32_from_f(b
)));
138 aeabi_float_t
__aeabi_fmul(aeabi_float_t a
, aeabi_float_t b
)
140 return f32_to_f(f32_mul(f32_from_f(a
), f32_from_f(b
)));
143 aeabi_float_t
__aeabi_frsub(aeabi_float_t a
, aeabi_float_t b
)
145 return f32_to_f(f32_sub(f32_from_f(b
), f32_from_f(a
)));
148 aeabi_float_t
__aeabi_fsub(aeabi_float_t a
, aeabi_float_t b
)
150 return f32_to_f(f32_sub(f32_from_f(a
), f32_from_f(b
)));
154 * Table 5, Standard single precision floating-point comparison helper
158 int __aeabi_fcmpeq(aeabi_float_t a
, aeabi_float_t b
)
160 return f32_eq(f32_from_f(a
), f32_from_f(b
));
163 int __aeabi_fcmplt(aeabi_float_t a
, aeabi_float_t b
)
165 return f32_lt(f32_from_f(a
), f32_from_f(b
));
168 int __aeabi_fcmple(aeabi_float_t a
, aeabi_float_t b
)
170 return f32_le(f32_from_f(a
), f32_from_f(b
));
173 int __aeabi_fcmpge(aeabi_float_t a
, aeabi_float_t b
)
175 return f32_le(f32_from_f(b
), f32_from_f(a
));
178 int __aeabi_fcmpgt(aeabi_float_t a
, aeabi_float_t b
)
180 return f32_lt(f32_from_f(b
), f32_from_f(a
));
184 * Table 6, Standard floating-point to integer conversions
187 int __aeabi_d2iz(aeabi_double_t a
)
189 return f64_to_i32_r_minMag(f64_from_d(a
), false);
192 unsigned __aeabi_d2uiz(aeabi_double_t a
)
194 return f64_to_ui32_r_minMag(f64_from_d(a
), false);
197 long long __aeabi_d2lz(aeabi_double_t a
)
199 return f64_to_i64_r_minMag(f64_from_d(a
), false);
202 unsigned long long __aeabi_d2ulz(aeabi_double_t a
)
204 return f64_to_ui64_r_minMag(f64_from_d(a
), false);
207 int __aeabi_f2iz(aeabi_float_t a
)
209 return f32_to_i32_r_minMag(f32_from_f(a
), false);
212 unsigned __aeabi_f2uiz(aeabi_float_t a
)
214 return f32_to_ui32_r_minMag(f32_from_f(a
), false);
217 long long __aeabi_f2lz(aeabi_float_t a
)
219 return f32_to_i64_r_minMag(f32_from_f(a
), false);
222 unsigned long long __aeabi_f2ulz(aeabi_float_t a
)
224 return f32_to_ui64_r_minMag(f32_from_f(a
), false);
228 * Table 7, Standard conversions between floating types
231 aeabi_float_t
__aeabi_d2f(aeabi_double_t a
)
233 return f32_to_f(f64_to_f32(f64_from_d(a
)));
236 aeabi_double_t
__aeabi_f2d(aeabi_float_t a
)
238 return f64_to_d(f32_to_f64(f32_from_f(a
)));
242 * Table 8, Standard integer to floating-point conversions
245 aeabi_double_t
__aeabi_i2d(int a
)
247 return f64_to_d(i32_to_f64(a
));
250 aeabi_double_t
__aeabi_ui2d(unsigned a
)
252 return f64_to_d(ui32_to_f64(a
));
255 aeabi_double_t
__aeabi_l2d(long long a
)
257 return f64_to_d(i64_to_f64(a
));
260 aeabi_double_t
__aeabi_ul2d(unsigned long long a
)
262 return f64_to_d(ui64_to_f64(a
));
265 aeabi_float_t
__aeabi_i2f(int a
)
267 return f32_to_f(i32_to_f32(a
));
270 aeabi_float_t
__aeabi_ui2f(unsigned a
)
272 return f32_to_f(ui32_to_f32(a
));
275 aeabi_float_t
__aeabi_l2f(long long a
)
277 return f32_to_f(i64_to_f32(a
));
280 aeabi_float_t
__aeabi_ul2f(unsigned long long a
)
282 return f32_to_f(ui64_to_f32(a
));