Skip to content

Commit c1effb1

Browse files
author
Jamie Smith
authored
Enable RPi Pico's optimized ROM floating point routines (#202)
* Enable RPi Pico's optimized ROM floating point routines * Add license header
1 parent 79c56f3 commit c1effb1

File tree

14 files changed

+2519
-457
lines changed

14 files changed

+2519
-457
lines changed

targets/TARGET_RASPBERRYPI/CMakeLists.txt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,83 @@ file(GENERATE
3030
CONTENT "${header_content}"
3131
)
3232

33+
# add a link option to wrap the given function name; i.e. -Wl:wrap=FUNCNAME for gcc
34+
function(pico_wrap_function TARGET FUNCNAME)
35+
target_link_options(${TARGET} INTERFACE "LINKER:--wrap=${FUNCNAME}")
36+
endfunction()
37+
38+
# Following is copied from src/rp2_common/pico_float/CMakeLists.txt
39+
function(wrap_float_functions TARGET)
40+
pico_wrap_function(${TARGET} __aeabi_fadd)
41+
pico_wrap_function(${TARGET} __aeabi_fdiv)
42+
pico_wrap_function(${TARGET} __aeabi_fmul)
43+
pico_wrap_function(${TARGET} __aeabi_frsub)
44+
pico_wrap_function(${TARGET} __aeabi_fsub)
45+
pico_wrap_function(${TARGET} __aeabi_cfcmpeq)
46+
pico_wrap_function(${TARGET} __aeabi_cfrcmple)
47+
pico_wrap_function(${TARGET} __aeabi_cfcmple)
48+
pico_wrap_function(${TARGET} __aeabi_fcmpeq)
49+
pico_wrap_function(${TARGET} __aeabi_fcmplt)
50+
pico_wrap_function(${TARGET} __aeabi_fcmple)
51+
pico_wrap_function(${TARGET} __aeabi_fcmpge)
52+
pico_wrap_function(${TARGET} __aeabi_fcmpgt)
53+
pico_wrap_function(${TARGET} __aeabi_fcmpun)
54+
pico_wrap_function(${TARGET} __aeabi_i2f)
55+
pico_wrap_function(${TARGET} __aeabi_l2f)
56+
pico_wrap_function(${TARGET} __aeabi_ui2f)
57+
pico_wrap_function(${TARGET} __aeabi_ul2f)
58+
pico_wrap_function(${TARGET} __aeabi_f2iz)
59+
pico_wrap_function(${TARGET} __aeabi_f2lz)
60+
pico_wrap_function(${TARGET} __aeabi_f2uiz)
61+
pico_wrap_function(${TARGET} __aeabi_f2ulz)
62+
pico_wrap_function(${TARGET} __aeabi_f2d)
63+
pico_wrap_function(${TARGET} sqrtf)
64+
pico_wrap_function(${TARGET} cosf)
65+
pico_wrap_function(${TARGET} sinf)
66+
pico_wrap_function(${TARGET} tanf)
67+
pico_wrap_function(${TARGET} atan2f)
68+
pico_wrap_function(${TARGET} expf)
69+
pico_wrap_function(${TARGET} logf)
70+
71+
pico_wrap_function(${TARGET} ldexpf)
72+
pico_wrap_function(${TARGET} copysignf)
73+
pico_wrap_function(${TARGET} truncf)
74+
pico_wrap_function(${TARGET} floorf)
75+
pico_wrap_function(${TARGET} ceilf)
76+
pico_wrap_function(${TARGET} roundf)
77+
pico_wrap_function(${TARGET} sincosf) # gnu
78+
pico_wrap_function(${TARGET} asinf)
79+
pico_wrap_function(${TARGET} acosf)
80+
pico_wrap_function(${TARGET} atanf)
81+
pico_wrap_function(${TARGET} sinhf)
82+
pico_wrap_function(${TARGET} coshf)
83+
pico_wrap_function(${TARGET} tanhf)
84+
pico_wrap_function(${TARGET} asinhf)
85+
pico_wrap_function(${TARGET} acoshf)
86+
pico_wrap_function(${TARGET} atanhf)
87+
pico_wrap_function(${TARGET} exp2f)
88+
pico_wrap_function(${TARGET} log2f)
89+
pico_wrap_function(${TARGET} exp10f)
90+
pico_wrap_function(${TARGET} log10f)
91+
pico_wrap_function(${TARGET} powf)
92+
pico_wrap_function(${TARGET} powintf) #gnu
93+
pico_wrap_function(${TARGET} hypotf)
94+
pico_wrap_function(${TARGET} cbrtf)
95+
pico_wrap_function(${TARGET} fmodf)
96+
pico_wrap_function(${TARGET} dremf)
97+
pico_wrap_function(${TARGET} remainderf)
98+
pico_wrap_function(${TARGET} remquof)
99+
pico_wrap_function(${TARGET} expm1f)
100+
pico_wrap_function(${TARGET} log1pf)
101+
pico_wrap_function(${TARGET} fmaf)
102+
endfunction()
103+
33104
# Now, add includes and headers from the Pico SDK
34105
target_include_directories(mbed-raspberrypi
35106
INTERFACE
36107
.
37108
pico-sdk/src/rp2_common/hardware_adc/include
109+
pico-sdk/src/rp2_common/hardware_divider/include
38110
pico-sdk/src/rp2_common/hardware_gpio/include
39111
pico-sdk/src/rp2_common/hardware_resets/include
40112
pico-sdk/src/rp2_common/hardware_pwm/include
@@ -54,6 +126,7 @@ target_include_directories(mbed-raspberrypi
54126
pico-sdk/src/rp2_common/pico_platform/include
55127
pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/
56128
pico-sdk/src/rp2_common/pico_bootrom/include
129+
pico-sdk/src/rp2_common/pico_float/include
57130
pico-sdk/src/rp2_common/hardware_claim/include
58131
pico-sdk/src/common/pico_sync/include
59132
pico-sdk/src/common/pico_time/include
@@ -89,6 +162,11 @@ target_sources(mbed-raspberrypi
89162
pico-sdk/src/common/pico_time/time.c
90163
pico-sdk/src/common/pico_sync/lock_core.c
91164
pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RaspberryPi/RP2040/Source/system_RP2040.c
165+
pico-sdk/src/rp2_common/pico_float/float_aeabi.S
166+
pico-sdk/src/rp2_common/pico_float/float_init_rom.c
167+
pico-sdk/src/rp2_common/pico_float/float_math.c
168+
pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S
169+
pico-sdk/src/rp2_common/hardware_divider/divider.S
92170
)
93171

94172
target_compile_definitions(mbed-raspberrypi
@@ -110,4 +188,7 @@ target_sources(mbed-rp2040
110188
pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
111189
)
112190

191+
# Enable usage of the RPi Pico optimized floating point routines
192+
wrap_float_functions(mbed-rp2040)
193+
113194
add_subdirectory(TARGET_RP2040 EXCLUDE_FROM_ALL)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "pico/asm_helper.S"
2+
#include "hardware/regs/addressmap.h"
3+
#include "hardware/regs/sio.h"
4+
5+
pico_default_asm_setup
6+
7+
// tag::hw_div_s32[]
8+
regular_func_with_section hw_divider_divmod_s32
9+
ldr r3, =(SIO_BASE)
10+
str r0, [r3, #SIO_DIV_SDIVIDEND_OFFSET]
11+
str r1, [r3, #SIO_DIV_SDIVISOR_OFFSET]
12+
b hw_divider_divmod_return
13+
// end::hw_div_s32[]
14+
15+
// tag::hw_div_u32[]
16+
regular_func_with_section hw_divider_divmod_u32
17+
ldr r3, =(SIO_BASE)
18+
str r0, [r3, #SIO_DIV_UDIVIDEND_OFFSET]
19+
str r1, [r3, #SIO_DIV_UDIVISOR_OFFSET]
20+
b hw_divider_divmod_return
21+
// end::hw_div_u32[]
22+
23+
// Common delay and return section for s32 and u32
24+
.section .text.hw_divider_divmod_return
25+
hw_divider_divmod_return:
26+
// Branching here is 2 cycles, delay another 6
27+
b 1f
28+
1: b 1f
29+
1: b 1f
30+
1: // return 64 bit value so we can efficiently return both (note quotient must be read last)
31+
ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET]
32+
ldr r0, [r3, #SIO_DIV_QUOTIENT_OFFSET]
33+
bx lr
34+
35+
regular_func_with_section hw_divider_save_state
36+
ldr r3, =SIO_BASE
37+
ldr r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET]
38+
ldr r2, [r3, #SIO_DIV_UDIVISOR_OFFSET]
39+
stmia r0!, {r1-r2}
40+
// The 8 cycles needed to guarantee that the result is ready is ensured by the preceeding
41+
// code of 7 cycles together with any branch to it taking at least 2 cycles.
42+
ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET]
43+
ldr r2, [r3, #SIO_DIV_QUOTIENT_OFFSET]
44+
stmia r0!, {r1-r2}
45+
bx lr
46+
47+
regular_func_with_section hw_divider_restore_state
48+
ldr r3, =SIO_BASE
49+
ldmia r0!, {r1-r2}
50+
str r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET]
51+
str r2, [r3, #SIO_DIV_UDIVISOR_OFFSET]
52+
ldmia r0!, {r1-r2}
53+
str r1, [r3, #SIO_DIV_REMAINDER_OFFSET]
54+
str r2, [r3, #SIO_DIV_QUOTIENT_OFFSET]
55+
bx lr

0 commit comments

Comments
 (0)