1#include "pico/asm_helper.S" 2#include "hardware/regs/addressmap.h" 3#include "hardware/regs/sio.h" 4 5#if !PICO_RP2040 6#warning "Building hardware/divider.S on a platform with no SIO divider hardware" 7#endif 8 9pico_default_asm_setup 10 11// tag::hw_div_s32[] 12regular_func_with_section hw_divider_divmod_s32 13 ldr r3, =(SIO_BASE) 14 str r0, [r3, #SIO_DIV_SDIVIDEND_OFFSET] 15 str r1, [r3, #SIO_DIV_SDIVISOR_OFFSET] 16 b hw_divider_divmod_return 17// end::hw_div_s32[] 18 19// tag::hw_div_u32[] 20regular_func_with_section hw_divider_divmod_u32 21 ldr r3, =(SIO_BASE) 22 str r0, [r3, #SIO_DIV_UDIVIDEND_OFFSET] 23 str r1, [r3, #SIO_DIV_UDIVISOR_OFFSET] 24 b hw_divider_divmod_return 25// end::hw_div_u32[] 26 27// Common delay and return section for s32 and u32 28.section .text.hw_divider_divmod_return 29hw_divider_divmod_return: 30 // Branching here is 2 cycles, delay another 6 31 b 1f 321: b 1f 331: b 1f 341: // return 64 bit value so we can efficiently return both (note quotient must be read last) 35 ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] 36 ldr r0, [r3, #SIO_DIV_QUOTIENT_OFFSET] 37 bx lr 38 39regular_func_with_section hw_divider_save_state 40 ldr r3, =SIO_BASE 41 ldr r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET] 42 ldr r2, [r3, #SIO_DIV_UDIVISOR_OFFSET] 43 stmia r0!, {r1-r2} 44 // The 8 cycles needed to guarantee that the result is ready is ensured by the preceding 45 // code of 7 cycles together with any branch to it taking at least 2 cycles. 46 ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] 47 ldr r2, [r3, #SIO_DIV_QUOTIENT_OFFSET] 48 stmia r0!, {r1-r2} 49 bx lr 50 51regular_func_with_section hw_divider_restore_state 52 ldr r3, =SIO_BASE 53 ldmia r0!, {r1-r2} 54 str r1, [r3, #SIO_DIV_UDIVIDEND_OFFSET] 55 str r2, [r3, #SIO_DIV_UDIVISOR_OFFSET] 56 ldmia r0!, {r1-r2} 57 str r1, [r3, #SIO_DIV_REMAINDER_OFFSET] 58 str r2, [r3, #SIO_DIV_QUOTIENT_OFFSET] 59 bx lr 60