#include #include #include "pico/stdlib.h" #include "pico/double.h" #include "pico/platform/cpu_regs.h" #if defined(LLVM_LIBC_COMMON_H) && !defined(__LLVM_LIBC__) #define __LLVM_LIBC__ 1 #endif static void init_systick() { systick_hw->csr = 0; systick_hw->rvr = ARM_CPU_PREFIXED(SYST_RVR_RELOAD_BITS); systick_hw->csr = ARM_CPU_PREFIXED(SYST_CSR_CLKSOURCE_BITS) | ARM_CPU_PREFIXED(SYST_CSR_ENABLE_BITS); } // Stop the compiler from constant-folding a hardware base pointer into the // pointers to individual registers, in cases where constant folding has // produced redundant 32-bit pointer literals that could have been load/store // offsets. (Note typeof(ptr+0) gives non-const, for +r constraint.) E.g. // uart_hw_t *uart0 = __get_opaque_ptr(uart0_hw); #define __get_opaque_ptr(ptr) ({ \ typeof((ptr)+0) __opaque_ptr = (ptr); \ asm ("" : "+r"(__opaque_ptr)); \ __opaque_ptr; \ }) static __force_inline uint32_t systick_value() { return systick_hw->cvr; } static __force_inline io_ro_32 *systick_value_ptr() { return __get_opaque_ptr(&systick_hw->cvr); } static int cycle_diff(uint32_t systick1, uint32_t systick2) { static_assert(ARM_CPU_PREFIXED(SYST_CVR_CURRENT_LSB) == 0, ""); uint32_t shift = 32 - ARM_CPU_PREFIXED(SYST_CVR_CURRENT_MSB); return (((int32_t)((systick1 << shift) - (systick2 << shift))) >> shift) - 1; // -1 since the second systick read costs one } #define timer_func_def(name) static __noinline int __not_in_flash_func(time_##name) static double d_a[] = {1.3, -200.3, 1.6e15, 1e-2}; static double d_b[] = {-121.3, 50.3, 27.9, 1.7e23}; static double d_c[] = {20.3, -50.3, -3.9e-3, -4.1e7}; static double d_m1to1[] = {-0.5, .9999, 0.1, -0.999999}; static int32_t i_pow[] = {3,6,27,-10}; static double d_positive[] = {0.0, 3.7, 1245325., 1e27}; static double d_1plus[] = {1.0, 3.7, 1245325., 1e27}; static double d_smaller[] = {-1000.3, 200.3, 1.6e15}; static double d_bigger[] = {-121.3, 5000.3, 1.6e16}; static int32_t i_32[] = { 0, 3, -200, INT32_MIN, INT32_MAX }; static int64_t i_64[] = { 0, 3, -200, 0x123456789abcll, -0x123456789abcll, INT64_MIN, INT64_MAX }; // bits for fixed point conversions static int32_t n_32[] = { 0, 3, -3, 16, -16 }; static_assert(count_of(d_a) == count_of(d_b), ""); static_assert(count_of(d_a) == count_of(d_c), ""); static_assert(count_of(d_a) == count_of(i_pow), ""); static_assert(count_of(d_a) == count_of(d_positive), ""); static_assert(count_of(d_smaller) == count_of(d_bigger), ""); static double time_unary_func(int (*timer)(double), double *d, uint count) { double total = 0.f; for (uint i=0;i