Initial Release
This commit is contained in:
5
src/common/pico_divider/CMakeLists.txt
Normal file
5
src/common/pico_divider/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
if (NOT TARGET pico_divider_headers)
|
||||
add_library(pico_divider_headers INTERFACE)
|
||||
target_include_directories(pico_divider_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
target_link_libraries(pico_divider_headers INTERFACE pico_base_headers)
|
||||
endif()
|
322
src/common/pico_divider/include/pico/divider.h
Normal file
322
src/common/pico_divider/include/pico/divider.h
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_DIVIDER_H_
|
||||
#define _PICO_DIVIDER_H_
|
||||
|
||||
#include "pico.h"
|
||||
#include "hardware/divider.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup pico_divider pico_divider
|
||||
* Optimized 32 and 64 bit division functions accelerated by the RP2040 hardware divider.
|
||||
* Additionally provides integration with the C `/` and `%` operators
|
||||
*/
|
||||
|
||||
/** \file pico/divider.h
|
||||
* \brief High level APIs including combined quotient and remainder functions for 32 and 64 bit accelerated by the hardware divider
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* These functions all call __aeabi_idiv0 or __aebi_ldiv0 on division by zero
|
||||
* passing the largest applicably signed value
|
||||
*
|
||||
* Functions with unsafe in their name do not save/restore divider state, so are unsafe to call from interrupts. Unsafe functions are slightly faster.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient
|
||||
*/
|
||||
int32_t div_s32s32(int32_t a, int32_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 32-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*/
|
||||
static inline int32_t divmod_s32s32_rem(int32_t a, int32_t b, int32_t *rem) {
|
||||
divmod_result_t r = hw_divider_divmod_s32(a, b);
|
||||
*rem = to_remainder_s32(r);
|
||||
return to_quotient_s32(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in low word/r0, remainder in high word/r1
|
||||
*/
|
||||
divmod_result_t divmod_s32s32(int32_t a, int32_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two unsigned 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*/
|
||||
uint32_t div_u32u32(uint32_t a, uint32_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two unsigned 32-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*/
|
||||
static inline uint32_t divmod_u32u32_rem(uint32_t a, uint32_t b, uint32_t *rem) {
|
||||
divmod_result_t r = hw_divider_divmod_u32(a, b);
|
||||
*rem = to_remainder_u32(r);
|
||||
return to_quotient_u32(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two unsigned 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in low word/r0, remainder in high word/r1
|
||||
*/
|
||||
divmod_result_t divmod_u32u32(uint32_t a, uint32_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*/
|
||||
int64_t div_s64s64(int64_t a, int64_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 64-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*/
|
||||
int64_t divmod_s64s64_rem(int64_t a, int64_t b, int64_t *rem);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
||||
*/
|
||||
int64_t divmod_s64s64(int64_t a, int64_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two unsigned 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*/
|
||||
uint64_t div_u64u64(uint64_t a, uint64_t b);
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two unsigned 64-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*/
|
||||
uint64_t divmod_u64u64_rem(uint64_t a, uint64_t b, uint64_t *rem);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
||||
*/
|
||||
uint64_t divmod_u64u64(uint64_t a, uint64_t b);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// these "unsafe" functions are slightly faster, but do not save the divider state,
|
||||
// so are not generally safe to be called from interrupts
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int32_t div_s32s32_unsafe(int32_t a, int32_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 32-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int32_t divmod_s32s32_rem_unsafe(int32_t a, int32_t b, int32_t *rem);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in low word/r0, remainder in high word/r1
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int64_t divmod_s32s32_unsafe(int32_t a, int32_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint32_t div_u32u32_unsafe(uint32_t a, uint32_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 32-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint32_t divmod_u32u32_rem_unsafe(uint32_t a, uint32_t b, uint32_t *rem);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in low word/r0, remainder in high word/r1
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint64_t divmod_u32u32_unsafe(uint32_t a, uint32_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int64_t div_s64s64_unsafe(int64_t a, int64_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 64-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int64_t divmod_s64s64_rem_unsafe(int64_t a, int64_t b, int64_t *rem);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
int64_t divmod_s64s64_unsafe(int64_t a, int64_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return Quotient
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint64_t div_u64u64_unsafe(uint64_t a, uint64_t b);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two unsigned 64-bit values, with remainder
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \param [out] rem The remainder of dividend/divisor
|
||||
* \return Quotient result of dividend/divisor
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint64_t divmod_u64u64_rem_unsafe(uint64_t a, uint64_t b, uint64_t *rem);
|
||||
|
||||
/**
|
||||
* \brief Unsafe integer divide of two signed 64-bit values
|
||||
* \ingroup pico_divider
|
||||
*
|
||||
* \param a Dividend
|
||||
* \param b Divisor
|
||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
||||
*
|
||||
* Do not use in interrupts
|
||||
*/
|
||||
uint64_t divmod_u64u64_unsafe(uint64_t a, uint64_t b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
Reference in New Issue
Block a user