#include "pico/asm_helper.S" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" #if !PICO_RP2040 #warning "Building hardware/divider.S on a platform with no SIO divider hardware" #endif pico_default_asm_setup // tag::hw_div_s32[] regular_func_with_section hw_divider_divmod_s32 ldr r3, =(SIO_BASE) str r0, [r3, #SIO_DIV_SDIVIDEND_OFFSET] str r1, [r3, #SIO_DIV_SDIVISOR_OFFSET] b hw_divider_divmod_return // end::hw_div_s32[] // tag::hw_div_u32[] regular_func_with_section hw_divider_divmod_u32 ldr r3, =(SIO_BASE) str r0, [r3, #SIO_DIV_UDIVIDEND_OFFSET] str r1, [r3, #SIO_DIV_UDIVISOR_OFFSET] b hw_divider_divmod_return // end::hw_div_u32[] // Common delay and return section for s32 and u32 .section .text.hw_divider_divmod_return hw_divider_divmod_return: // Branching here is 2 cycles, delay another 6 b 1f 1: b 1f 1: b 1f 1: // return 64 bit value so we can efficiently return both (note quotient must be read last) ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] ldr r0, [r3, #SIO_DIV_QUOTIENT_OFFSET] bx lr regular_func_with_section hw_divider_save_state ldr r3, =SIO_BASE ldr r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET] ldr r2, [r3, #SIO_DIV_UDIVISOR_OFFSET] stmia r0!, {r1-r2} // The 8 cycles needed to guarantee that the result is ready is ensured by the preceding // code of 7 cycles together with any branch to it taking at least 2 cycles. ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] ldr r2, [r3, #SIO_DIV_QUOTIENT_OFFSET] stmia r0!, {r1-r2} bx lr regular_func_with_section hw_divider_restore_state ldr r3, =SIO_BASE ldmia r0!, {r1-r2} str r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET] str r2, [r3, #SIO_DIV_UDIVISOR_OFFSET] ldmia r0!, {r1-r2} str r1, [r3, #SIO_DIV_REMAINDER_OFFSET] str r2, [r3, #SIO_DIV_QUOTIENT_OFFSET] bx lr