1#include "pico/asm_helper.S" 2#include "hardware/regs/addressmap.h" 3#include "hardware/regs/sio.h" 4 5.syntax unified 6.cpu cortex-m0plus 7.thumb 8 9// tag::hw_div_s32[] 10 11.macro __divider_delay 12 // delay 8 cycles 13 b 1f 141: b 1f 151: b 1f 161: b 1f 171: 18.endm 19 20.align 2 21 22regular_func_with_section hw_divider_divmod_s32 23 ldr r3, =(SIO_BASE) 24 str r0, [r3, #SIO_DIV_SDIVIDEND_OFFSET] 25 str r1, [r3, #SIO_DIV_SDIVISOR_OFFSET] 26 __divider_delay 27 // return 64 bit value so we can efficiently return both (note quotient must be read last) 28 ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] 29 ldr r0, [r3, #SIO_DIV_QUOTIENT_OFFSET] 30 bx lr 31// end::hw_div_s32[] 32 33.align 2 34 35// tag::hw_div_u32[] 36regular_func_with_section hw_divider_divmod_u32 37 ldr r3, =(SIO_BASE) 38 str r0, [r3, #SIO_DIV_UDIVIDEND_OFFSET] 39 str r1, [r3, #SIO_DIV_UDIVISOR_OFFSET] 40 __divider_delay 41 // return 64 bit value so we can efficiently return both (note quotient must be read last) 42 ldr r1, [r3, #SIO_DIV_REMAINDER_OFFSET] 43 ldr r0, [r3, #SIO_DIV_QUOTIENT_OFFSET] 44 bx lr 45// end::hw_div_u32[] 46 47#if SIO_DIV_CSR_READY_LSB == 0 48.equ SIO_DIV_CSR_READY_SHIFT_FOR_CARRY, 1 49#else 50#error need to change SHIFT above 51#endif 52 53regular_func_with_section hw_divider_save_state 54 push {r4, r5, lr} 55 ldr r5, =SIO_BASE 56 ldr r4, [r5, #SIO_DIV_CSR_OFFSET] 57 # wait for results as we can't save signed-ness of operation 581: 59 lsrs r4, #SIO_DIV_CSR_READY_SHIFT_FOR_CARRY 60 bcc 1b 61 ldr r1, [r5, #SIO_DIV_UDIVIDEND_OFFSET] 62 ldr r2, [r5, #SIO_DIV_UDIVISOR_OFFSET] 63 ldr r3, [r5, #SIO_DIV_REMAINDER_OFFSET] 64 ldr r4, [r5, #SIO_DIV_QUOTIENT_OFFSET] 65 stmia r0!, {r1-r4} 66 pop {r4, r5, pc} 67 68regular_func_with_section hw_divider_restore_state 69 push {r4, r5, lr} 70 ldr r5, =SIO_BASE 71 ldmia r0!, {r1-r4} 72 str r1, [r5, #SIO_DIV_UDIVIDEND_OFFSET] 73 str r2, [r5, #SIO_DIV_UDIVISOR_OFFSET] 74 str r3, [r5, #SIO_DIV_REMAINDER_OFFSET] 75 str r4, [r5, #SIO_DIV_QUOTIENT_OFFSET] 76 pop {r4, r5, pc} 77