blob: b9389c514a76a805a3779ef0b15caf8601368e17 [file] [log] [blame]
#include "pico/asm_helper.S"
#include "hardware/regs/addressmap.h"
#include "hardware/regs/sio.h"
.syntax unified
.cpu cortex-m0plus
.thumb
// tag::hw_div_s32[]
.macro __divider_delay
// delay 8 cycles
b 1f
1: b 1f
1: b 1f
1: b 1f
1:
.endm
.align 2
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]
__divider_delay
// 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
// end::hw_div_s32[]
.align 2
// 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]
__divider_delay
// 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
// end::hw_div_u32[]
#if SIO_DIV_CSR_READY_LSB == 0
.equ SIO_DIV_CSR_READY_SHIFT_FOR_CARRY, 1
#else
#error need to change SHIFT above
#endif
regular_func_with_section hw_divider_save_state
push {r4, r5, lr}
ldr r5, =SIO_BASE
ldr r4, [r5, #SIO_DIV_CSR_OFFSET]
# wait for results as we can't save signed-ness of operation
1:
lsrs r4, #SIO_DIV_CSR_READY_SHIFT_FOR_CARRY
bcc 1b
ldr r1, [r5, #SIO_DIV_UDIVIDEND_OFFSET]
ldr r2, [r5, #SIO_DIV_UDIVISOR_OFFSET]
ldr r3, [r5, #SIO_DIV_REMAINDER_OFFSET]
ldr r4, [r5, #SIO_DIV_QUOTIENT_OFFSET]
stmia r0!, {r1-r4}
pop {r4, r5, pc}
regular_func_with_section hw_divider_restore_state
push {r4, r5, lr}
ldr r5, =SIO_BASE
ldmia r0!, {r1-r4}
str r1, [r5, #SIO_DIV_UDIVIDEND_OFFSET]
str r2, [r5, #SIO_DIV_UDIVISOR_OFFSET]
str r3, [r5, #SIO_DIV_REMAINDER_OFFSET]
str r4, [r5, #SIO_DIV_QUOTIENT_OFFSET]
pop {r4, r5, pc}