Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/rp2_common/pico_double/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ if (NOT TARGET pico_double)
${CMAKE_CURRENT_LIST_DIR}/double_sci_m33.S
${CMAKE_CURRENT_LIST_DIR}/double_conv_m33.S
)

# PICO_CMAKE_CONFIG: PICO_DOUBLE_USE_UNSAFE_DCP, Use unsafe variant as the default implemention for all wrapper functions, default=0, type=bool, group=pico_double
if(PICO_DOUBLE_USE_UNSAFE_DCP)
target_compile_definitions(pico_double_pico INTERFACE PICO_DOUBLE_USE_UNSAFE_DCP=1)
endif()
endif()

target_link_libraries(pico_double_pico INTERFACE pico_bootrom pico_double_headers hardware_divider)
Expand Down
27 changes: 26 additions & 1 deletion src/rp2_common/pico_double/double_aeabi_dcp.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ double_section WRAPPER_FUNC_NAME(\func)

// ============== STATE SAVE AND RESTORE ===============

// PICO_CONFIG: PICO_DOUBLE_USE_UNSAFE_DCP, Use unsafe variant as the default implemention for all wrapper functions, default=0, type=bool, group=pico_double
#if 0
#define PICO_DOUBLE_USE_UNSAFE_DCP 0
#endif

.macro saving_func type func, opt_label1='-', opt_label2='-'
// Note we are usually 32-bit aligned already at this point, as most of the
// function bodies contain exactly two 16-bit instructions: bmi and bx lr.
Expand All @@ -47,10 +52,30 @@ regular_func \opt_label1
.ifnc \opt_label2,'-'
regular_func \opt_label2
.endif
// This is the actual entry point:
// Configurable entry point of wrapper functions.
.ifc \type,wrapper
regular_func \func\()_safe
#if !PICO_DOUBLE_USE_UNSAFE_DCP
\type\()_func \func
#endif
.else
\type\()_func \func
.endif
PCMP apsr_nzcv
bmi 1b
#if PICO_DOUBLE_USE_UNSAFE_DCP
.ifc \type,wrapper
\type\()_func \func
.endif
#endif
regular_func \func\()_unsafe
.ifnc \opt_label1,'-'
regular_func \opt_label1\()_unsafe
.endif
.ifnc \opt_label2,'-'
regular_func \opt_label2\()_unsafe
.endif
// This is the actual entry point:
1:
.endm

Expand Down
9 changes: 9 additions & 0 deletions src/rp2_common/pico_double/double_fma_dcp.S
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,18 @@ double_wrapper_section __dfma
@ r0:r1 m
@ r2:r3 n
@ [r13,#0] a
regular_func fma_safe
#if !PICO_DOUBLE_USE_UNSAFE_DCP
wrapper_func fma
#endif
mov r12,sp @ save the SP
PCMP apsr_nzcv @ test the engaged flag
bmi 1b
1:
#if PICO_DOUBLE_USE_UNSAFE_DCP
wrapper_func fma
#endif
regular_func fma_unsafe
push {r4-r8,r14}
ldrd r4,r5,[r12,#0] @ fetch a using original SP
ubfx r7,r1,#20,#11 @ r7=em
Expand Down Expand Up @@ -597,6 +604,8 @@ regular_func mla
mov r12,sp @ save the SP
PCMP apsr_nzcv @ test the engaged flag
bmi 1b
regular_func fma_fast_unsafe
regular_func mla_unsafe
1:
push {r4,r5,r14}
dcp_dmul_m r0,r1,r0,r1,r2,r3,r0,r1,r2,r3,r4,r5,r14
Expand Down
19 changes: 19 additions & 0 deletions src/rp2_common/pico_double/include/pico/double.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ uint32_t double2ufix(double f, int e);
int64_t double2fix64(double f, int e);
uint64_t double2ufix64(double f, int e);

#if PICO_RP2350
int32_t double2int_unsafe(double f);
uint32_t double2uint_unsafe(double f);
int32_t double2fix_unsafe(double f, int e);
uint32_t double2ufix_unsafe(double f, int e);
int32_t double2fix_z_unsafe(double f, int e);
double int2double_unsafe(int32_t i);
double uint2double_unsafe(uint32_t i);
int32_t double2int_z_unsafe(double f);
int32_t double2uint_z_unsafe(double f);
uint32_t double2ufix_z_unsafe(double f, int e);
#endif

#endif

double exp10(double x);
Expand All @@ -173,6 +186,12 @@ double ddiv_fast(double n, double d);
double sqrt_fast(double f);
double fma_fast(double x, double y, double z); // this is not fused
double mla(double x, double y, double z); // another name for fma_fast
#if !defined(__riscv) && LIB_PICO_DOUBLE_PICO
double ddiv_fast_unsafe(double n, double d);
double sqrt_fast_unsafe(double f);
double fma_fast_unsafe(double x, double y, double z);
double mla_unsafe(double x, double y, double z);
#endif
#endif

#endif
Expand Down
5 changes: 5 additions & 0 deletions src/rp2_common/pico_float/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@
${CMAKE_CURRENT_LIST_DIR}/float_sci_m33.S
)

# PICO_CMAKE_CONFIG: PICO_FLOAT_USE_UNSAFE_DCP, Use unsafe variant as the default implemention for all wrapper functions, default=0, type=bool, group=pico_float
if(PICO_FLOAT_USE_UNSAFE_DCP)
target_compile_definitions(pico_float_pico_dcp INTERFACE PICO_FLOAT_USE_UNSAFE_DCP=1)
endif()

# NOTE the main reason for using pico_float_pico_dcp is presumably that you
# don't want to use VFP at all, so turn off compiler support, otherwise, it will inline usages
target_compile_options(pico_float_pico_dcp INTERFACE -msoft-float)
Expand Down
28 changes: 27 additions & 1 deletion src/rp2_common/pico_float/float_aeabi_dcp.S
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,31 @@ regular_func \opt_label1
.ifnc \opt_label2,'-'
regular_func \opt_label2
.endif
// This is the actual entry point:
// For wrapper functions: export `<func>_safe`, `<func>_unsafe` and configurable `<func>`.
// For regular functions: export fixed `<func>` and `<func>_unsafe`.
.ifc \type,wrapper
regular_func \func\()_safe
#if !PICO_FLOAT_USE_UNSAFE_DCP
\type\()_func \func
#endif
.else
\type\()_func \func
.endif
PCMP apsr_nzcv
bmi 1b
#if PICO_FLOAT_USE_UNSAFE_DCP
.ifc \type,wrapper
\type\()_func \func
.endif
#endif
regular_func \func\()_unsafe
.ifnc \opt_label1,'-'
regular_func \opt_label1\()_unsafe
.endif
.ifnc \opt_label2,'-'
regular_func \opt_label2\()_unsafe
.endif
// This is the actual entry point:
1:
.endm

Expand Down Expand Up @@ -138,6 +159,11 @@ saving_func regular fclassify

// ============== CONVERSION FUNCTIONS ===============

// PICO_CONFIG: PICO_FLOAT_USE_UNSAFE_DCP, Use unsafe variant as the default implemention for all wrapper functions, default=0, type=bool, group=pico_float
#if 0
#define PICO_FLOAT_USE_UNSAFE_DCP 0
#endif

float_wrapper_section __aeabi_f2d
saving_func wrapper __aeabi_f2d float2double
dcp_float2double_m r0,r1,r0
Expand Down
18 changes: 18 additions & 0 deletions src/rp2_common/pico_float/include/pico/float.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,19 @@ uint32_t float2ufix(float f, int e);
int64_t float2fix64(float f, int e);
uint64_t float2ufix64(float f, int e);

#if LIB_PICO_FLOAT_PICO_DCP
float int2float_unsafe(int32_t i);
float uint2float_unsafe(uint32_t i);
int32_t float2int_z_unsafe(float f);
int32_t float2uint_z_unsafe(float f);
int32_t float2fix_z_unsafe(float f, int e);
int32_t float2int_unsafe(float f);
uint32_t float2uint_unsafe(float f);
int32_t float2fix_unsafe(float f, int e);
uint32_t float2ufix_unsafe(float f, int e);
uint32_t float2ufix_z_unsafe(float f, int e);
#endif

#if LIB_PICO_FLOAT_PICO_VFP
// a bit of a hack to inline VFP fixed point conversion when exponent is constant and in range 1-32
#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))
Expand Down Expand Up @@ -295,6 +308,11 @@ float powintf(float x, int y);
#if !PICO_RP2040 || PICO_COMBINED_DOCS
float fdiv_fast(float n, float d);
float sqrtf_fast(float f);

#if LIB_PICO_FLOAT_PICO_DCP
float fdiv_fast_unsafe(float n, float d);
float sqrtf_fast_unsafe(float f);
#endif
#endif

#endif
Expand Down
13 changes: 13 additions & 0 deletions test/pico_float_test/custom_double_funcs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ static inline double double2ufix_12(int32_t m) { return double2ufix(m, 12); }
#define uint642double(i) ({ uint64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint642 ## double(_i); })
#endif

#if 1 && PICO_DOUBLE_USE_UNSAFE_DCP && !defined(__riscv) && PICO_RP2350
#define int2double int2double_unsafe
#define uint2double uint2double_unsafe
#define double2fix double2fix_unsafe
#define double2ufix double2ufix_unsafe
#define double2fix_z double2fix_z_unsafe
#define double2ufix_z double2ufix_z_unsafe
#define double2int double2int_unsafe
#define double2int_z double2int_z_unsafe
#define double2uint double2uint_unsafe
#define double2uint_z double2uint_z_unsafe
#endif

int test() {
int rc = 0;
#if LIB_PICO_DOUBLE_PICO
Expand Down
13 changes: 13 additions & 0 deletions test/pico_float_test/custom_float_funcs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@
#define test_checki64(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %lld != %lld\n", msg, (int64_t)(x), (int64_t)(expected)); stop(); } })
#define test_checku64(x, expected, msg) ({ if ((uint64_t)(x) != (uint64_t)(expected)) { printf(" %s: %llu != %llu\n", msg, (uint64_t)(x), (uint64_t)(expected)); stop(); } })

#if PICO_FLOAT_USE_UNSAFE_DCP && PICO_RP2350 && !defined(__riscv)
#define int2float int2float_unsafe
#define uint2float uint2float_unsafe
#define float2int float2int_unsafe
#define float2int_z float2int_z_unsafe
#define float2uint float2uint_unsafe
#define float2uint_z float2uint_z_unsafe
#define float2fix float2fix_unsafe
#define float2fix_z float2fix_z_unsafe
#define float2ufix float2ufix_unsafe
#define float2ufix_z float2ufix_z_unsafe
#endif

#if !(LIB_PICO_FLOAT_COMPILER || defined(__riscv))
static inline float fix2float_8(int32_t m) { return fix2float(m, 8); }
static inline float fix2float_12(int32_t m) { return fix2float(m, 12); }
Expand Down
9 changes: 9 additions & 0 deletions test/pico_float_test/m33.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ extern ui64 sqrt_fast(ui64);
#define m33cf_dadd __aeabi_dadd
#define m33cf_dsub __aeabi_dsub
#define m33cf_dmul __aeabi_dmul

#if LIB_PICO_DOUBLE_PICO && PICO_DOUBLE_USE_UNSAFE_DCP
extern ui64 ddiv_fast_unsafe(ui64, ui64);
extern ui64 sqrt_fast_unsafe(ui64);
#define m33cf_ddiv_fast ddiv_fast_unsafe
#define m33cf_dsqrt_fast sqrt_fast_unsafe
#else
#define m33cf_ddiv_fast ddiv_fast
#define m33cf_dsqrt_fast sqrt_fast
#endif

static void checkf(ui32 r,ui32 t) {
static int n=0;
if(r!=t) {
Expand Down