7#ifndef _HARDWARE_DIVIDER_H
8#define _HARDWARE_DIVIDER_H
43#include "hardware/structs/sio.h"
45#define PICO_EMULATE_DIVIDER 1
52typedef uint64_t divmod_result_t;
54#if PICO_EMULATE_DIVIDER
55extern divmod_result_t hw_divider_results[NUM_CORES];
57static inline int __sign_of(int32_t v) {
58 return v > 0 ? 1 : (v < 0 ? -1 : 0);
71#if !PICO_EMULATE_DIVIDER
75 if (!b)
return (((uint64_t)a)<<32u) | (uint32_t)(-__sign_of(a));
76 return (((uint64_t)(a%b))<<32u) | (uint32_t)(a/b);
89#if !PICO_EMULATE_DIVIDER
93 if (!b)
return (((uint64_t)a)<<32u) | (uint32_t)(-1);
94 return (((uint64_t)(a%b))<<32u) | (a/b);
108#if !PICO_EMULATE_DIVIDER
109 check_hw_layout(
sio_hw_t, div_sdividend, SIO_DIV_SDIVIDEND_OFFSET);
110 sio_hw->div_sdividend = (uint32_t)a;
111 sio_hw->div_sdivisor = (uint32_t)b;
127#if !PICO_EMULATE_DIVIDER
129 sio_hw_t, div_udividend, SIO_DIV_UDIVIDEND_OFFSET);
130 sio_hw->div_udividend = a;
131 sio_hw->div_udivisor = b;
143#if !PICO_EMULATE_DIVIDER
145 static_assert(SIO_DIV_CSR_READY_BITS == 1,
"");
150 pico_default_asm_volatile (
151 "hw_divider_result_loop_%=:"
152 "ldr %0, [%1, %2]\n\t"
153 "lsrs %0, %0, #1\n\t"
154 "bcc hw_divider_result_loop_%=\n\t"
156 :
"l" (sio_hw),
"I" (SIO_DIV_CSR_OFFSET)
170#if !PICO_EMULATE_DIVIDER
172 divmod_result_t rc = ((divmod_result_t) sio_hw->div_remainder) << 32u;
173 rc |= sio_hw->div_quotient;
209 return (int32_t)(uint32_t)r;
221 return (uint32_t)(r >> 32u);
233 return (int32_t)(r >> 32u);
245#if !PICO_EMULATE_DIVIDER
247 return sio_hw->div_quotient;
261#if !PICO_EMULATE_DIVIDER
263 return (int32_t)sio_hw->div_quotient;
277#if !PICO_EMULATE_DIVIDER
279 uint32_t rc = sio_hw->div_remainder;
280 sio_hw->div_quotient;
295#if !PICO_EMULATE_DIVIDER
297 int32_t rc = (int32_t)sio_hw->div_remainder;
298 sio_hw->div_quotient;
315#if !PICO_EMULATE_DIVIDER
318 return b ? (a / b) : (uint32_t)(-1);
332#if !PICO_EMULATE_DIVIDER
335 return b ? (a % b) : a;
349#if !PICO_EMULATE_DIVIDER
352 return b ? (a / b) : -1;
366#if !PICO_EMULATE_DIVIDER
369 return b ? (a % b) : a;
377#if !PICO_EMULATE_DIVIDER
378 pico_default_asm_volatile(
401#if !PICO_EMULATE_DIVIDER
404 return sio_hw->div_quotient;
420#if !PICO_EMULATE_DIVIDER
423 uint32_t rc = sio_hw->div_remainder;
424 sio_hw->div_quotient;
441#if !PICO_EMULATE_DIVIDER
444 return (int32_t)sio_hw->div_quotient;
460#if !PICO_EMULATE_DIVIDER
463 int32_t rc = (int32_t)sio_hw->div_remainder;
464 sio_hw->div_quotient;
471#if !PICO_EMULATE_DIVIDER
476typedef uint64_t hw_divider_state_t;
488#if !PICO_EMULATE_DIVIDER
503#if !PICO_EMULATE_DIVIDER
static int32_t hw_divider_quotient_s32(int32_t a, int32_t b)
Do a signed HW divide, wait for result, return quotient.
Definition divider.h:348
static uint32_t to_quotient_u32(divmod_result_t r)
Efficient extraction of unsigned quotient from 32p32 fixed point.
Definition divider.h:198
static int32_t hw_divider_s32_quotient_inlined(int32_t a, int32_t b)
Do a hardware signed HW divide, wait for result, return quotient.
Definition divider.h:440
static uint32_t hw_divider_u32_remainder_wait(void)
Return result of last asynchronous HW divide, unsigned remainder only.
Definition divider.h:276
static void hw_divider_divmod_u32_start(uint32_t a, uint32_t b)
Start an unsigned asynchronous divide.
Definition divider.h:126
static void hw_divider_divmod_s32_start(int32_t a, int32_t b)
Start a signed asynchronous divide.
Definition divider.h:107
static int32_t hw_divider_remainder_s32(int32_t a, int32_t b)
Do a signed HW divide, wait for result, return remainder.
Definition divider.h:365
static uint32_t hw_divider_u32_remainder_inlined(uint32_t a, uint32_t b)
Do a hardware unsigned HW divide, wait for result, return remainder.
Definition divider.h:419
static uint32_t hw_divider_u32_quotient_wait(void)
Return result of last asynchronous HW divide, unsigned quotient only.
Definition divider.h:244
static divmod_result_t hw_divider_result_nowait(void)
Return result of HW divide, nowait.
Definition divider.h:169
static int32_t to_quotient_s32(divmod_result_t r)
Efficient extraction of signed quotient from 32p32 fixed point.
Definition divider.h:208
static int32_t to_remainder_s32(divmod_result_t r)
Efficient extraction of signed remainder from 32p32 fixed point.
Definition divider.h:232
static divmod_result_t hw_divider_divmod_s32(int32_t a, int32_t b)
Do a signed HW divide and wait for result.
Definition divider.h:74
static void hw_divider_wait_ready(void)
Wait for a divide to complete.
Definition divider.h:142
static int32_t hw_divider_s32_remainder_inlined(int32_t a, int32_t b)
Do a hardware signed HW divide, wait for result, return remainder.
Definition divider.h:459
static uint32_t hw_divider_u32_quotient(uint32_t a, uint32_t b)
Do an unsigned HW divide, wait for result, return quotient.
Definition divider.h:314
static void hw_divider_restore_state(hw_divider_state_t *src)
Load a saved hardware divider state into the current core's hardware divider.
Definition divider.h:506
static uint32_t hw_divider_u32_remainder(uint32_t a, uint32_t b)
Do an unsigned HW divide, wait for result, return remainder.
Definition divider.h:331
static int32_t hw_divider_s32_quotient_wait(void)
Return result of last asynchronous HW divide, signed quotient only.
Definition divider.h:260
static void hw_divider_save_state(hw_divider_state_t *dest)
Save the calling cores hardware divider state.
Definition divider.h:491
static divmod_result_t hw_divider_result_wait(void)
Return result of last asynchronous HW divide.
Definition divider.h:187
static divmod_result_t hw_divider_divmod_u32(uint32_t a, uint32_t b)
Do an unsigned HW divide and wait for result.
Definition divider.h:92
static void hw_divider_pause(void)
Pause for exact amount of time needed for a asynchronous divide to complete.
Definition divider.h:376
static uint32_t hw_divider_u32_quotient_inlined(uint32_t a, uint32_t b)
Do a hardware unsigned HW divide, wait for result, return quotient.
Definition divider.h:400
static int32_t hw_divider_s32_remainder_wait(void)
Return result of last asynchronous HW divide, signed remainder only.
Definition divider.h:294
static uint32_t to_remainder_u32(divmod_result_t r)
Efficient extraction of unsigned remainder from 32p32 fixed point.
Definition divider.h:220