1*1bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2fce4cfa1SJens Wiklander /*
3fce4cfa1SJens Wiklander * Copyright (c) 2015, Linaro Limited
4fce4cfa1SJens Wiklander */
5fce4cfa1SJens Wiklander
60de9a5fbSJens Wiklander #include <compiler.h>
7fce4cfa1SJens Wiklander #include "platform.h"
8fce4cfa1SJens Wiklander #include <softfloat.h>
9fce4cfa1SJens Wiklander
10fce4cfa1SJens Wiklander /*
110de9a5fbSJens Wiklander * On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
120de9a5fbSJens Wiklander * hard-float is basically a super set of soft-float. Hard-float requires
130de9a5fbSJens Wiklander * all the support routines provided for soft-float, but the compiler may
140de9a5fbSJens Wiklander * choose to optimize to not use some of them.
150de9a5fbSJens Wiklander *
160de9a5fbSJens Wiklander * The AEABI functions uses soft-float calling convention even if the
170de9a5fbSJens Wiklander * functions are compiled for hard-float. So where float and double would
180de9a5fbSJens Wiklander * have been expected we use aeabi_float_t and aeabi_double_t respectively
190de9a5fbSJens Wiklander * instead.
20fce4cfa1SJens Wiklander */
210de9a5fbSJens Wiklander typedef unsigned aeabi_float_t;
220de9a5fbSJens Wiklander typedef unsigned long long aeabi_double_t;
230de9a5fbSJens Wiklander
240de9a5fbSJens Wiklander /*
250de9a5fbSJens Wiklander * Helpers to convert between float32 and aeabi_float_t, and float64 and
260de9a5fbSJens Wiklander * aeabi_double_t used by the AEABI functions below.
270de9a5fbSJens Wiklander */
f32_to_f(float32_t val)280de9a5fbSJens Wiklander static aeabi_float_t f32_to_f(float32_t val)
29fce4cfa1SJens Wiklander {
30fce4cfa1SJens Wiklander union {
31fce4cfa1SJens Wiklander float32_t from;
320de9a5fbSJens Wiklander aeabi_float_t to;
33fce4cfa1SJens Wiklander } res = { .from = val };
34fce4cfa1SJens Wiklander
35fce4cfa1SJens Wiklander return res.to;
36fce4cfa1SJens Wiklander }
37fce4cfa1SJens Wiklander
f32_from_f(aeabi_float_t val)380de9a5fbSJens Wiklander static float32_t f32_from_f(aeabi_float_t val)
39fce4cfa1SJens Wiklander {
40fce4cfa1SJens Wiklander union {
410de9a5fbSJens Wiklander aeabi_float_t from;
42fce4cfa1SJens Wiklander float32_t to;
43fce4cfa1SJens Wiklander } res = { .from = val };
44fce4cfa1SJens Wiklander
45fce4cfa1SJens Wiklander return res.to;
46fce4cfa1SJens Wiklander }
47fce4cfa1SJens Wiklander
f64_to_d(float64_t val)480de9a5fbSJens Wiklander static aeabi_double_t f64_to_d(float64_t val)
49fce4cfa1SJens Wiklander {
50fce4cfa1SJens Wiklander union {
51fce4cfa1SJens Wiklander float64_t from;
520de9a5fbSJens Wiklander aeabi_double_t to;
53fce4cfa1SJens Wiklander } res = { .from = val };
54fce4cfa1SJens Wiklander
55fce4cfa1SJens Wiklander return res.to;
56fce4cfa1SJens Wiklander }
57fce4cfa1SJens Wiklander
f64_from_d(aeabi_double_t val)580de9a5fbSJens Wiklander static float64_t f64_from_d(aeabi_double_t val)
59fce4cfa1SJens Wiklander {
60fce4cfa1SJens Wiklander union {
610de9a5fbSJens Wiklander aeabi_double_t from;
62fce4cfa1SJens Wiklander float64_t to;
63fce4cfa1SJens Wiklander } res = { .from = val };
64fce4cfa1SJens Wiklander
65fce4cfa1SJens Wiklander return res.to;
66fce4cfa1SJens Wiklander }
67fce4cfa1SJens Wiklander
68fce4cfa1SJens Wiklander /*
69fce4cfa1SJens Wiklander * From ARM Run-time ABI for ARM Architecture
70fce4cfa1SJens Wiklander * ARM IHI 0043D, current through ABI release 2.09
71fce4cfa1SJens Wiklander *
72fce4cfa1SJens Wiklander * 4.1.2 The floating-point helper functions
73fce4cfa1SJens Wiklander */
74fce4cfa1SJens Wiklander
75fce4cfa1SJens Wiklander /*
760de9a5fbSJens Wiklander * Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
77fce4cfa1SJens Wiklander * functions
78fce4cfa1SJens Wiklander */
79fce4cfa1SJens Wiklander
__aeabi_dadd(aeabi_double_t a,aeabi_double_t b)800de9a5fbSJens Wiklander aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
81fce4cfa1SJens Wiklander {
82fce4cfa1SJens Wiklander return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
83fce4cfa1SJens Wiklander }
84fce4cfa1SJens Wiklander
__aeabi_ddiv(aeabi_double_t a,aeabi_double_t b)850de9a5fbSJens Wiklander aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
86fce4cfa1SJens Wiklander {
87fce4cfa1SJens Wiklander return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
88fce4cfa1SJens Wiklander }
89fce4cfa1SJens Wiklander
__aeabi_dmul(aeabi_double_t a,aeabi_double_t b)900de9a5fbSJens Wiklander aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
91fce4cfa1SJens Wiklander {
92fce4cfa1SJens Wiklander return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
93fce4cfa1SJens Wiklander }
94fce4cfa1SJens Wiklander
95fce4cfa1SJens Wiklander
__aeabi_drsub(aeabi_double_t a,aeabi_double_t b)960de9a5fbSJens Wiklander aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
97fce4cfa1SJens Wiklander {
98fce4cfa1SJens Wiklander return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
99fce4cfa1SJens Wiklander }
100fce4cfa1SJens Wiklander
__aeabi_dsub(aeabi_double_t a,aeabi_double_t b)1010de9a5fbSJens Wiklander aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
102fce4cfa1SJens Wiklander {
103fce4cfa1SJens Wiklander return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
104fce4cfa1SJens Wiklander }
105fce4cfa1SJens Wiklander
106fce4cfa1SJens Wiklander /*
107fce4cfa1SJens Wiklander * Table 3, double precision floating-point comparison helper functions
108fce4cfa1SJens Wiklander */
109fce4cfa1SJens Wiklander
__aeabi_dcmpeq(aeabi_double_t a,aeabi_double_t b)1100de9a5fbSJens Wiklander int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
111fce4cfa1SJens Wiklander {
112fce4cfa1SJens Wiklander return f64_eq(f64_from_d(a), f64_from_d(b));
113fce4cfa1SJens Wiklander }
114fce4cfa1SJens Wiklander
__aeabi_dcmplt(aeabi_double_t a,aeabi_double_t b)1150de9a5fbSJens Wiklander int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
116fce4cfa1SJens Wiklander {
117fce4cfa1SJens Wiklander return f64_lt(f64_from_d(a), f64_from_d(b));
118fce4cfa1SJens Wiklander }
119fce4cfa1SJens Wiklander
__aeabi_dcmple(aeabi_double_t a,aeabi_double_t b)1200de9a5fbSJens Wiklander int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
121fce4cfa1SJens Wiklander {
122fce4cfa1SJens Wiklander return f64_le(f64_from_d(a), f64_from_d(b));
123fce4cfa1SJens Wiklander }
124fce4cfa1SJens Wiklander
__aeabi_dcmpge(aeabi_double_t a,aeabi_double_t b)1250de9a5fbSJens Wiklander int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
126fce4cfa1SJens Wiklander {
127fce4cfa1SJens Wiklander return f64_le(f64_from_d(b), f64_from_d(a));
128fce4cfa1SJens Wiklander }
129fce4cfa1SJens Wiklander
__aeabi_dcmpgt(aeabi_double_t a,aeabi_double_t b)1300de9a5fbSJens Wiklander int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
131fce4cfa1SJens Wiklander {
132fce4cfa1SJens Wiklander return f64_lt(f64_from_d(b), f64_from_d(a));
133fce4cfa1SJens Wiklander }
134fce4cfa1SJens Wiklander
135fce4cfa1SJens Wiklander /*
136fce4cfa1SJens Wiklander * Table 4, Standard single precision floating-point arithmetic helper
137fce4cfa1SJens Wiklander * functions
138fce4cfa1SJens Wiklander */
139fce4cfa1SJens Wiklander
__aeabi_fadd(aeabi_float_t a,aeabi_float_t b)1400de9a5fbSJens Wiklander aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
141fce4cfa1SJens Wiklander {
142fce4cfa1SJens Wiklander return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
143fce4cfa1SJens Wiklander }
144fce4cfa1SJens Wiklander
__aeabi_fdiv(aeabi_float_t a,aeabi_float_t b)1450de9a5fbSJens Wiklander aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
146fce4cfa1SJens Wiklander {
147fce4cfa1SJens Wiklander return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
148fce4cfa1SJens Wiklander }
149fce4cfa1SJens Wiklander
__aeabi_fmul(aeabi_float_t a,aeabi_float_t b)1500de9a5fbSJens Wiklander aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
151fce4cfa1SJens Wiklander {
152fce4cfa1SJens Wiklander return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
153fce4cfa1SJens Wiklander }
154fce4cfa1SJens Wiklander
__aeabi_frsub(aeabi_float_t a,aeabi_float_t b)1550de9a5fbSJens Wiklander aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
156fce4cfa1SJens Wiklander {
157fce4cfa1SJens Wiklander return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
158fce4cfa1SJens Wiklander }
159fce4cfa1SJens Wiklander
__aeabi_fsub(aeabi_float_t a,aeabi_float_t b)1600de9a5fbSJens Wiklander aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
161fce4cfa1SJens Wiklander {
162fce4cfa1SJens Wiklander return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
163fce4cfa1SJens Wiklander }
164fce4cfa1SJens Wiklander
165fce4cfa1SJens Wiklander /*
166fce4cfa1SJens Wiklander * Table 5, Standard single precision floating-point comparison helper
167fce4cfa1SJens Wiklander * functions
168fce4cfa1SJens Wiklander */
169fce4cfa1SJens Wiklander
__aeabi_fcmpeq(aeabi_float_t a,aeabi_float_t b)1700de9a5fbSJens Wiklander int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
171fce4cfa1SJens Wiklander {
172fce4cfa1SJens Wiklander return f32_eq(f32_from_f(a), f32_from_f(b));
173fce4cfa1SJens Wiklander }
174fce4cfa1SJens Wiklander
__aeabi_fcmplt(aeabi_float_t a,aeabi_float_t b)1750de9a5fbSJens Wiklander int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
176fce4cfa1SJens Wiklander {
177fce4cfa1SJens Wiklander return f32_lt(f32_from_f(a), f32_from_f(b));
178fce4cfa1SJens Wiklander }
179fce4cfa1SJens Wiklander
__aeabi_fcmple(aeabi_float_t a,aeabi_float_t b)1800de9a5fbSJens Wiklander int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
181fce4cfa1SJens Wiklander {
182fce4cfa1SJens Wiklander return f32_le(f32_from_f(a), f32_from_f(b));
183fce4cfa1SJens Wiklander }
184fce4cfa1SJens Wiklander
__aeabi_fcmpge(aeabi_float_t a,aeabi_float_t b)1850de9a5fbSJens Wiklander int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
186fce4cfa1SJens Wiklander {
187fce4cfa1SJens Wiklander return f32_le(f32_from_f(b), f32_from_f(a));
188fce4cfa1SJens Wiklander }
189fce4cfa1SJens Wiklander
__aeabi_fcmpgt(aeabi_float_t a,aeabi_float_t b)1900de9a5fbSJens Wiklander int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
191fce4cfa1SJens Wiklander {
192fce4cfa1SJens Wiklander return f32_lt(f32_from_f(b), f32_from_f(a));
193fce4cfa1SJens Wiklander }
194fce4cfa1SJens Wiklander
195fce4cfa1SJens Wiklander /*
196fce4cfa1SJens Wiklander * Table 6, Standard floating-point to integer conversions
197fce4cfa1SJens Wiklander */
198fce4cfa1SJens Wiklander
__aeabi_d2iz(aeabi_double_t a)1990de9a5fbSJens Wiklander int __aeabi_d2iz(aeabi_double_t a)
200fce4cfa1SJens Wiklander {
201fce4cfa1SJens Wiklander return f64_to_i32_r_minMag(f64_from_d(a), false);
202fce4cfa1SJens Wiklander }
203fce4cfa1SJens Wiklander
__aeabi_d2uiz(aeabi_double_t a)2040de9a5fbSJens Wiklander unsigned __aeabi_d2uiz(aeabi_double_t a)
205fce4cfa1SJens Wiklander {
206fce4cfa1SJens Wiklander return f64_to_ui32_r_minMag(f64_from_d(a), false);
207fce4cfa1SJens Wiklander }
208fce4cfa1SJens Wiklander
__aeabi_d2lz(aeabi_double_t a)2090de9a5fbSJens Wiklander long long __aeabi_d2lz(aeabi_double_t a)
210fce4cfa1SJens Wiklander {
211fce4cfa1SJens Wiklander return f64_to_i64_r_minMag(f64_from_d(a), false);
212fce4cfa1SJens Wiklander }
213fce4cfa1SJens Wiklander
__aeabi_d2ulz(aeabi_double_t a)2140de9a5fbSJens Wiklander unsigned long long __aeabi_d2ulz(aeabi_double_t a)
215fce4cfa1SJens Wiklander {
216fce4cfa1SJens Wiklander return f64_to_ui64_r_minMag(f64_from_d(a), false);
217fce4cfa1SJens Wiklander }
218fce4cfa1SJens Wiklander
__aeabi_f2iz(aeabi_float_t a)2190de9a5fbSJens Wiklander int __aeabi_f2iz(aeabi_float_t a)
220fce4cfa1SJens Wiklander {
221fce4cfa1SJens Wiklander return f32_to_i32_r_minMag(f32_from_f(a), false);
222fce4cfa1SJens Wiklander }
223fce4cfa1SJens Wiklander
__aeabi_f2uiz(aeabi_float_t a)2240de9a5fbSJens Wiklander unsigned __aeabi_f2uiz(aeabi_float_t a)
225fce4cfa1SJens Wiklander {
226fce4cfa1SJens Wiklander return f32_to_ui32_r_minMag(f32_from_f(a), false);
227fce4cfa1SJens Wiklander }
228fce4cfa1SJens Wiklander
__aeabi_f2lz(aeabi_float_t a)2290de9a5fbSJens Wiklander long long __aeabi_f2lz(aeabi_float_t a)
230fce4cfa1SJens Wiklander {
231fce4cfa1SJens Wiklander return f32_to_i64_r_minMag(f32_from_f(a), false);
232fce4cfa1SJens Wiklander }
233fce4cfa1SJens Wiklander
__aeabi_f2ulz(aeabi_float_t a)2340de9a5fbSJens Wiklander unsigned long long __aeabi_f2ulz(aeabi_float_t a)
235fce4cfa1SJens Wiklander {
236fce4cfa1SJens Wiklander return f32_to_ui64_r_minMag(f32_from_f(a), false);
237fce4cfa1SJens Wiklander }
238fce4cfa1SJens Wiklander
239fce4cfa1SJens Wiklander /*
240fce4cfa1SJens Wiklander * Table 7, Standard conversions between floating types
241fce4cfa1SJens Wiklander */
242fce4cfa1SJens Wiklander
__aeabi_d2f(aeabi_double_t a)2430de9a5fbSJens Wiklander aeabi_float_t __aeabi_d2f(aeabi_double_t a)
244fce4cfa1SJens Wiklander {
245fce4cfa1SJens Wiklander return f32_to_f(f64_to_f32(f64_from_d(a)));
246fce4cfa1SJens Wiklander }
247fce4cfa1SJens Wiklander
__aeabi_f2d(aeabi_float_t a)2480de9a5fbSJens Wiklander aeabi_double_t __aeabi_f2d(aeabi_float_t a)
249fce4cfa1SJens Wiklander {
250fce4cfa1SJens Wiklander return f64_to_d(f32_to_f64(f32_from_f(a)));
251fce4cfa1SJens Wiklander }
252fce4cfa1SJens Wiklander
253fce4cfa1SJens Wiklander /*
254fce4cfa1SJens Wiklander * Table 8, Standard integer to floating-point conversions
255fce4cfa1SJens Wiklander */
256fce4cfa1SJens Wiklander
__aeabi_i2d(int a)2570de9a5fbSJens Wiklander aeabi_double_t __aeabi_i2d(int a)
258fce4cfa1SJens Wiklander {
259fce4cfa1SJens Wiklander return f64_to_d(i32_to_f64(a));
260fce4cfa1SJens Wiklander }
261fce4cfa1SJens Wiklander
__aeabi_ui2d(unsigned a)2620de9a5fbSJens Wiklander aeabi_double_t __aeabi_ui2d(unsigned a)
263fce4cfa1SJens Wiklander {
264fce4cfa1SJens Wiklander return f64_to_d(ui32_to_f64(a));
265fce4cfa1SJens Wiklander }
266fce4cfa1SJens Wiklander
__aeabi_l2d(long long a)2670de9a5fbSJens Wiklander aeabi_double_t __aeabi_l2d(long long a)
268fce4cfa1SJens Wiklander {
269fce4cfa1SJens Wiklander return f64_to_d(i64_to_f64(a));
270fce4cfa1SJens Wiklander }
271fce4cfa1SJens Wiklander
__aeabi_ul2d(unsigned long long a)2720de9a5fbSJens Wiklander aeabi_double_t __aeabi_ul2d(unsigned long long a)
273fce4cfa1SJens Wiklander {
274fce4cfa1SJens Wiklander return f64_to_d(ui64_to_f64(a));
275fce4cfa1SJens Wiklander }
276fce4cfa1SJens Wiklander
__aeabi_i2f(int a)2770de9a5fbSJens Wiklander aeabi_float_t __aeabi_i2f(int a)
278fce4cfa1SJens Wiklander {
279fce4cfa1SJens Wiklander return f32_to_f(i32_to_f32(a));
280fce4cfa1SJens Wiklander }
281fce4cfa1SJens Wiklander
__aeabi_ui2f(unsigned a)2820de9a5fbSJens Wiklander aeabi_float_t __aeabi_ui2f(unsigned a)
283fce4cfa1SJens Wiklander {
284fce4cfa1SJens Wiklander return f32_to_f(ui32_to_f32(a));
285fce4cfa1SJens Wiklander }
286fce4cfa1SJens Wiklander
__aeabi_l2f(long long a)2870de9a5fbSJens Wiklander aeabi_float_t __aeabi_l2f(long long a)
288fce4cfa1SJens Wiklander {
289fce4cfa1SJens Wiklander return f32_to_f(i64_to_f32(a));
290fce4cfa1SJens Wiklander }
291fce4cfa1SJens Wiklander
__aeabi_ul2f(unsigned long long a)2920de9a5fbSJens Wiklander aeabi_float_t __aeabi_ul2f(unsigned long long a)
293fce4cfa1SJens Wiklander {
294fce4cfa1SJens Wiklander return f32_to_f(ui64_to_f32(a));
295fce4cfa1SJens Wiklander }
296