@web-font-path: "roboto-debian.css";
Menu Toggle
v2.1.1 (RP2040)
Loading...
Searching...
No Matches
float.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3
*
4
* SPDX-License-Identifier: BSD-3-Clause
5
*/
6
7
#ifndef _PICO_FLOAT_H
8
#define _PICO_FLOAT_H
9
10
#include <math.h>
11
#include <
float.h
>
12
#include "
pico.h
"
13
#include "pico/bootrom/sf_table.h"
14
15
#ifdef __cplusplus
16
extern
"C"
{
17
#endif
18
152
#if !defined(__riscv) || PICO_COMBINED_DOCS
153
154
#if PICO_COMBINED_DOCS || !LIB_PICO_FLOAT_COMPILER
155
float
int2float(int32_t i);
156
float
uint2float(uint32_t i);
157
float
int642float(int64_t i);
158
float
uint642float(uint64_t i);
159
float
fix2float(int32_t m,
int
e);
160
float
ufix2float(uint32_t m,
int
e);
161
float
fix642float(int64_t m,
int
e);
162
float
ufix642float(uint64_t m,
int
e);
163
164
// These methods round towards 0, which IS the C way
165
int32_t float2int_z(
float
f);
166
int64_t float2int64_z(
float
f);
167
int32_t float2uint_z(
float
f);
168
int64_t float2uint64_z(
float
f);
169
int32_t float2fix_z(
float
f,
int
e);
170
uint32_t float2ufix_z(
float
f,
int
e);
171
int64_t float2fix64_z(
float
f,
int
e);
172
uint64_t float2ufix64_z(
float
f,
int
e);
173
174
// These methods round towards -Infinity - which IS NOT the C way for negative numbers;
175
// as such the naming is not ideal, however is kept for backwards compatibility
176
int32_t float2int(
float
f);
177
uint32_t float2uint(
float
f);
178
int64_t float2int64(
float
f);
179
uint64_t float2uint64(
float
f);
180
int32_t float2fix(
float
f,
int
e);
181
uint32_t float2ufix(
float
f,
int
e);
182
int64_t float2fix64(
float
f,
int
e);
183
uint64_t float2ufix64(
float
f,
int
e);
184
185
#if LIB_PICO_FLOAT_PICO_VFP
186
// a bit of a hack to inline VFP fixed point conversion when exponent is constant and in range 1-32
187
#define fix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _fix2float_inline(m, e) : fix2 ## float(m, e), fix2 ## float(m, e))
188
#define ufix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _ufix2float_inline(m, e) : ufix2 ## float(m, e), ufix2 ## float(m, e))
189
#define float2fix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_z_inline(f, e) : float2 ## fix_z(f, e), float2 ## fix_z(f, e))
190
#define float2ufix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_z_inline(f, e) : float2 ## ufix_z(f, e), float2 ## ufix_z(f, e))
191
#define float2fix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_inline(f, e) : float2 ## fix(f, e), float2 ## fix(f, e))
192
#define float2ufix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_inline(f, e) : float2 ## ufix(f, e), float2 ## ufix(f, e))
193
194
#define _fix2float_inline(m, e) ({ \
195
int32_t _m = m; \
196
float f; \
197
pico_default_asm( \
198
"vmov %0, %1\n" \
199
"vcvt.f32.s32 %0, %0, %2\n" \
200
: "=t" (f) \
201
: "r" (_m), "i" (e) \
202
); \
203
f; \
204
})
205
#define _ufix2float_inline(m, e) ({ \
206
uint32_t _m = m; \
207
float f; \
208
pico_default_asm( \
209
"vmov %0, %1\n" \
210
"vcvt.f32.u32 %0, %0, %2\n" \
211
: "=t" (f) \
212
: "r" (_m), "i" (e) \
213
); \
214
f; \
215
})
216
#define _float2fix_z_inline(f, e) ({ \
217
int32_t _m; \
218
float _f = (f); \
219
pico_default_asm( \
220
"vcvt.s32.f32 %0, %0, %2\n" \
221
"vmov %1, %0\n" \
222
: "+t" (_f), "=r" (_m) \
223
: "i" (e) \
224
); \
225
_m; \
226
})
227
#define _float2ufix_z_inline(f, e) ({ \
228
uint32_t _m; \
229
float _f = (f); \
230
pico_default_asm( \
231
"vcvt.u32.f32 %0, %0, %2\n" \
232
"vmov %1, %0\n" \
233
: "+t" (_f), "=r" (_m) \
234
: "i" (e) \
235
); \
236
_m; \
237
})
238
#define _float2fix_z_inline(f, e) ({ \
239
int32_t _m; \
240
float _f = (f); \
241
pico_default_asm( \
242
"vcvt.s32.f32 %0, %0, %2\n" \
243
"vmov %1, %0\n" \
244
: "+t" (_f), "=r" (_m) \
245
: "i" (e) \
246
); \
247
_m; \
248
})
249
#define _float2fix_inline(f, e) ({ \
250
union { float _f; int32_t _i; } _u; \
251
_u._f = (f); \
252
uint rc, tmp; \
253
pico_default_asm( \
254
"vcvt.s32.f32 %0, %0, %4\n" \
255
"vmov %2, %0\n" \
256
"lsls %1, #1\n" \
257
"bls 2f\n"
/* positive or zero or -zero are ok with the result we have */
\
258
"lsrs %3, %1, #24\n" \
259
"subs %3, #0x7f - %c4\n" \
260
"bcc 1f\n"
/* 0 < abs(f) < 1 ^ e, so need to round down */
\
261
/* mask off all but fractional bits */
\
262
"lsls %1, %3\n" \
263
"lsls %1, #8\n" \
264
"beq 2f\n"
/* integers can round towards zero */
\
265
"1:\n" \
266
/* need to subtract 1 from the result to round towards -infinity... */
\
267
/* this will never cause an overflow, because to get here we must have had a non integer/infinite value which */
\
268
/* therefore cannot have been equal to INT64_MIN when rounded towards zero */
\
269
"subs %2, #1\n" \
270
"2:\n" \
271
: "+t" (_u._f), "+r" (_u._i), "=r" (rc), "=r" (tmp) \
272
: "i" (e) \
273
); \
274
rc; \
275
})
276
#define _float2ufix_inline(f, e) _float2ufix_z_inline((f), (e))
277
#endif
278
279
#if LIB_PICO_FLOAT_PICO_VFP
280
// may as well provide inline macros for VFP
281
#define int2float(i) ((float)(int32_t)(i))
282
#define uint2float(i) ((float)(uint32_t)(i))
283
#define float2int_z(f) ((int32_t)(f))
284
#define float2uint_z(f) ((uint32_t)(f))
285
#endif
286
287
#endif
288
289
float
exp10f(
float
x);
290
void
sincosf(
float
x,
float
*sinx,
float
*cosx);
291
float
powintf(
float
x,
int
y);
292
293
#if !PICO_RP2040 || PICO_COMBINED_DOCS
294
float
fdiv_fast(
float
n,
float
d);
295
float
sqrtf_fast(
float
f);
296
#endif
297
298
#endif
299
300
#if defined(__riscv) || LIB_PICO_FLOAT_COMPILER
301
// when using the compiler or RISC-V, we provide as many functions as we trivially can - these will be efficient
302
// when using hard-float on Arm
303
static
inline
float
int2float(int32_t i) {
return
(
float
)i; }
304
static
inline
float
uint2float(uint32_t i) {
return
(
float
)i; }
305
static
inline
float
int642float(int64_t i) {
return
(
float
)i; }
306
static
inline
float
uint642float(uint64_t i) {
return
(
float
)i; }
307
308
static
inline
int32_t float2int_z(
float
f) {
return
(int32_t)f; }
309
static
inline
int64_t float2int64_z(
float
f) {
return
(int64_t)f; }
310
static
inline
int32_t float2uint_z(
float
f) {
return
(uint32_t)f; }
311
static
inline
int64_t float2uint64_z(
float
f) {
return
(uint64_t)f; }
312
#endif
313
314
#ifdef __cplusplus
315
}
316
#endif
317
318
#endif
float.h
pico.h