Merge branch 'develop' into iar/develop
diff --git a/CMakeLists.txt b/CMakeLists.txt index e79d04a..e3f57c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -9,6 +9,13 @@ project(pico_sdk C CXX ASM) + string(REGEX MATCH "Clang" PICO_C_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}") + string(REGEX MATCH "GNU" PICO_C_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}") + string(REGEX MATCH "IAR" PICO_C_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}") + pico_register_common_scope_var(PICO_C_COMPILER_IS_CLANG) + pico_register_common_scope_var(PICO_C_COMPILER_IS_GNU) + pico_register_common_scope_var(PICO_C_COMPILER_IS_IAR) + message("Build type is ${CMAKE_BUILD_TYPE}") if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") if (PICO_DEOPTIMIZED_DEBUG)
diff --git a/cmake/preload/toolchains/pico_arm_clang.cmake b/cmake/preload/toolchains/pico_arm_clang.cmake index d06d77e..2e600c8 100644 --- a/cmake/preload/toolchains/pico_arm_clang.cmake +++ b/cmake/preload/toolchains/pico_arm_clang.cmake
@@ -1,4 +1,5 @@ -# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED +# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED, however should work with LLVM Embedded Toolchain for ARM +# version 14.0.0 https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/tag/release-14.0.0 # todo there is probably a more "cmake" way of doing this going thru the standard path with our "PICO" platform # i.e. CMake<Lang>Information and whatnot include(${CMAKE_CURRENT_LIST_DIR}/find_compiler.cmake) @@ -37,9 +38,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -include_directories(/usr/include/newlib) - option(PICO_DEOPTIMIZED_DEBUG "Build debug builds with -O0" 0) -set(ARM_TOOLCHAIN_COMMON_FLAGS " --target=arm-none-eabi -mcpu=cortex-m0plus -mthumb") +# Oz is preferred for Clang (verses CMake default -Os) see also https://gitlab.kitware.com/cmake/cmake/-/issues/22458 +set(CMAKE_C_FLAGS_MINSIZEREL "-Oz -DNDEBUG") + +set(ARM_TOOLCHAIN_COMMON_FLAGS "--target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m --sysroot ${PICO_COMPILER_DIR}/../lib/clang-runtimes/armv6m_soft_nofp") include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake)
diff --git a/src/common/pico_binary_info/include/pico/binary_info/code.h b/src/common/pico_binary_info/include/pico/binary_info/code.h index 9478477..a1b13d9 100644 --- a/src/common/pico_binary_info/include/pico/binary_info/code.h +++ b/src/common/pico_binary_info/include/pico/binary_info/code.h
@@ -16,12 +16,12 @@ #include "pico/binary_info/structure.h" #if !PICO_NO_BINARY_INFO -#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *name = bi +#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *const name = bi #define __bi_lineno_var_name __CONCAT(__bi_, __LINE__) #define __bi_ptr_lineno_var_name __CONCAT(__bi_ptr, __LINE__) #define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__) #define __bi_mark_enclosure static const __unused int __bi_enclosure_check_lineno_var_name=0; -#if !defined(__GNUC__) || __cplusplus || __GNUC__ >= 8 +#if __cplusplus || __GNUC__ >= 8 #define __bi_enclosure_check(x) (x + __bi_enclosure_check_lineno_var_name) #else // skip the version check on older GCC non C++, as it doesn't compile.. this is only here to catch the @@ -39,10 +39,10 @@ * binary information declared this way will also be stripped * \ingroup pico_binary_info */ -#define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); +#define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); #define bi_decl_with_attr(_decl, _attr) __bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); -#define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); +#define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); #else #define __bi_decl(bi, name, attr) #define bi_decl_with_attr(_decl, _attr)
diff --git a/src/common/pico_sync/sem.c b/src/common/pico_sync/sem.c index ec49fdb..9044817 100644 --- a/src/common/pico_sync/sem.c +++ b/src/common/pico_sync/sem.c
@@ -15,7 +15,12 @@ } int __time_critical_func(sem_available)(semaphore_t *sem) { +#ifdef __GNUC__ return *(volatile typeof(sem->permits) *) &sem->permits; +#else + static_assert(sizeof(sem->permits) == 2, ""); + return *(volatile int16_t *) &sem->permits; +#endif } void __time_critical_func(sem_acquire_blocking)(semaphore_t *sem) {
diff --git a/src/common/pico_time/time.c b/src/common/pico_time/time.c index a4c0b27..fa32dd8 100644 --- a/src/common/pico_time/time.c +++ b/src/common/pico_time/time.c
@@ -22,7 +22,7 @@ void *user_data; } alarm_pool_entry_t; -typedef struct alarm_pool { +struct alarm_pool { pheap_t *heap; spin_lock_t *lock; alarm_pool_entry_t *entries; @@ -32,7 +32,7 @@ alarm_id_t alarm_in_progress; // this is set during a callback from the IRQ handler... it can be cleared by alarm_cancel to prevent repeats uint8_t hardware_alarm_num; uint8_t core_num; -} alarm_pool_t; +}; #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED // To avoid bringing in calloc, we statically allocate the arrays and the heap
diff --git a/src/common/pico_util/include/pico/util/queue.h b/src/common/pico_util/include/pico/util/queue.h index e920009..80e5a92 100644 --- a/src/common/pico_util/include/pico/util/queue.h +++ b/src/common/pico_util/include/pico/util/queue.h
@@ -59,7 +59,7 @@ * \param element_count Maximum number of entries in the queue */ static inline void queue_init(queue_t *q, uint element_size, uint element_count) { - return queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num()); + queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num()); } /*! \brief Destroy the specified queue.
diff --git a/src/rp2_common/boot_stage2/CMakeLists.txt b/src/rp2_common/boot_stage2/CMakeLists.txt index a130f41..97c8e01 100644 --- a/src/rp2_common/boot_stage2/CMakeLists.txt +++ b/src/rp2_common/boot_stage2/CMakeLists.txt
@@ -40,9 +40,9 @@ ) # todo bit of an abstraction failure - revisit for Clang support anyway - if (CMAKE_C_COMPILER_ID STREQUAL "Clang") + if (PICO_C_COMPILER_IS_CLANG) target_link_options(${NAME} PRIVATE "-nostdlib") - else () + elseif (PICO_C_COMPILER_IS_GNU) target_link_options(${NAME} PRIVATE "--specs=nosys.specs") target_link_options(${NAME} PRIVATE "-nostartfiles") endif ()
diff --git a/src/rp2_common/hardware_claim/claim.c b/src/rp2_common/hardware_claim/claim.c index c96764f..1636855 100644 --- a/src/rp2_common/hardware_claim/claim.c +++ b/src/rp2_common/hardware_claim/claim.c
@@ -6,7 +6,7 @@ #include "hardware/claim.h" -uint32_t hw_claim_lock() { +uint32_t hw_claim_lock(void) { return spin_lock_blocking(spin_lock_instance(PICO_SPINLOCK_ID_HARDWARE_CLAIM)); }
diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 86c5e8d..7507893 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c
@@ -78,8 +78,7 @@ // Note XOSC_COUNT is not helpful here because XOSC is not // necessarily running, nor is timer... so, 3 cycles per loop: uint delay_cyc = configured_freq[clk_sys] / configured_freq[clk_index] + 1; - asm volatile ( - ".syntax unified \n\t" + unified_asm ( "1: \n\t" "subs %0, #1 \n\t" "bne 1b"
diff --git a/src/rp2_common/hardware_divider/include/hardware/divider.h b/src/rp2_common/hardware_divider/include/hardware/divider.h index 0be2ef8..c5b91de 100644 --- a/src/rp2_common/hardware_divider/include/hardware/divider.h +++ b/src/rp2_common/hardware_divider/include/hardware/divider.h
@@ -85,10 +85,10 @@ // we use one less register and instruction than gcc which uses a TST instruction uint32_t tmp; // allow compiler to pick scratch register - asm volatile ( + unified_asm ( "hw_divider_result_loop_%=:" "ldr %0, [%1, %2]\n\t" - "lsr %0, #1\n\t" + "lsrs %0, %0, #1\n\t" "bcc hw_divider_result_loop_%=\n\t" : "=&l" (tmp) : "l" (sio_hw), "I" (SIO_DIV_CSR_OFFSET) @@ -105,7 +105,8 @@ */ static inline divmod_result_t hw_divider_result_nowait(void) { // as ugly as this looks it is actually quite efficient - divmod_result_t rc = (((divmod_result_t) sio_hw->div_remainder) << 32u) | sio_hw->div_quotient; + divmod_result_t rc = ((divmod_result_t) sio_hw->div_remainder) << 32u; + rc |= sio_hw->div_quotient; return rc; } @@ -295,7 +296,7 @@ * \ingroup hardware_divider */ static inline void hw_divider_pause(void) { - asm volatile ( + unified_asm ( "b _1_%=\n" "_1_%=:\n" "b _2_%=\n"
diff --git a/src/rp2_common/hardware_dma/dma.c b/src/rp2_common/hardware_dma/dma.c index f142b53..5fec210 100644 --- a/src/rp2_common/hardware_dma/dma.c +++ b/src/rp2_common/hardware_dma/dma.c
@@ -13,8 +13,8 @@ check_hw_layout(dma_hw_t, abort, DMA_CHAN_ABORT_OFFSET); // sanity check -static_assert(__builtin_offsetof(dma_hw_t, ch[0].ctrl_trig) == DMA_CH0_CTRL_TRIG_OFFSET, "hw mismatch"); -static_assert(__builtin_offsetof(dma_hw_t, ch[1].ctrl_trig) == DMA_CH1_CTRL_TRIG_OFFSET, "hw mismatch"); +static_assert(offsetof(dma_hw_t, ch[0].ctrl_trig) == DMA_CH0_CTRL_TRIG_OFFSET, "hw mismatch"); +static_assert(offsetof(dma_hw_t, ch[1].ctrl_trig) == DMA_CH1_CTRL_TRIG_OFFSET, "hw mismatch"); static_assert(NUM_DMA_CHANNELS <= 16, ""); static uint16_t _claimed;
diff --git a/src/rp2_common/hardware_flash/flash.c b/src/rp2_common/hardware_flash/flash.c index 5699302..970f0bf 100644 --- a/src/rp2_common/hardware_flash/flash.c +++ b/src/rp2_common/hardware_flash/flash.c
@@ -41,7 +41,7 @@ } static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void) { - ((void (*)(void))boot2_copyout+1)(); + ((void (*)(void))((intptr_t)boot2_copyout+1))(); } #else
diff --git a/src/rp2_common/hardware_i2c/i2c.c b/src/rp2_common/hardware_i2c/i2c.c index 95bcfea..c5cdbec 100644 --- a/src/rp2_common/hardware_i2c/i2c.c +++ b/src/rp2_common/hardware_i2c/i2c.c
@@ -27,9 +27,7 @@ // Addresses of the form 000 0xxx or 111 1xxx are reserved. No slave should // have these addresses. -static inline bool i2c_reserved_addr(uint8_t addr) { - return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; -} +#define i2c_reserved_addr(addr) (((addr) & 0x78) == 0 || ((addr) & 0x78) == 0x78) uint i2c_init(i2c_inst_t *i2c, uint baudrate) { i2c_reset(i2c);
diff --git a/src/rp2_common/hardware_irq/include/hardware/irq.h b/src/rp2_common/hardware_irq/include/hardware/irq.h index 3fca001..85caf67 100644 --- a/src/rp2_common/hardware_irq/include/hardware/irq.h +++ b/src/rp2_common/hardware_irq/include/hardware/irq.h
@@ -10,7 +10,7 @@ // These two config items are also used by assembler, so keeping separate // PICO_CONFIG: PICO_MAX_SHARED_IRQ_HANDLERS, Maximum number of shared IRQ handlers, default=4, advanced=true, group=hardware_irq #ifndef PICO_MAX_SHARED_IRQ_HANDLERS -#define PICO_MAX_SHARED_IRQ_HANDLERS 4u +#define PICO_MAX_SHARED_IRQ_HANDLERS 4 #endif // PICO_CONFIG: PICO_DISABLE_SHARED_IRQ_HANDLERS, Disable shared IRQ handlers, type=bool, default=0, group=hardware_irq
diff --git a/src/rp2_common/hardware_irq/irq.c b/src/rp2_common/hardware_irq/irq.c index 12b0dcd..3e66c18 100644 --- a/src/rp2_common/hardware_irq/irq.c +++ b/src/rp2_common/hardware_irq/irq.c
@@ -186,11 +186,11 @@ int32_t result = 0xaaaa; // return (to - from); // note this implementation has limited range, but is fine for plenty more than -128->127 result - asm (".syntax unified\n" + unified_asm ( "subs %1, %2\n" "adcs %1, %1\n" // * 2 (and + 1 if negative for rounding) "muls %0, %1\n" - "lsrs %0, 20\n" + "lsrs %0, %0, #20\n" : "+l" (result), "+l" (to) : "l" (from) : @@ -221,9 +221,9 @@ // start new chain hard_assert(vtable_handler == __unhandled_user_irq); struct irq_handler_chain_slot slot_data = { - .inst1 = 0xa100, // add r1, pc, #0 - .inst2 = make_branch(&slot->inst2, irq_handler_chain_first_slot), // b irq_handler_chain_first_slot - .inst3 = 0xbd01, // pop {r0, pc} + .inst1 = 0xa100, // add r1, pc, #0 + .inst2 = make_branch(&slot->inst2, (void *) irq_handler_chain_first_slot), // b irq_handler_chain_first_slot + .inst3 = 0xbd01, // pop {r0, pc} .link = -1, .priority = order_priority, .handler = handler @@ -233,7 +233,7 @@ } else { assert(!((((uintptr_t)vtable_handler) - ((uintptr_t)irq_handler_chain_slots) - 1)%sizeof(struct irq_handler_chain_slot))); struct irq_handler_chain_slot *prev_slot = NULL; - struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit(vtable_handler); + struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit((void *) vtable_handler); struct irq_handler_chain_slot *cur_slot = existing_vtable_slot; while (cur_slot->priority > order_priority) { prev_slot = cur_slot; @@ -259,9 +259,9 @@ } else { // update with new chain head struct irq_handler_chain_slot slot_data = { - .inst1 = 0xa100, // add r1, pc, #0 - .inst2 = make_branch(&slot->inst2, irq_handler_chain_first_slot), // b irq_handler_chain_first_slot - .inst3 = make_branch(&slot->inst3, existing_vtable_slot), // b existing_slot + .inst1 = 0xa100, // add r1, pc, #0 + .inst2 = make_branch(&slot->inst2, (void *) irq_handler_chain_first_slot), // b irq_handler_chain_first_slot + .inst3 = make_branch(&slot->inst3, existing_vtable_slot), // b existing_slot .link = get_slot_index(existing_vtable_slot), .priority = order_priority, .handler = handler @@ -309,7 +309,7 @@ hard_assert(!exception || exception == num + VTABLE_FIRST_IRQ); struct irq_handler_chain_slot *prev_slot = NULL; - struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit(vtable_handler); + struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit((void *) vtable_handler); struct irq_handler_chain_slot *to_free_slot = existing_vtable_slot; while (to_free_slot->handler != handler) { prev_slot = to_free_slot; @@ -354,7 +354,7 @@ // it to bl to irq_handler_chain_remove_tail which will remove the slot. // NOTE THAT THIS TRASHES PRIORITY AND LINK SINCE THIS IS A 4 BYTE INSTRUCTION // BUT THEY ARE NOT NEEDED NOW - insert_branch_and_link(&to_free_slot->inst3, irq_handler_chain_remove_tail); + insert_branch_and_link(&to_free_slot->inst3, (void *) irq_handler_chain_remove_tail); } } } else {
diff --git a/src/rp2_common/hardware_sync/include/hardware/sync.h b/src/rp2_common/hardware_sync/include/hardware/sync.h index 995b911..c571542 100644 --- a/src/rp2_common/hardware_sync/include/hardware/sync.h +++ b/src/rp2_common/hardware_sync/include/hardware/sync.h
@@ -114,9 +114,11 @@ * The SEV (send event) instruction sends an event to both cores. */ +#if !__has_builtin(__sev) __force_inline static void __sev(void) { - __asm volatile ("sev"); + unified_asm ("sev"); } +#endif /*! \brief Insert a WFE instruction in to the code path. * \ingroup hardware_sync @@ -124,18 +126,22 @@ * The WFE (wait for event) instruction waits until one of a number of * events occurs, including events signalled by the SEV instruction on either core. */ +#if !__has_builtin(__wfe) __force_inline static void __wfe(void) { - __asm volatile ("wfe"); + unified_asm ("wfe"); } +#endif /*! \brief Insert a WFI instruction in to the code path. * \ingroup hardware_sync * * The WFI (wait for interrupt) instruction waits for a interrupt to wake up the core. */ +#if !__has_builtin(__wfi) __force_inline static void __wfi(void) { - __asm volatile ("wfi"); + unified_asm ("wfi"); } +#endif /*! \brief Insert a DMB instruction in to the code path. * \ingroup hardware_sync @@ -144,7 +150,7 @@ * instruction will be observed before any explicit access after the instruction. */ __force_inline static void __dmb(void) { - __asm volatile ("dmb" : : : "memory"); + unified_asm ("dmb" : : : "memory"); } /*! \brief Insert a DSB instruction in to the code path. @@ -155,7 +161,7 @@ * accesses before this instruction complete. */ __force_inline static void __dsb(void) { - __asm volatile ("dsb" : : : "memory"); + unified_asm ("dsb" : : : "memory"); } /*! \brief Insert a ISB instruction in to the code path. @@ -166,7 +172,7 @@ * the ISB instruction has been completed. */ __force_inline static void __isb(void) { - __asm volatile ("isb"); + unified_asm ("isb"); } /*! \brief Acquire a memory fence @@ -207,8 +213,8 @@ */ __force_inline static uint32_t save_and_disable_interrupts(void) { uint32_t status; - __asm volatile ("mrs %0, PRIMASK" : "=r" (status)::); - __asm volatile ("cpsid i"); + unified_asm ("mrs %0, PRIMASK" : "=r" (status)::); + unified_asm ("cpsid i"); return status; } @@ -218,7 +224,7 @@ * \param status Previous interrupt status from save_and_disable_interrupts() */ __force_inline static void restore_interrupts(uint32_t status) { - __asm volatile ("msr PRIMASK,%0"::"r" (status) : ); + unified_asm ("msr PRIMASK,%0"::"r" (status) : ); } /*! \brief Get HW Spinlock instance from number @@ -389,7 +395,8 @@ */ bool spin_lock_is_claimed(uint lock_num); -#define remove_volatile_cast(t, x) ({__mem_fence_acquire(); (t)(x); }) +// no longer use __mem_fence_acquire here, as it is overkill on cortex M0+ +#define remove_volatile_cast(t, x) ({__compiler_memory_barrier(); Clang_Pragma("clang diagnostic push"); Clang_Pragma("clang diagnostic ignored \"-Wcast-qual\""); (t)(x); Clang_Pragma("clang diagnostic pop"); }) #ifdef __cplusplus }
diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c index 5def61a..0115686 100644 --- a/src/rp2_common/pico_bootrom/bootrom.c +++ b/src/rp2_common/pico_bootrom/bootrom.c
@@ -8,10 +8,6 @@ /// \tag::table_lookup[] -// Bootrom function: rom_table_lookup -// Returns the 32 bit pointer into the ROM if found or NULL otherwise. -typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); - void *rom_func_lookup(uint32_t code) { return rom_func_lookup_inline(code); }
diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h index e92207c..d4796af 100644 --- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h +++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h
@@ -116,7 +116,7 @@ // Returns the 32 bit pointer into the ROM if found or NULL otherwise. typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); -#if defined(__GNUC__) && (__GNUC__ >= 12) +#if PICO_C_COMPILER_IS_GNU && (__GNUC__ >= 12) // Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer static inline void *rom_hword_as_ptr(uint16_t rom_address) { #pragma GCC diagnostic push
diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c index 91ae242..6976d47 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c +++ b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
@@ -63,7 +63,7 @@ //#define SWAP32(A) ((((A) & 0xff000000U) >> 8) | (((A) & 0xff0000U) << 8) | (((A) & 0xff00U) >> 8) | (((A) & 0xffU) << 8)) __force_inline static uint32_t __swap16x2(uint32_t a) { - __asm ("rev16 %0, %0" : "+l" (a) : : ); + unified_asm ("rev16 %0, %0" : "+l" (a) : : ); return a; } #define SWAP32(a) __swap16x2(a)
diff --git a/src/rp2_common/pico_double/double_init_rom.c b/src/rp2_common/pico_double/double_init_rom.c index af6f6a2..eec56c4 100644 --- a/src/rp2_common/pico_double/double_init_rom.c +++ b/src/rp2_common/pico_double/double_init_rom.c
@@ -47,7 +47,7 @@ #endif if (rom_version >= 2) { void *rom_table = rom_data_lookup(rom_table_code('S', 'D')); - assert(*((uint8_t *)(((void *)rom_data_lookup(rom_table_code('S', 'F')))-2)) * 4 >= SF_TABLE_V2_SIZE); + assert(*((uint8_t *)rom_data_lookup(rom_table_code('S', 'F'))-2) * 4 >= SF_TABLE_V2_SIZE); memcpy(&sd_table, rom_table, SF_TABLE_V2_SIZE); if (rom_version == 2) { #ifndef NDEBUG
diff --git a/src/rp2_common/pico_double/double_math.c b/src/rp2_common/pico_double/double_math.c index 0d8e43c..6d2a48e 100644 --- a/src/rp2_common/pico_double/double_math.c +++ b/src/rp2_common/pico_double/double_math.c
@@ -8,9 +8,9 @@ #include "pico/double.h" // opened a separate issue https://github.com/raspberrypi/pico-sdk/issues/166 to deal with these warnings if at all -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Wconversion\"") -_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wconversion\"") +GCC_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") typedef uint64_t ui64; typedef uint32_t ui32; @@ -56,13 +56,13 @@ return tmp.ix; } +#if PICO_DOUBLE_PROPAGATE_NANS static inline bool disnan(double x) { ui64 ix= double2ui64(x); // checks the top bit of the low 32 bit of the NAN, but it I think that is ok return ((uint32_t)(ix >> 31)) > 0xffe00000u; } -#if PICO_DOUBLE_PROPAGATE_NANS #define check_nan_d1(x) if (disnan((x))) return (x) #define check_nan_d2(x,y) if (disnan((x))) return (x); else if (disnan((y))) return (y); #else @@ -109,8 +109,8 @@ return dcopysign(x, y); } static inline int diszero(double x) { return dgetexp (x)==0; } -static inline int dispzero(double x) { return dgetsignexp(x)==0; } -static inline int dismzero(double x) { return dgetsignexp(x)==0x800; } +//static inline int dispzero(double x) { return dgetsignexp(x)==0; } +//static inline int dismzero(double x) { return dgetsignexp(x)==0x800; } static inline int disinf(double x) { return dgetexp (x)==0x7ff; } static inline int dispinf(double x) { return dgetsignexp(x)==0x7ff; } static inline int disminf(double x) { return dgetsignexp(x)==0xfff; } @@ -419,10 +419,10 @@ } double WRAPPER_FUNC(powint)(double x,int y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0||y==0) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") check_nan_d1(x); if(diszero(x)) { if(y>0) { @@ -468,13 +468,13 @@ } double WRAPPER_FUNC(pow)(double x,double y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0||diszero(y)) return 1; check_nan_d2(x, y); if(x==-1.0&&disinf(y)) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") if(diszero(x)) { if(!disneg(y)) { @@ -621,4 +621,4 @@ double WRAPPER_FUNC(remainder)(double x,double y) { check_nan_d2(x, y); return remquo(x,y,0); } -_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file +GCC_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file
diff --git a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c index 503cd12..2fefb80 100644 --- a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c +++ b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
@@ -110,8 +110,9 @@ gpio_set_inover(dp, GPIO_OVERRIDE_HIGH); // Force PHY pull up to stay before switching away from the phy - hw_set_alias(usb_hw)->phy_direct = USB_USBPHY_DIRECT_DP_PULLUP_EN_BITS; - hw_set_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; + usb_hw_t *usb_hw_set = (usb_hw_t *)hw_set_alias_untyped(usb_hw); + usb_hw_set->phy_direct = USB_USBPHY_DIRECT_DP_PULLUP_EN_BITS; + usb_hw_set->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; // Switch to GPIO phy with LS_J forced usb_hw->muxing = USB_USB_MUXING_TO_DIGITAL_PAD_BITS | USB_USB_MUXING_SOFTCON_BITS; @@ -138,7 +139,7 @@ usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; // Get rid of DP pullup override - hw_clear_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; + hw_clear_bits(&usb_hw->phy_direct_override, USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS); // Finally, restore the gpio ctrl value back to GPIO15 iobank0_hw->io[dp].ctrl = gpio_ctrl_prev;
diff --git a/src/rp2_common/pico_float/float_init_rom.c b/src/rp2_common/pico_float/float_init_rom.c index 646c0e9..062bfe7 100644 --- a/src/rp2_common/pico_float/float_init_rom.c +++ b/src/rp2_common/pico_float/float_init_rom.c
@@ -63,7 +63,7 @@ } #endif if (rom_version >= 2) { - assert(*((uint8_t *)(rom_table-2)) * 4 >= SF_TABLE_V2_SIZE); + assert(*((uint8_t *)rom_table-2) * 4 >= SF_TABLE_V2_SIZE); memcpy(&sf_table, rom_table, SF_TABLE_V2_SIZE); } sf_clz_func = rom_func_lookup(ROM_FUNC_CLZ32);
diff --git a/src/rp2_common/pico_float/float_math.c b/src/rp2_common/pico_float/float_math.c index d11491c..93eb01d 100644 --- a/src/rp2_common/pico_float/float_math.c +++ b/src/rp2_common/pico_float/float_math.c
@@ -7,9 +7,9 @@ #include "pico/float.h" // opened a separate issue https://github.com/raspberrypi/pico-sdk/issues/166 to deal with these warnings if at all -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Wconversion\"") -_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wconversion\"") +GCC_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") typedef uint32_t ui32; typedef int32_t i32; @@ -54,12 +54,12 @@ return tmp.ix; } +#if PICO_FLOAT_PROPAGATE_NANS static inline bool fisnan(float x) { ui32 ix=float2ui32(x); return ix * 2 > 0xff000000u; } -#if PICO_FLOAT_PROPAGATE_NANS #define check_nan_f1(x) if (fisnan((x))) return (x) #define check_nan_f2(x,y) if (fisnan((x))) return (x); else if (fisnan((y))) return (y); #else @@ -106,8 +106,8 @@ } static inline int fiszero(float x) { return fgetexp (x)==0; } -static inline int fispzero(float x) { return fgetsignexp(x)==0; } -static inline int fismzero(float x) { return fgetsignexp(x)==0x100; } +//static inline int fispzero(float x) { return fgetsignexp(x)==0; } +//static inline int fismzero(float x) { return fgetsignexp(x)==0x100; } static inline int fisinf(float x) { return fgetexp (x)==0xff; } static inline int fispinf(float x) { return fgetsignexp(x)==0xff; } static inline int fisminf(float x) { return fgetsignexp(x)==0x1ff; } @@ -377,8 +377,8 @@ } float WRAPPER_FUNC(powintf)(float x,int y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Pragma("GCC diagnostic push") + GCC_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0f||y==0) return 1; if(x==0.0f) { if(y>0) { @@ -388,7 +388,7 @@ if((y&1)) return fcopysign(FPINF,x); return FPINF; } - _Pragma("GCC diagnostic pop") + GCC_Pragma("GCC diagnostic pop") check_nan_f1(x); if(fispinf(x)) { if(y<0) return 0; @@ -426,12 +426,12 @@ } float WRAPPER_FUNC(powf)(float x,float y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0f||fiszero(y)) return 1; check_nan_f2(x,y); if(x==-1.0f&&fisinf(y)) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") if(fiszero(x)) { if(!fisneg(y)) { if(fisoddint(y)) return x; @@ -579,4 +579,4 @@ float WRAPPER_FUNC(remainderf)(float x,float y) { check_nan_f2(x,y); return remquof(x,y,0); } -_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file +GCC_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file
diff --git a/src/rp2_common/pico_float/float_none.S b/src/rp2_common/pico_float/float_none.S index 55baf29..db8e126 100644 --- a/src/rp2_common/pico_float/float_none.S +++ b/src/rp2_common/pico_float/float_none.S
@@ -29,7 +29,6 @@ wrapper_func __aeabi_l2f wrapper_func __aeabi_ui2f wrapper_func __aeabi_ul2f -wrapper_func __aeabi_i2f wrapper_func __aeabi_f2iz wrapper_func __aeabi_f2lz wrapper_func __aeabi_f2uiz
diff --git a/src/rp2_common/pico_i2c_slave/i2c_slave.c b/src/rp2_common/pico_i2c_slave/i2c_slave.c index 74a988e..12b5301 100644 --- a/src/rp2_common/pico_i2c_slave/i2c_slave.c +++ b/src/rp2_common/pico_i2c_slave/i2c_slave.c
@@ -15,10 +15,6 @@ static i2c_slave_t i2c_slaves[2]; -static inline i2c_inst_t *get_hw_instance(const i2c_slave_t *slave) { - return i2c_get_instance(slave - i2c_slaves); -} - static void __isr __not_in_flash_func(i2c_slave_irq_handler)(void) { uint i2c_index = __get_current_exception() - VTABLE_FIRST_IRQ - I2C0_IRQ; i2c_slave_t *slave = &i2c_slaves[i2c_index];
diff --git a/src/rp2_common/pico_malloc/CMakeLists.txt b/src/rp2_common/pico_malloc/CMakeLists.txt index d6f2a12..dacfaca 100644 --- a/src/rp2_common/pico_malloc/CMakeLists.txt +++ b/src/rp2_common/pico_malloc/CMakeLists.txt
@@ -3,7 +3,7 @@ pico_add_library(pico_malloc) target_sources(pico_malloc INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/pico_malloc.c + ${CMAKE_CURRENT_LIST_DIR}/pico_malloc_iar.c ) target_include_directories(pico_malloc_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
diff --git a/src/rp2_common/pico_malloc/pico_malloc.c b/src/rp2_common/pico_malloc/pico_malloc.c index a053986..0fdc82a 100644 --- a/src/rp2_common/pico_malloc/pico_malloc.c +++ b/src/rp2_common/pico_malloc/pico_malloc.c
@@ -4,8 +4,20 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#ifdef __ICCARM__ +/* To support IAR's runtime library, which features multiple link-time + * selectable heap implementations, this file is designed to be + * multiply included with PREFIX set to the appropriate function name + * prefix (if any) */ +#ifndef PREFIX +#error pico_malloc.c is #included on IAR +#endif +#else +#define PREFIX +#endif + +#ifndef PICO_MALLOC_INCLUDED_ONCE #include <stdlib.h> -#include <stdio.h> #include "pico.h" #include "pico/malloc.h" @@ -14,11 +26,6 @@ auto_init_mutex(malloc_mutex); #endif -extern void *__real_malloc(size_t size); -extern void *__real_calloc(size_t count, size_t size); -extern void *__real_realloc(void *mem, size_t size); -extern void __real_free(void *mem); - extern char __StackLimit; /* Set by linker. */ static inline void check_alloc(__unused void *mem, __unused uint size) { @@ -28,12 +35,19 @@ } #endif } +#define PICO_MALLOC_INCLUDED_ONCE +#endif -void *__wrap_malloc(size_t size) { +extern void *REAL_FUNC_EXP(__CONCAT(PREFIX,malloc))(size_t size); +extern void *REAL_FUNC_EXP(__CONCAT(PREFIX,calloc))(size_t count, size_t size); +extern void *REAL_FUNC_EXP(__CONCAT(PREFIX,realloc))(void *mem, size_t size); +extern void REAL_FUNC_EXP(__CONCAT(PREFIX,free))(void *mem); + +void *WRAPPER_FUNC_EXP(__CONCAT(PREFIX,malloc))(size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_malloc(size); + void *rc = REAL_FUNC_EXP(__CONCAT(PREFIX,malloc))(size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -46,11 +60,11 @@ return rc; } -void *__wrap_calloc(size_t count, size_t size) { +void *WRAPPER_FUNC_EXP(__CONCAT(PREFIX,calloc))(size_t count, size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_calloc(count, size); + void *rc = REAL_FUNC_EXP(__CONCAT(PREFIX,calloc))(count, size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -63,11 +77,11 @@ return rc; } -void *__wrap_realloc(void *mem, size_t size) { +void *WRAPPER_FUNC_EXP(__CONCAT(PREFIX,realloc))(void *mem, size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_realloc(mem, size); + void *rc = REAL_FUNC_EXP(__CONCAT(PREFIX,realloc))(mem, size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -80,11 +94,11 @@ return rc; } -void __wrap_free(void *mem) { +void WRAPPER_FUNC_EXP(__CONCAT(PREFIX,free))(void *mem) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - __real_free(mem); + REAL_FUNC_EXP(__CONCAT(PREFIX,free))(mem); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif
diff --git a/src/rp2_common/pico_malloc/pico_malloc_iar.c b/src/rp2_common/pico_malloc/pico_malloc_iar.c new file mode 100644 index 0000000..1ff0336 --- /dev/null +++ b/src/rp2_common/pico_malloc/pico_malloc_iar.c
@@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#if defined __ICCARM__ + +/* Used when you select "No-free heap" in Project > Options... > General options > Library options 2 */ +#define PREFIX __no_free_ +#include "pico_malloc.c" +#undef PREFIX +/* Used when you select "Basic heap" in Project > Options... > General options > Library options 2 */ +#define PREFIX __basic_ +#include "pico_malloc.c" +#undef PREFIX +/* Used when you select "Advanced heap" in Project > Options... > General options > Library options 2 */ +#define PREFIX __iar_dl +#include "pico_malloc.c" +#undef PREFIX + +#else + +#error Unsupported toolchain + +#endif
diff --git a/src/rp2_common/pico_multicore/multicore.c b/src/rp2_common/pico_multicore/multicore.c index 96f5065..1622145 100644 --- a/src/rp2_common/pico_multicore/multicore.c +++ b/src/rp2_common/pico_multicore/multicore.c
@@ -75,7 +75,7 @@ static uint32_t __attribute__((section(".stack1"))) core1_stack[PICO_CORE1_STACK_SIZE / sizeof(uint32_t)]; static void __attribute__ ((naked)) core1_trampoline(void) { - __asm("pop {r0, r1, pc}"); + unified_asm ("pop {r0, r1, pc}"); } int core1_wrapper(int (*entry)(void), void *stack_base) {
diff --git a/src/rp2_common/pico_platform/include/pico/platform.h b/src/rp2_common/pico_platform/include/pico/platform.h index 017680b..91606de 100644 --- a/src/rp2_common/pico_platform/include/pico/platform.h +++ b/src/rp2_common/pico_platform/include/pico/platform.h
@@ -68,9 +68,80 @@ #ifndef __ASSEMBLER__ +#if defined __GNUC__ #include <sys/cdefs.h> +// note LLVM defines __GNUC__ +#ifdef __clang__ +#define PICO_C_COMPILER_IS_CLANG 1 +#else +#define PICO_C_COMPILER_IS_GNU 1 +#endif +#elif defined __ICCARM__ +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif +#ifndef __always_inline +#define __always_inline __attribute__((__always_inline__)) +#endif +#ifndef __noinline +#define __noinline __attribute__((__noinline__)) +#endif +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif +#ifndef __printflike +#define __printflike(a, b) +#endif +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#ifndef __used +#define __used __attribute__((__used__)) +#endif +#ifndef __CONCAT1 +#define __CONCAT1(a, b) a ## b +#endif +#ifndef __CONCAT +#define __CONCAT(a, b) __CONCAT1(a, b) +#endif +#ifndef __STRING +#define __STRING(a) #a +#endif +/* Compatible definitions of GCC builtins */ + +static inline uint __builtin_ctz(uint x) { + extern uint32_t __ctzsi2(uint32_t); + return __ctzsi2(x); +} +#define __builtin_expect(x, y) (x) +#define __builtin_isnan(x) __iar_isnan(x) +#else +#error Unsupported toolchain +#endif + #include "pico/types.h" +// GCC_Like_Pragma(x) is a pragma on GNUC compatible compilers +#ifdef __GNUC__ +#define GCC_Like_Pragma _Pragma +#else +#define GCC_Like_Pragma(x) +#endif + +// Clang_Pragma(x) is a pragma on Clang only +#ifdef __clang__ +#define Clang_Pragma _Pragma +#else +#define Clang_Pragma(x) +#endif + +// GCC_Pragma(x) is a pragma on GCC only +#if PICO_C_COMPILER_IS_GNU +#define GCC_Pragma _Pragma +#else +#define GCC_Pragma(x) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -236,7 +307,8 @@ * int __force_inline my_function(int x) { * */ -#if defined(__GNUC__) && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus)))) + +#if PICO_C_COMPILER_IS_GNU && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus)))) #define __force_inline inline __always_inline #else #define __force_inline __always_inline @@ -263,11 +335,13 @@ #define MIN(a, b) ((b)>(a)?(a):(b)) #endif +#define unified_asm(...) __asm volatile (".syntax unified\n" __VA_ARGS__) + /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ static inline void __breakpoint(void) { - __asm__("bkpt #0"); + unified_asm ("bkpt #0"); } /*! \brief Ensure that the compiler does not move memory access across this method call @@ -283,7 +357,7 @@ * might - even above the memory store!) */ __force_inline static void __compiler_memory_barrier(void) { - __asm__ volatile ("" : : : "memory"); + unified_asm ("" : : : "memory"); } /*! \brief Macro for converting memory addresses to 32 bit addresses suitable for DMA @@ -343,10 +417,10 @@ * @return the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2) */ static inline uint8_t rp2040_rom_version(void) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") return *(uint8_t*)0x13; -#pragma GCC diagnostic pop +GCC_Pragma("GCC diagnostic pop") } /*! \brief No-op function for the body of tight loops @@ -369,7 +443,7 @@ * \return a * b */ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { - asm ("mul %0, %1" : "+l" (a) : "l" (b) : ); + unified_asm ("muls %0, %1" : "+l" (a) : "l" (b) : ); return a; } @@ -405,7 +479,7 @@ */ static inline uint __get_current_exception(void) { uint exception; - asm ("mrs %0, ipsr" : "=l" (exception)); + unified_asm ("mrs %0, ipsr" : "=l" (exception)); return exception; } @@ -431,8 +505,7 @@ * \param minimum_cycles the minimum number of system clock cycles to delay for */ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { - __asm volatile ( - ".syntax unified\n" + unified_asm ( "1: subs %0, #3\n" "bcs 1b\n" : "+r" (minimum_cycles) : : "memory"
diff --git a/src/rp2_common/pico_platform/platform.c b/src/rp2_common/pico_platform/platform.c index 9bbcf26..46e3c88 100644 --- a/src/rp2_common/pico_platform/platform.c +++ b/src/rp2_common/pico_platform/platform.c
@@ -18,7 +18,7 @@ #if !PICO_NO_FPGA_CHECK // Inline stub provided in header if this code is unused (so folding can be // done in each TU instead of relying on LTO) -bool running_on_fpga() { +bool running_on_fpga(void) { return !!((*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS); } #endif @@ -26,7 +26,7 @@ #define MANUFACTURER_RPI 0x927 #define PART_RP2 0x2 -uint8_t rp2040_chip_version() { +uint8_t rp2040_chip_version(void) { // First register of sysinfo is chip id uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET)); uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS;
diff --git a/src/rp2_common/pico_printf/printf.c b/src/rp2_common/pico_printf/printf.c index cafdc1b..7ae526f 100644 --- a/src/rp2_common/pico_printf/printf.c +++ b/src/rp2_common/pico_printf/printf.c
@@ -107,15 +107,6 @@ #endif -/** - * Output a character to a custom device like UART, used by the printf() function - * This function is declared here only. You have to write your custom implementation somewhere - * \param character Character to output - */ -static void _putchar(char character) { - putchar(character); -} - // output function type typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen); @@ -148,17 +139,6 @@ (void) maxlen; } -// internal _putchar wrapper -static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { - (void) buffer; - (void) idx; - (void) maxlen; - if (character) { - _putchar(character); - } -} - - // internal output function wrapper static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { (void) idx; @@ -920,6 +900,25 @@ #if LIB_PICO_PRINTF_PICO #if !PICO_PRINTF_ALWAYS_INCLUDED +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +static void _putchar(char character) { + putchar(character); +} + +// internal _putchar wrapper +static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { + (void) buffer; + (void) idx; + (void) maxlen; + if (character) { + _putchar(character); + } +} + bool weak_raw_printf(const char *fmt, ...) { va_list va; va_start(va, fmt);
diff --git a/src/rp2_common/pico_runtime/CMakeLists.txt b/src/rp2_common/pico_runtime/CMakeLists.txt index 08a9a50..9879ba1 100644 --- a/src/rp2_common/pico_runtime/CMakeLists.txt +++ b/src/rp2_common/pico_runtime/CMakeLists.txt
@@ -40,5 +40,9 @@ endif() # todo is this correct/needed? -target_link_options(pico_runtime INTERFACE "--specs=nosys.specs") +if (PICO_C_COMPILER_IS_GNU) + target_link_options(pico_runtime INTERFACE "--specs=nosys.specs") +elseif (PICO_C_COMPILER_IS_CLANG) + # target_link_options(pico_runtime INTERFACE "-nostdlib") +endif()
diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index f9018d0..b707617 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c
@@ -114,8 +114,9 @@ #if !PICO_IE_26_29_UNCHANGED_ON_RESET // after resetting BANK0 we should disable IE on 26-29 - hw_clear_alias(padsbank0_hw)->io[26] = hw_clear_alias(padsbank0_hw)->io[27] = - hw_clear_alias(padsbank0_hw)->io[28] = hw_clear_alias(padsbank0_hw)->io[29] = PADS_BANK0_GPIO0_IE_BITS; + padsbank0_hw_t *padsbank0_hw_clear = (padsbank0_hw_t *)hw_clear_alias_untyped(padsbank0_hw); + padsbank0_hw_clear->io[26] = padsbank0_hw_clear->io[27] = + padsbank0_hw_clear->io[28] = padsbank0_hw_clear->io[29] = PADS_BANK0_GPIO0_IE_BITS; #endif // this is an array of either mutex_t or recursive_mutex_t (i.e. not necessarily the same size) @@ -150,7 +151,7 @@ #ifndef NDEBUG if (__get_current_exception()) { // crap; started in exception handler - __asm ("bkpt #0"); + unified_asm ("bkpt #0"); } #endif @@ -260,8 +261,8 @@ } // incorrect warning from GCC 6 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"") void __assert_func(const char *file, int line, const char *func, const char *failedexpr) { weak_raw_printf("assertion \"%s\" failed: file \"%s\", line %d%s%s\n", failedexpr, file, line, func ? ", function: " : "", @@ -269,10 +270,9 @@ _exit(1); } +GCC_Pragma("GCC diagnostic pop") -#pragma GCC diagnostic pop - -void __attribute__((noreturn)) panic_unsupported() { +void __attribute__((noreturn)) panic_unsupported(void) { panic("not supported"); } @@ -286,7 +286,7 @@ // Use a forwarding method here as it is a little simpler than renaming the symbol as it is used from assembler void __attribute__((naked, noreturn)) __printflike(1, 0) panic(__unused const char *fmt, ...) { // if you get an undefined reference here, you didn't define your PICO_PANIC_FUNCTION! - __asm ( + unified_asm ( "push {lr}\n" #if !PICO_PANIC_FUNCTION_EMPTY "bl " __XSTRING(PICO_PANIC_FUNCTION) "\n"
diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index 582b439..b9282e2 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt
@@ -10,8 +10,8 @@ pico_add_map_output(pico_standard_link) # todo revisit when we do Clang - if (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(pico_standard_link INTERFACE "LINKER:-nostdlib") + if (PICO_C_COMPILER_IS_CLANG) +# target_link_options(pico_standard_link INTERFACE "LINKER:-fuse-ld=lld") endif () pico_mirrored_target_link_libraries(pico_standard_link INTERFACE hardware_regs pico_bootrom pico_binary_info) @@ -74,9 +74,11 @@ target_compile_definitions(pico_standard_link INTERFACE PICO_DEOPTIMIZED_DEBUG=1) endif() - # todo revisit/recall reasoning for why not -nostartfiles always? - # -nostartfiles will be added if PICO_NO_FLASH would be defined to 1 - target_link_options(pico_standard_link INTERFACE $<$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>:-nostartfiles>) + # -nostartfiles will be added if not using C++ exceptions (which is the only thing that seems to need it) + if (PICO_C_COMPILER_IS_GNU AND NOT PICO_CXX_ENABLE_EXCEPTIONS) +# target_link_options(pico_standard_link INTERFACE $<$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>:-nostartfiles>) + target_link_options(pico_standard_link INTERFACE -nostartfiles) + endif() # boot_stage2 will be linked if PICO_NO_FLASH would be defined to 0 target_link_libraries(pico_standard_link INTERFACE $<$<NOT:$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>>:$<IF:$<BOOL:$<TARGET_PROPERTY:PICO_TARGET_BOOT_STAGE2>>,$<TARGET_PROPERTY:PICO_TARGET_BOOT_STAGE2>,bs2_default>_library>) @@ -96,7 +98,7 @@ target_link_options(pico_standard_link INTERFACE "LINKER:--gc-sections") endif() - if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + if (PICO_C_COMPILER_IS_GNU) # Ignore warnings about rwx segments introduced in binutils 2.39 execute_process(COMMAND ${CMAKE_C_COMPILER} -print-prog-name=ld RESULT_VARIABLE RUN_C_RESULT OUTPUT_VARIABLE FULL_LD_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
diff --git a/src/rp2_common/pico_standard_link/crt0.S b/src/rp2_common/pico_standard_link/crt0.S index d061108..43b069d 100644 --- a/src/rp2_common/pico_standard_link/crt0.S +++ b/src/rp2_common/pico_standard_link/crt0.S
@@ -325,13 +325,13 @@ // ---------------------------------------------------------------------------- // Stack/heap dummies to set size -.section .stack +.section .stack, "a" // align to allow for memory protection (although this alignment is pretty much ignored by linker script) .align 5 .equ StackSize, PICO_STACK_SIZE .space StackSize -.section .heap +.section .heap, "a" .align 2 .equ HeapSize, PICO_HEAP_SIZE .space HeapSize
diff --git a/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld b/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld index 5b0afe6..efe5a40 100644 --- a/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld +++ b/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld
@@ -117,10 +117,7 @@ __binary_info_end = .; . = ALIGN(4); - /* End of .text-like segments */ - __etext = .; - - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -173,8 +170,10 @@ /* All data end */ __data_end__ = .; } > RAM AT> FLASH + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -205,7 +204,7 @@ __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -222,17 +221,17 @@ /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y .flash_end : { - __flash_binary_end = .; + PROVIDE(__flash_binary_end = .); } > FLASH /* stack limit is poorly named, but historically is maximum heap ptr */
diff --git a/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld b/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld index 90975b5..f149a84 100644 --- a/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld +++ b/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld
@@ -96,7 +96,7 @@ . = ALIGN(4); /* Vector table goes first in RAM, to avoid large alignment hole */ - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -123,7 +123,7 @@ __ram_text_end__ = .; } > RAM AT> FLASH __ram_text_source__ = LOADADDR(.text); - + . = ALIGN(4); .data : { __data_start__ = .; @@ -172,10 +172,10 @@ /* All data end */ __data_end__ = .; } > RAM AT> FLASH - /* __etext is the name of the .data init source pointer (...) */ + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -206,7 +206,7 @@ __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -223,11 +223,11 @@ /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y
diff --git a/src/rp2_common/pico_standard_link/memmap_default.ld b/src/rp2_common/pico_standard_link/memmap_default.ld index 07d5812..638e994 100644 --- a/src/rp2_common/pico_standard_link/memmap_default.ld +++ b/src/rp2_common/pico_standard_link/memmap_default.ld
@@ -117,10 +117,7 @@ __binary_info_end = .; . = ALIGN(4); - /* End of .text-like segments */ - __etext = .; - - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -173,8 +170,10 @@ /* All data end */ __data_end__ = .; } > RAM AT> FLASH + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -205,7 +204,7 @@ __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -222,17 +221,17 @@ /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y .flash_end : { - __flash_binary_end = .; + PROVIDE(__flash_binary_end = .); } > FLASH /* stack limit is poorly named, but historically is maximum heap ptr */
diff --git a/src/rp2_common/pico_standard_link/memmap_no_flash.ld b/src/rp2_common/pico_standard_link/memmap_no_flash.ld index 7a5977f..6d1aff0 100644 --- a/src/rp2_common/pico_standard_link/memmap_no_flash.ld +++ b/src/rp2_common/pico_standard_link/memmap_no_flash.ld
@@ -100,8 +100,6 @@ . = ALIGN(4); .data : { - /* End of .text-like segments */ - __etext = .; __data_start__ = .; *(vtable) *(.data*) @@ -143,10 +141,12 @@ __data_end__ = .; } > RAM - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); /* Start and end symbols must be word-aligned */ .scratch_x : { @@ -174,7 +174,7 @@ __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -191,11 +191,11 @@ /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y
diff --git a/src/rp2_common/pico_standard_link/new_delete.cpp b/src/rp2_common/pico_standard_link/new_delete.cpp index 6d632e2..19addda 100644 --- a/src/rp2_common/pico_standard_link/new_delete.cpp +++ b/src/rp2_common/pico_standard_link/new_delete.cpp
@@ -9,6 +9,7 @@ #if !PICO_CXX_DISABLE_ALLOCATION_OVERRIDES // Let user override #include <cstdlib> +#include "pico.h" void *operator new(std::size_t n) { return std::malloc(n);
diff --git a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c index 18e90df..291e939 100644 --- a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c +++ b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c
@@ -25,11 +25,11 @@ args.buf = buf; args.len = length; - __asm ( + unified_asm ( // r1 must contain a pointer to the arguments - "mov r1, %[args]\n" + "movs r1, %[args]\n" // semihosting call number 0x05 = SYS_WRITE - "mov r0, #5\n" + "movs r0, #5\n" // make the semihosting call: https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/The-semihosting-interface "bkpt 0xab\n" :
diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb.c b/src/rp2_common/pico_stdio_usb/stdio_usb.c index 32f1f33..0dc8d6d 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb.c
@@ -20,9 +20,6 @@ #include "device/usbd_pvt.h" // for usbd_defer_func static mutex_t stdio_usb_mutex; -#ifndef NDEBUG -static uint8_t stdio_usb_core_num; -#endif #if PICO_STDIO_USB_SUPPORT_CHARS_AVAILABLE_CALLBACK static void (*chars_available_callback)(void*); @@ -181,9 +178,6 @@ assert(false); return false; } -#ifndef NDEBUG - stdio_usb_core_num = (uint8_t)get_core_num(); -#endif #if !PICO_NO_BI_STDIO_USB bi_decl_if_func_used(bi_program_feature("USB stdin / stdout")); #endif
diff --git a/src/rp2_common/tinyusb/CMakeLists.txt b/src/rp2_common/tinyusb/CMakeLists.txt index 8b9e474..3b93163 100644 --- a/src/rp2_common/tinyusb/CMakeLists.txt +++ b/src/rp2_common/tinyusb/CMakeLists.txt
@@ -49,10 +49,12 @@ # Override suppress_tinyusb_warnings to add suppression of (falsely) reported GCC 11.2 warnings function(suppress_tinyusb_warnings) _suppress_tinyusb_warnings() - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c - PROPERTIES - COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds") + if (PICO_C_COMPILER_IS_GNU) + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c + PROPERTIES + COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds") + endif() endfunction() pico_promote_common_scope_vars()
diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index 22564b9..807ec47 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt
@@ -80,6 +80,14 @@ #-Wundef ) +if (PICO_C_COMPILER_IS_CLANG) + # todo fix up clang warnings + target_compile_options(kitchen_sink_options INTERFACE + -Wno-cast-qual + -Wno-unused-function + -Wno-format) +endif() + target_compile_definitions(kitchen_sink_libs INTERFACE PARAM_ASSERTIONS_ENABLE_ALL=1 # want to check all the assertions for compilation warnings PICO_AUDIO_DMA_IRQ=1 @@ -97,6 +105,8 @@ # TinyUSB itself, so we have to guard against TinyUSB not being present with the above if suppress_tinyusb_warnings() endif() +target_compile_definitions(kitchen_sink_extra_stdio PRIVATE + TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1) if (TARGET pico_lwip) set_source_files_properties( ${PICO_LWIP_PATH}/src/core/ipv4/ip4_frag.c @@ -119,6 +129,11 @@ target_link_libraries(kitchen_sink_no_flash kitchen_sink_libs kitchen_sink_options) pico_add_extra_outputs(kitchen_sink_no_flash) +add_executable(kitchen_sink_blocked_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) +pico_set_binary_type(kitchen_sink_blocked_ram blocked_ram) +target_link_libraries(kitchen_sink_blocked_ram kitchen_sink_libs kitchen_sink_options) +pico_add_extra_outputs(kitchen_sink_blocked_ram) + add_executable(kitchen_sink_cpp ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) target_link_libraries(kitchen_sink_cpp kitchen_sink_libs kitchen_sink_options) pico_set_program_name(kitchen_sink_cpp "Wombat tentacles CPP")
diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index c030a76..ab6118f 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c
@@ -100,9 +100,6 @@ BINARY_INFO_BLOCK_DEV_FLAG_READ | BINARY_INFO_BLOCK_DEV_FLAG_WRITE | BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN)); -//#pragma GCC push_options -//#pragma GCC optimize ("O3") - uint32_t *foo = (uint32_t *) 200; uint32_t dma_to = 0; @@ -133,11 +130,14 @@ puts("Hello Everything!"); puts("Hello Everything2!"); + printf("main at %p\n", (void *)main); + static uint x[2]; + printf("x[0] = %p, x[1] = %p\n", x, x+1); hard_assert(mutex_try_enter(&mutex, NULL)); hard_assert(!mutex_try_enter(&mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); // this should compile as we are Cortex M0+ - __asm volatile("SVC #3"); + unified_asm ("SVC #3"); }
diff --git a/test/pico_divider_test/pico_divider_nesting_test.c b/test/pico_divider_test/pico_divider_nesting_test.c index 3b5a745..cf1b950 100644 --- a/test/pico_divider_test/pico_divider_nesting_test.c +++ b/test/pico_divider_test/pico_divider_nesting_test.c
@@ -34,16 +34,16 @@ FAILED(); } } - float fz = z; + float fz = (float)z; float fa = fz / 11.0f; float fb = fmodf(fz, 11.0f); - if (fabsf(fz - (fa * 11.0 + fb) > 1e-9)) { + if (fabs(fz - (fa * 11.0 + fb)) > 1e-9) { FAILED(); } double dz = z; double da = dz / 11.0; double db = fmod(dz, 11.0); - if (fabsf(dz - (da * 11.0 + db) > 1e-9)) { + if (fabs(dz - (da * 11.0 + db)) > 1e-9) { FAILED(); }
diff --git a/test/pico_divider_test/pico_divider_test.c b/test/pico_divider_test/pico_divider_test.c index fc0e9ef..97936f8 100644 --- a/test/pico_divider_test/pico_divider_test.c +++ b/test/pico_divider_test/pico_divider_test.c
@@ -193,10 +193,9 @@ #endif uint32_t __attribute__((naked)) time_32(uint32_t a, uint32_t b, uint32_t (*func)(uint32_t a, uint32_t b)) { - asm( - ".syntax unified\n" + unified_asm ( "push {r4, r5, lr}\n" - "ldr r4, =#0xe000e018\n" + "ldr r4, =0xe000e018\n" "ldr r5, [r4]\n" "blx r2\n" "ldr r0, [r4]\n" @@ -208,11 +207,10 @@ } uint32_t __attribute__((naked)) time_64(uint64_t a, uint64_t b, uint64_t (*func64)(uint64_t a, uint64_t b)) { - asm( - ".syntax unified\n" + unified_asm ( "push {r4-r6, lr}\n" "ldr r6, [sp, #16]\n" - "ldr r4, =#0xe000e018\n" + "ldr r4, =0xe000e018\n" "ldr r5, [r4]\n" "blx r6\n" "ldr r0, [r4]\n"
diff --git a/test/pico_float_test/pico_float_test.c b/test/pico_float_test/pico_float_test.c index 73dfbc3..6cb034c 100644 --- a/test/pico_float_test/pico_float_test.c +++ b/test/pico_float_test/pico_float_test.c
@@ -398,7 +398,10 @@ printf("FEXP %10.18f\n", check_close1(expf, x)); printf("FLN %10.18f\n", check_close1(logf, x)); printf("POWF %10.18f\n", check_close2(powf, x, x)); + // todo clang why does this not compile? +#ifndef __clang__ printf("TRUNCF %10.18f\n", check_close1(truncf, x)); +#endif printf("LDEXPF %10.18f\n", check_close2(ldexpf, x, x)); printf("FMODF %10.18f\n", check_close2(fmodf, x, 3.0f)); sincosf(x, &s, &c); @@ -528,6 +531,10 @@ } for(float x = 4294967296.f * 4294967296.f; x>=0.5f; x/=2.f) { printf("d2i32 %f->%d\n", x, (int32_t)x); +#ifdef __clang__ + // seems to be a bug in clang wgere f2iz(2147483648.f) returns -2147483648 + if (x != 2147483648.f) +#endif check1(__aeabi_f2iz, x); }
diff --git a/tools/elf2uf2/main.cpp b/tools/elf2uf2/main.cpp index f8d635e..6b3c525 100644 --- a/tools/elf2uf2/main.cpp +++ b/tools/elf2uf2/main.cpp
@@ -129,7 +129,7 @@ for(const auto& range : valid_ranges) { if (range.from <= addr && range.to >= addr + size) { if (range.type == address_range::type::NO_CONTENTS && !uninitialized) { - return fail(ERROR_INCOMPATIBLE, "ELF contains memory contents for uninitialized memory at 0x%p", addr); + return fail(ERROR_INCOMPATIBLE, "ELF contains memory contents for uninitialized memory at %p", addr); } ar = range; if (verbose) {