YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
float_aeabi.S
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "asm_helper.S"
8#include "sf_table.h"
9#include "divider_helper.S"
10
11__pre_init __aeabi_float_init, 00020
12
13.syntax unified
14.cpu cortex-m0plus
15.thumb
16
17.macro float_section name
18#if PICO_FLOAT_IN_RAM
19.section RAM_SECTION_NAME(\name), "ax"
20#else
21.section SECTION_NAME(\name), "ax"
22#endif
23.endm
24
25.macro float_wrapper_section func
26float_section WRAPPER_FUNC_NAME(\func)
27.endm
28
29.macro _float_wrapper_func x
30 wrapper_func \x
31.endm
32
33.macro wrapper_func_f1 x
34 _float_wrapper_func \x
35#if PICO_FLOAT_PROPAGATE_NANS
36 mov ip, lr
37 bl __check_nan_f1
38 mov lr, ip
39#endif
40.endm
41
42.macro wrapper_func_f2 x
43 _float_wrapper_func \x
44#if PICO_FLOAT_PROPAGATE_NANS
45 mov ip, lr
46 bl __check_nan_f2
47 mov lr, ip
48#endif
49.endm
50
51.section .text
52
53#if PICO_FLOAT_PROPAGATE_NANS
54.thumb_func
55__check_nan_f1:
56 movs r3, #1
57 lsls r3, #24
58 lsls r2, r0, #1
59 adds r2, r3
60 bhi 1f
61 bx lr
621:
63 bx ip
64
65.thumb_func
66__check_nan_f2:
67 movs r3, #1
68 lsls r3, #24
69 lsls r2, r0, #1
70 adds r2, r3
71 bhi 1f
72 lsls r2, r1, #1
73 adds r2, r3
74 bhi 2f
75 bx lr
762:
77 mov r0, r1
781:
79 bx ip
80#endif
81
82.macro table_tail_call SF_TABLE_OFFSET
83#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
84#ifndef NDEBUG
85 movs r3, #0
86 mov ip, r3
87#endif
88#endif
89 ldr r3, =sf_table
90 ldr r3, [r3, #\SF_TABLE_OFFSET]
91 bx r3
92.endm
93
94.macro shimmable_table_tail_call SF_TABLE_OFFSET shim
95 ldr r3, =sf_table
96 ldr r3, [r3, #\SF_TABLE_OFFSET]
97#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
98 mov ip, pc
99#endif
100 bx r3
101#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
102.byte \SF_TABLE_OFFSET, 0xdf
103.word \shim
104#endif
105.endm
106
107
108// note generally each function is in a separate section unless there is fall thru or branching between them
109// note fadd, fsub, fmul, fdiv are so tiny and just defer to rom so are lumped together so they can share constant pool
110
111// note functions are word aligned except where they are an odd number of linear instructions
112
113// float FUNC_NAME(__aeabi_fadd)(float, float) single-precision addition
114float_wrapper_section __aeabi_farithmetic
115// float FUNC_NAME(__aeabi_frsub)(float x, float y) single-precision reverse subtraction, y - x
116
117// frsub first because it is the only one that needs alignment
118.align 2
119wrapper_func __aeabi_frsub
120 eors r0, r1
121 eors r1, r0
122 eors r0, r1
123 // fall thru
124
125// float FUNC_NAME(__aeabi_fsub)(float x, float y) single-precision subtraction, x - y
126wrapper_func_f2 __aeabi_fsub
127#if PICO_FLOAT_PROPAGATE_NANS
128 // we want to return nan for inf-inf or -inf - -inf, but without too much upfront cost
129 mov r2, r0
130 eors r2, r1
131 bmi 1f // different signs
132 push {r0, r1, lr}
133 bl 1f
134 b fdiv_fsub_nan_helper
1351:
136#endif
137 table_tail_call SF_TABLE_FSUB
138
139wrapper_func_f2 __aeabi_fadd
140 table_tail_call SF_TABLE_FADD
141
142// float FUNC_NAME(__aeabi_fdiv)(float n, float d) single-precision division, n / d
143wrapper_func_f2 __aeabi_fdiv
144#if PICO_FLOAT_PROPAGATE_NANS
145 push {r0, r1, lr}
146 bl 1f
147 b fdiv_fsub_nan_helper
1481:
149#endif
150#if !PICO_DIVIDER_DISABLE_INTERRUPTS
151 // to support IRQ usage (or context switch) we must save/restore divider state around call if state is dirty
152 ldr r2, =(SIO_BASE)
153 ldr r3, [r2, #SIO_DIV_CSR_OFFSET]
154 lsrs r3, #SIO_DIV_CSR_DIRTY_SHIFT_FOR_CARRY
155 bcs fdiv_save_state
156#else
157 // to avoid worrying about IRQs (or context switches), simply disable interrupts around call
158 push {r4, lr}
159 mrs r4, PRIMASK
160 cpsid i
161 bl fdiv_shim_call
162 msr PRIMASK, r4
163 pop {r4, pc}
164#endif
165fdiv_shim_call:
166 table_tail_call SF_TABLE_FDIV
167#if !PICO_DIVIDER_DISABLE_INTERRUPTS
168fdiv_save_state:
169 save_div_state_and_lr
170 bl fdiv_shim_call
171 ldr r2, =(SIO_BASE)
172 restore_div_state_and_return
173#endif
174
175fdiv_fsub_nan_helper:
176#if PICO_FLOAT_PROPAGATE_NANS
177 pop {r1, r2}
178
179 // check for infinite op infinite (or rather check for infinite result with both
180 // operands being infinite)
181 lsls r3, r0, #1
182 asrs r3, r3, #24
183 adds r3, #1
184 beq 2f
185 pop {pc}
1862:
187 lsls r1, #1
188 asrs r1, r1, #24
189 lsls r2, #1
190 asrs r2, r2, #24
191 ands r1, r2
192 adds r1, #1
193 bne 3f
194 // infinite to nan
195 movs r1, #1
196 lsls r1, #22
197 orrs r0, r1
1983:
199 pop {pc}
200#endif
201
202// float FUNC_NAME(__aeabi_fmul)(float, float) single-precision multiplication
203wrapper_func_f2 __aeabi_fmul
204#if PICO_FLOAT_PROPAGATE_NANS
205 push {r0, r1, lr}
206 bl 1f
207 pop {r1, r2}
208
209 // check for multiplication of infinite by zero (or rather check for infinite result with either
210 // operand 0)
211 lsls r3, r0, #1
212 asrs r3, r3, #24
213 adds r3, #1
214 beq 2f
215 pop {pc}
2162:
217 ands r1, r2
218 bne 3f
219 // infinite to nan
220 movs r1, #1
221 lsls r1, #22
222 orrs r0, r1
2233:
224 pop {pc}
2251:
226#endif
227 table_tail_call SF_TABLE_FMUL
228
229// void FUNC_NAME(__aeabi_cfrcmple)(float, float) reversed 3-way (<, =, ?>) compare [1], result in PSR ZC flags
230float_wrapper_section __aeabi_cfcmple
231.align 2
232wrapper_func __aeabi_cfrcmple
233 push {r0-r2, lr}
234 eors r0, r1
235 eors r1, r0
236 eors r0, r1
237 b __aeabi_cfcmple_guts
238
239// NOTE these share an implementation as we have no excepting NaNs.
240// void FUNC_NAME(__aeabi_cfcmple)(float, float) 3-way (<, =, ?>) compare [1], result in PSR ZC flags
241// void FUNC_NAME(__aeabi_cfcmpeq)(float, float) non-excepting equality comparison [1], result in PSR ZC flags
242.align 2
243wrapper_func __aeabi_cfcmple
244wrapper_func __aeabi_cfcmpeq
245 push {r0-r2, lr}
246
247__aeabi_cfcmple_guts:
248 lsls r2,r0,#1
249 lsrs r2,#24
250 beq 1f
251 cmp r2,#0xff
252 bne 2f
253 lsls r2, r0, #9
254 bhi 3f
2551:
256 lsrs r0,#23 @ clear mantissa if denormal or infinite
257 lsls r0,#23
2582:
259 lsls r2,r1,#1
260 lsrs r2,#24
261 beq 1f
262 cmp r2,#0xff
263 bne 2f
264 lsls r2, r1, #9
265 bhi 3f
2661:
267 lsrs r1,#23 @ clear mantissa if denormal or infinite
268 lsls r1,#23
2692:
270 movs r2,#1 @ initialise result
271 eors r1,r0
272 bmi 2f @ opposite signs? then can proceed on basis of sign of x
273 eors r1,r0 @ restore y
274 bpl 1f
275 cmp r1,r0
276 pop {r0-r2, pc}
2771:
278 cmp r0,r1
279 pop {r0-r2, pc}
2802:
281 orrs r1, r0 @ handle 0/-0
282 adds r1, r1 @ note this always sets C
283 beq 3f
284 mvns r0, r0 @ carry inverse of r0 sign
285 adds r0, r0
2863:
287 pop {r0-r2, pc}
288
289
290// int FUNC_NAME(__aeabi_fcmpeq)(float, float) result (1, 0) denotes (=, ?<>) [2], use for C == and !=
291float_wrapper_section __aeabi_fcmpeq
292.align 2
293wrapper_func __aeabi_fcmpeq
294 push {lr}
295 bl __aeabi_cfcmpeq
296 beq 1f
297 movs r0, #0
298 pop {pc}
2991:
300 movs r0, #1
301 pop {pc}
302
303// int FUNC_NAME(__aeabi_fcmplt)(float, float) result (1, 0) denotes (<, ?>=) [2], use for C <
304float_wrapper_section __aeabi_fcmplt
305.align 2
306wrapper_func __aeabi_fcmplt
307 push {lr}
308 bl __aeabi_cfcmple
309 sbcs r0, r0
310 pop {pc}
311
312// int FUNC_NAME(__aeabi_fcmple)(float, float) result (1, 0) denotes (<=, ?>) [2], use for C <=
313float_wrapper_section __aeabi_fcmple
314.align 2
315wrapper_func __aeabi_fcmple
316 push {lr}
317 bl __aeabi_cfcmple
318 bls 1f
319 movs r0, #0
320 pop {pc}
3211:
322 movs r0, #1
323 pop {pc}
324
325// int FUNC_NAME(__aeabi_fcmpge)(float, float) result (1, 0) denotes (>=, ?<) [2], use for C >=
326float_wrapper_section __aeabi_fcmpge
327.align 2
328wrapper_func __aeabi_fcmpge
329 push {lr}
330 // because of NaNs it is better to reverse the args than the result
331 bl __aeabi_cfrcmple
332 bls 1f
333 movs r0, #0
334 pop {pc}
3351:
336 movs r0, #1
337 pop {pc}
338
339// int FUNC_NAME(__aeabi_fcmpgt)(float, float) result (1, 0) denotes (>, ?<=) [2], use for C >
340float_wrapper_section __aeabi_fcmpgt
341wrapper_func __aeabi_fcmpgt
342 push {lr}
343 // because of NaNs it is better to reverse the args than the result
344 bl __aeabi_cfrcmple
345 sbcs r0, r0
346 pop {pc}
347
348// int FUNC_NAME(__aeabi_fcmpun)(float, float) result (1, 0) denotes (?, <=>) [2], use for C99 isunordered()
349float_wrapper_section __aeabi_fcmpun
350wrapper_func __aeabi_fcmpun
351 movs r3, #1
352 lsls r3, #24
353 lsls r2, r0, #1
354 adds r2, r3
355 bhi 1f
356 lsls r2, r1, #1
357 adds r2, r3
358 bhi 1f
359 movs r0, #0
360 bx lr
3611:
362 movs r0, #1
363 bx lr
364
365
366// float FUNC_NAME(__aeabi_ui2f)(unsigned) unsigned to float (single precision) conversion
367float_wrapper_section __aeabi_ui2f
368wrapper_func __aeabi_ui2f
369 subs r1, r1
370 cmp r0, #0
371 bne __aeabi_i2f_main
372 mov r0, r1
373 bx lr
374
375float_wrapper_section __aeabi_i2f
376// float FUNC_NAME(__aeabi_i2f)(int) integer to float (single precision) conversion
377wrapper_func __aeabi_i2f
378 lsrs r1, r0, #31
379 lsls r1, #31
380 bpl 1f
381 negs r0, r0
3821:
383 cmp r0, #0
384 beq 7f
385__aeabi_i2f_main:
386
387 mov ip, lr
388 push {r0, r1}
389 ldr r3, =sf_clz_func
390 ldr r3, [r3]
391 blx r3
392 pop {r1, r2}
393 lsls r1, r0
394 subs r0, #158
395 negs r0, r0
396
397 adds r1,#0x80 @ rounding
398 bcs 5f @ tripped carry? then have leading 1 in C as required (and result is even so can ignore sticky bits)
399
400 lsls r3,r1,#24 @ check bottom 8 bits of r1
401 beq 6f @ in rounding-tie case?
402 lsls r1,#1 @ remove leading 1
4033:
404 lsrs r1,#9 @ align mantissa
405 lsls r0,#23 @ align exponent
406 orrs r0,r2 @ assemble exponent and mantissa
4074:
408 orrs r0,r1 @ apply sign
4091:
410 bx ip
4115:
412 adds r0,#1 @ correct exponent offset
413 b 3b
4146:
415 lsrs r1,#9 @ ensure even result
416 lsls r1,#10
417 b 3b
4187:
419 bx lr
420
421
422// int FUNC_NAME(__aeabi_f2iz)(float) float (single precision) to integer C-style conversion [3]
423float_wrapper_section __aeabi_f2iz
424wrapper_func __aeabi_f2iz
425regular_func float2int_z
426 lsls r1, r0, #1
427 lsrs r2, r1, #24
428 movs r3, #0x80
429 lsls r3, #24
430 cmp r2, #126
431 ble 1f
432 subs r2, #158
433 bge 2f
434 asrs r1, r0, #31
435 lsls r0, #9
436 lsrs r0, #1
437 orrs r0, r3
438 negs r2, r2
439 lsrs r0, r2
440 lsls r1, #1
441 adds r1, #1
442 muls r0, r1
443 bx lr
4441:
445 movs r0, #0
446 bx lr
4472:
448 lsrs r0, #31
449 adds r0, r3
450 subs r0, #1
451 bx lr
452
453 cmn r0, r0
454 bcc float2int
455 push {lr}
456 lsls r0, #1
457 lsrs r0, #1
458 movs r1, #0
459 bl __aeabi_f2uiz
460 cmp r0, #0
461 bmi 1f
462 negs r0, r0
463 pop {pc}
4641:
465 movs r0, #128
466 lsls r0, #24
467 pop {pc}
468
469float_section float2int
470regular_func float2int
471 shimmable_table_tail_call SF_TABLE_FLOAT2INT float2int_shim
472
473float_section float2fix
474regular_func float2fix
475 shimmable_table_tail_call SF_TABLE_FLOAT2FIX float2fix_shim
476
477float_section float2ufix
478regular_func float2ufix
479 table_tail_call SF_TABLE_FLOAT2UFIX
480
481// unsigned FUNC_NAME(__aeabi_f2uiz)(float) float (single precision) to unsigned C-style conversion [3]
482float_wrapper_section __aeabi_f2uiz
483wrapper_func __aeabi_f2uiz
484 table_tail_call SF_TABLE_FLOAT2UINT
485
486float_section fix2float
487regular_func fix2float
488 table_tail_call SF_TABLE_FIX2FLOAT
489
490float_section ufix2float
491regular_func ufix2float
492 table_tail_call SF_TABLE_UFIX2FLOAT
493
494float_section fix642float
495regular_func fix642float
496 shimmable_table_tail_call SF_TABLE_FIX642FLOAT fix642float_shim
497
498float_section ufix642float
499regular_func ufix642float
500 shimmable_table_tail_call SF_TABLE_UFIX642FLOAT ufix642float_shim
501
502// float FUNC_NAME(__aeabi_l2f)(long long) long long to float (single precision) conversion
503float_wrapper_section __aeabi_l2f
5041:
505 ldr r2, =__aeabi_i2f
506 bx r2
507wrapper_func __aeabi_l2f
508 asrs r2, r0, #31
509 cmp r1, r2
510 beq 1b
511 shimmable_table_tail_call SF_TABLE_INT642FLOAT int642float_shim
512
513// float FUNC_NAME(__aeabi_l2f)(long long) long long to float (single precision) conversion
514float_wrapper_section __aeabi_ul2f
5151:
516 ldr r2, =__aeabi_ui2f
517 bx r2
518wrapper_func __aeabi_ul2f
519 cmp r1, #0
520 beq 1b
521 shimmable_table_tail_call SF_TABLE_UINT642FLOAT uint642float_shim
522
523// long long FUNC_NAME(__aeabi_f2lz)(float) float (single precision) to long long C-style conversion [3]
524float_wrapper_section __aeabi_f2lz
525wrapper_func __aeabi_f2lz
526regular_func float2int64_z
527 cmn r0, r0
528 bcc float2int64
529 push {lr}
530 lsls r0, #1
531 lsrs r0, #1
532 movs r1, #0
533 bl float2ufix64
534 cmp r1, #0
535 bmi 1f
536 movs r2, #0
537 negs r0, r0
538 sbcs r2, r1
539 mov r1, r2
540 pop {pc}
5411:
542 movs r1, #128
543 lsls r1, #24
544 movs r0, #0
545 pop {pc}
546
547float_section float2int64
548regular_func float2int64
549 shimmable_table_tail_call SF_TABLE_FLOAT2INT64 float2int64_shim
550
551float_section float2fix64
552regular_func float2fix64
553 shimmable_table_tail_call SF_TABLE_FLOAT2FIX64 float2fix64_shim
554
555// unsigned long long FUNC_NAME(__aeabi_f2ulz)(float) float to unsigned long long C-style conversion [3]
556float_wrapper_section __aeabi_f2ulz
557wrapper_func __aeabi_f2ulz
558 shimmable_table_tail_call SF_TABLE_FLOAT2UINT64 float2uint64_shim
559
560float_section float2ufix64
561regular_func float2ufix64
562 shimmable_table_tail_call SF_TABLE_FLOAT2UFIX64 float2ufix64_shim
563
564float_wrapper_section __aeabi_f2d
5651:
566#if PICO_FLOAT_PROPAGATE_NANS
567 // copy sign bit and 25 NAN id bits into sign bit and significant ID bits, also setting the high id bit
568 asrs r1, r0, #3
569 movs r2, #0xf
570 lsls r2, #27
571 orrs r1, r2
572 lsls r0, #25
573 bx lr
574#endif
575wrapper_func __aeabi_f2d
576#if PICO_FLOAT_PROPAGATE_NANS
577 movs r3, #1
578 lsls r3, #24
579 lsls r2, r0, #1
580 adds r2, r3
581 bhi 1b
582#endif
583 shimmable_table_tail_call SF_TABLE_FLOAT2DOUBLE float2double_shim
584
585float_wrapper_section srqtf
586wrapper_func_f1 sqrtf
587#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
588 // check for negative
589 asrs r1, r0, #23
590 bmi 1f
591#endif
592 table_tail_call SF_TABLE_FSQRT
593#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
5941:
595 mvns r0, r1
596 cmp r0, #255
597 bne 2f
598 // -0 or -Denormal return -0 (0x80000000)
599 lsls r0, #31
600 bx lr
6012:
602 // return -Inf (0xff800000)
603 asrs r0, r1, #31
604 lsls r0, #23
605 bx lr
606#endif
607
608float_wrapper_section cosf
609// note we don't use _f1 since we do an infinity/nan check for outside of range
610wrapper_func cosf
611 // rom version only works for -128 < angle < 128
612 lsls r1, r0, #1
613 lsrs r1, #24
614 cmp r1, #127 + 7
615 bge 1f
6162:
617 table_tail_call SF_TABLE_FCOS
6181:
619#if PICO_FLOAT_PROPAGATE_NANS
620 // also check for infinites
621 cmp r1, #255
622 bne 3f
623 // infinite to nan
624 movs r1, #1
625 lsls r1, #22
626 orrs r0, r1
627 bx lr
6283:
629#endif
630 ldr r1, =0x40c90fdb // 2 * M_PI
631 push {lr}
632 bl remainderf
633 pop {r1}
634 mov lr, r1
635 b 2b
636
637float_wrapper_section sinf
638// note we don't use _f1 since we do an infinity/nan check for outside of range
639wrapper_func sinf
640 // rom version only works for -128 < angle < 128
641 lsls r1, r0, #1
642 lsrs r1, #24
643 cmp r1, #127 + 7
644 bge 1f
6452:
646 table_tail_call SF_TABLE_FSIN
6471:
648#if PICO_FLOAT_PROPAGATE_NANS
649 // also check for infinites
650 cmp r1, #255
651 bne 3f
652 // infinite to nan
653 movs r1, #1
654 lsls r1, #22
655 orrs r0, r1
656 bx lr
6573:
658#endif
659 ldr r1, =0x40c90fdb // 2 * M_PI
660 push {lr}
661 bl remainderf
662 pop {r1}
663 mov lr, r1
664 b 2b
665
666float_wrapper_section sincosf
667// note we don't use _f1 since we do an infinity/nan check for outside of range
668wrapper_func sincosf
669 push {r1, r2, lr}
670 // rom version only works for -128 < angle < 128
671 lsls r3, r0, #1
672 lsrs r3, #24
673 cmp r3, #127 + 7
674 bge 3f
6752:
676 ldr r3, =sf_table
677 ldr r3, [r3, #SF_TABLE_FSIN]
678 blx r3
679 pop {r2, r3}
680 str r0, [r2]
681 str r1, [r3]
682 pop {pc}
683#if PICO_FLOAT_PROPAGATE_NANS
684.align 2
685 pop {pc}
686#endif
6873:
688#if PICO_FLOAT_PROPAGATE_NANS
689 // also check for infinites
690 cmp r3, #255
691 bne 4f
692 // infinite to nan
693 movs r3, #1
694 lsls r3, #22
695 orrs r0, r3
696 str r0, [r1]
697 str r0, [r2]
698 add sp, #12
699 bx lr
7004:
701#endif
702 ldr r1, =0x40c90fdb // 2 * M_PI
703 push {lr}
704 bl remainderf
705 pop {r1}
706 mov lr, r1
707 b 2b
708
709float_wrapper_section tanf
710// note we don't use _f1 since we do an infinity/nan check for outside of range
711wrapper_func tanf
712 // rom version only works for -128 < angle < 128
713 lsls r1, r0, #1
714 lsrs r1, #24
715 cmp r1, #127 + 7
716 bge ftan_out_of_range
717ftan_in_range:
718#if !PICO_DIVIDER_DISABLE_INTERRUPTS
719 // to support IRQ usage (or context switch) we must save/restore divider state around call if state is dirty
720 ldr r2, =(SIO_BASE)
721 ldr r3, [r2, #SIO_DIV_CSR_OFFSET]
722 lsrs r3, #SIO_DIV_CSR_DIRTY_SHIFT_FOR_CARRY
723 bcs ftan_save_state
724#else
725 // to avoid worrying about IRQs (or context switches), simply disable interrupts around call
726 push {r4, lr}
727 mrs r4, PRIMASK
728 cpsid i
729 bl ftan_shim_call
730 msr PRIMASK, r4
731 pop {r4, pc}
732#endif
733ftan_shim_call:
734 table_tail_call SF_TABLE_FTAN
735#if !PICO_DIVIDER_DISABLE_INTERRUPTS
736ftan_save_state:
737 save_div_state_and_lr
738 bl ftan_shim_call
739 ldr r2, =(SIO_BASE)
740 restore_div_state_and_return
741#endif
742ftan_out_of_range:
743#if PICO_FLOAT_PROPAGATE_NANS
744 // also check for infinites
745 cmp r1, #255
746 bne 3f
747 // infinite to nan
748 movs r1, #1
749 lsls r1, #22
750 orrs r0, r1
751 bx lr
7523:
753#endif
754 ldr r1, =0x40c90fdb // 2 * M_PI
755 push {lr}
756 bl remainderf
757 pop {r1}
758 mov lr, r1
759 b ftan_in_range
760
761float_wrapper_section atan2f
762wrapper_func_f2 atan2f
763 shimmable_table_tail_call SF_TABLE_FATAN2 fatan2_shim
764
765float_wrapper_section expf
766wrapper_func_f1 expf
767 table_tail_call SF_TABLE_FEXP
768
769float_wrapper_section logf
770wrapper_func_f1 logf
771 table_tail_call SF_TABLE_FLN