#include #include #include "pico/stdlib.h" #include "pico/float.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 float f_a[] = {1.3f, -200.3f, 1.6e15f, 1e-2f}; static float f_b[] = {-121.3f, 50.3f, 27.9f, 1.7e23f}; static float f_c[] = {20.3f, -50.3f, -3.9e-3f, -4.1e7f}; static float f_m1to1[] = {-0.5f, .9999f, 0.1f, -0.999999f}; static int32_t i_pow[] = {3,6,27,-10}; static float f_positive[] = {0.0f, 3.7f, 1245325.f, 1e27f}; static float f_1plus[] = {1.0f, 3.7f, 1245325.f, 1e27f}; static float f_smaller[] = {-1000.3f, 200.3f, 1.6e15f}; static float f_bigger[] = {-121.3f, 5000.3f, 1.6e16f}; 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(f_a) == count_of(f_b), ""); static_assert(count_of(f_a) == count_of(f_c), ""); static_assert(count_of(f_a) == count_of(i_pow), ""); static_assert(count_of(f_a) == count_of(f_positive), ""); static_assert(count_of(f_smaller) == count_of(f_bigger), ""); static float time_unary_func(int (*timer)(float), float *f, uint count) { float total = 0.f; for (uint i=0;i