Fixup divider save_restore for floating point too; improve tests (#405)
- The divider state needs to be saved for __aeabi_ddiv, __aeabi_fdiv, __aeabi_dtan and __aeabi_ftan or they won't work in interrupts *(probably not used much youd hope), or on an RTOS context switch - Refactored code out for the integer and floating point cases - Improved the floating point 'tests' in passing to check more return values against GCC implementations - Added floating point usage to the IRQ nesting test case
This commit is contained in:
@ -6,6 +6,7 @@
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "pico/bootrom/sf_table.h"
|
||||
#include "hardware/divider_helper.S"
|
||||
|
||||
__pre_init __aeabi_float_init, 00020
|
||||
|
||||
@ -104,16 +105,16 @@ __check_nan_f2:
|
||||
.endm
|
||||
|
||||
|
||||
# note generally each function is in a separate section unless there is fall thru or branching between them
|
||||
# note fadd, fsub, fmul, fdiv are so tiny and just defer to rom so are lumped together so they can share constant pool
|
||||
// note generally each function is in a separate section unless there is fall thru or branching between them
|
||||
// note fadd, fsub, fmul, fdiv are so tiny and just defer to rom so are lumped together so they can share constant pool
|
||||
|
||||
# note functions are word aligned except where they are an odd number of linear instructions
|
||||
// note functions are word aligned except where they are an odd number of linear instructions
|
||||
|
||||
// float FUNC_NAME(__aeabi_fadd)(float, float) single-precision addition
|
||||
float_wrapper_section __aeabi_farithmetic
|
||||
// float FUNC_NAME(__aeabi_frsub)(float x, float y) single-precision reverse subtraction, y - x
|
||||
|
||||
# frsub first because it is the only one that needs alignment
|
||||
// frsub first because it is the only one that needs alignment
|
||||
.align 2
|
||||
wrapper_func __aeabi_frsub
|
||||
eors r0, r1
|
||||
@ -146,7 +147,30 @@ wrapper_func_f2 __aeabi_fdiv
|
||||
b fdiv_fsub_nan_helper
|
||||
1:
|
||||
#endif
|
||||
#if !PICO_DIVIDER_DISABLE_INTERRUPTS
|
||||
// to support IRQ usage (or context switch) we must save/restore divider state around call if state is dirty
|
||||
ldr r2, =(SIO_BASE)
|
||||
ldr r3, [r2, #SIO_DIV_CSR_OFFSET]
|
||||
lsrs r3, #SIO_DIV_CSR_DIRTY_SHIFT_FOR_CARRY
|
||||
bcs fdiv_save_state
|
||||
#else
|
||||
// to avoid worrying about IRQs (or context switches), simply disable interrupts around call
|
||||
push {r4, lr}
|
||||
mrs r4, PRIMASK
|
||||
cpsid i
|
||||
bl fdiv_shim_call
|
||||
msr PRIMASK, r4
|
||||
pop {r4, pc}
|
||||
#endif
|
||||
fdiv_shim_call:
|
||||
table_tail_call SF_TABLE_FDIV
|
||||
#if !PICO_DIVIDER_DISABLE_INTERRUPTS
|
||||
fdiv_save_state:
|
||||
save_div_state_and_lr
|
||||
bl fdiv_shim_call
|
||||
ldr r2, =(SIO_BASE)
|
||||
restore_div_state_and_return
|
||||
#endif
|
||||
|
||||
fdiv_fsub_nan_helper:
|
||||
#if PICO_FLOAT_PROPAGATE_NANS
|
||||
@ -689,10 +713,33 @@ wrapper_func tanf
|
||||
lsls r1, r0, #1
|
||||
lsrs r1, #24
|
||||
cmp r1, #127 + 7
|
||||
bge 1f
|
||||
2:
|
||||
bge ftan_out_of_range
|
||||
ftan_in_range:
|
||||
#if !PICO_DIVIDER_DISABLE_INTERRUPTS
|
||||
// to support IRQ usage (or context switch) we must save/restore divider state around call if state is dirty
|
||||
ldr r2, =(SIO_BASE)
|
||||
ldr r3, [r2, #SIO_DIV_CSR_OFFSET]
|
||||
lsrs r3, #SIO_DIV_CSR_DIRTY_SHIFT_FOR_CARRY
|
||||
bcs ftan_save_state
|
||||
#else
|
||||
// to avoid worrying about IRQs (or context switches), simply disable interrupts around call
|
||||
push {r4, lr}
|
||||
mrs r4, PRIMASK
|
||||
cpsid i
|
||||
bl ftan_shim_call
|
||||
msr PRIMASK, r4
|
||||
pop {r4, pc}
|
||||
#endif
|
||||
ftan_shim_call:
|
||||
table_tail_call SF_TABLE_FTAN
|
||||
1:
|
||||
#if !PICO_DIVIDER_DISABLE_INTERRUPTS
|
||||
ftan_save_state:
|
||||
save_div_state_and_lr
|
||||
bl ftan_shim_call
|
||||
ldr r2, =(SIO_BASE)
|
||||
restore_div_state_and_return
|
||||
#endif
|
||||
ftan_out_of_range:
|
||||
#if PICO_FLOAT_PROPAGATE_NANS
|
||||
// also check for infinites
|
||||
cmp r1, #255
|
||||
@ -709,7 +756,7 @@ wrapper_func tanf
|
||||
bl remainderf
|
||||
pop {r1}
|
||||
mov lr, r1
|
||||
b 2b
|
||||
b ftan_in_range
|
||||
|
||||
float_wrapper_section atan2f
|
||||
wrapper_func_f2 atan2f
|
||||
|
Reference in New Issue
Block a user