Skip to content

Commit 1ac9037

Browse files
authored
Various small fixes towards building with other compilers (hathach#1285)
* Fix various non-GCC warnings (no effect on GCC) * Reduce use of typeof since non GCC compilers may not support it * Introduce PICO_C_COMPILER_IS_GNU, PICO_C_COMPILER_IS_CLANG, PICO_C_COMPILER_IS_IAR to CMake as if (CMAKE_C_COMPILER_ID STREQUAL "xxx") is a bit verbose * Use "unified_asm" macro for all inline asm (it is "volatile __asm" on GNU with a .syntex unified) * Use NOLOAD instead of COPY in linker scripts (arguably more correct anyway) * Use the same style for setting _etext in all 4 linker scripts (to the beginning of .data). Clang aligns .data on a 16 byte boundary. Note ideally we'd add a new symbol __data_source, however that would break backwards compatibility with existing user linker scripts * Use "a" for .stack, .heap sections because clang complains otherwise, and they are explicitly NOLOAD anyway * Avoid duplicating __sev, __wfe, __wfi which Clang sometimes seems to provide as built-ins * Add missing kitchen_sink_blocked_ram binary * Allow build with LLVM Embedded Toolchain Form ARM v 14.0.0 (unsupported atm)
1 parent bc7d9ce commit 1ac9037

File tree

49 files changed

+315
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+315
-212
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ if (NOT TARGET _pico_sdk_inclusion_marker)
99

1010
project(pico_sdk C CXX ASM)
1111

12+
string(REGEX MATCH "Clang" PICO_C_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
13+
string(REGEX MATCH "GNU" PICO_C_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}")
14+
string(REGEX MATCH "IAR" PICO_C_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}")
15+
pico_register_common_scope_var(PICO_C_COMPILER_IS_CLANG)
16+
pico_register_common_scope_var(PICO_C_COMPILER_IS_GNU)
17+
pico_register_common_scope_var(PICO_C_COMPILER_IS_IAR)
18+
1219
message("Build type is ${CMAKE_BUILD_TYPE}")
1320
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
1421
if (PICO_DEOPTIMIZED_DEBUG)

cmake/preload/toolchains/pico_arm_clang.cmake

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED
1+
# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED, however should work with LLVM Embedded Toolchain for ARM
2+
# version 14.0.0 https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/tag/release-14.0.0
23
# todo there is probably a more "cmake" way of doing this going thru the standard path with our "PICO" platform
34
# i.e. CMake<Lang>Information and whatnot
45
include(${CMAKE_CURRENT_LIST_DIR}/find_compiler.cmake)
@@ -37,9 +38,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
3738
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
3839
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
3940

40-
include_directories(/usr/include/newlib)
41-
4241
option(PICO_DEOPTIMIZED_DEBUG "Build debug builds with -O0" 0)
4342

44-
set(ARM_TOOLCHAIN_COMMON_FLAGS " --target=arm-none-eabi -mcpu=cortex-m0plus -mthumb")
43+
# Oz is preferred for Clang (verses CMake default -Os) see also https://gitlab.kitware.com/cmake/cmake/-/issues/22458
44+
set(CMAKE_C_FLAGS_MINSIZEREL "-Oz -DNDEBUG")
45+
46+
set(ARM_TOOLCHAIN_COMMON_FLAGS "--target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m --sysroot ${PICO_COMPILER_DIR}/../lib/clang-runtimes/armv6m_soft_nofp")
4547
include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake)

src/common/pico_binary_info/include/pico/binary_info/code.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
#include "pico/binary_info/structure.h"
1717

1818
#if !PICO_NO_BINARY_INFO
19-
#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *name = bi
19+
#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *const name = bi
2020
#define __bi_lineno_var_name __CONCAT(__bi_, __LINE__)
2121
#define __bi_ptr_lineno_var_name __CONCAT(__bi_ptr, __LINE__)
2222
#define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__)
2323
#define __bi_mark_enclosure static const __unused int __bi_enclosure_check_lineno_var_name=0;
24-
#if !defined(__GNUC__) || __cplusplus || __GNUC__ >= 8
24+
#if __cplusplus || __GNUC__ >= 8
2525
#define __bi_enclosure_check(x) (x + __bi_enclosure_check_lineno_var_name)
2626
#else
2727
// 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 @@
3939
* binary information declared this way will also be stripped
4040
* \ingroup pico_binary_info
4141
*/
42-
#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;});
42+
#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;});
4343

4444
#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);
45-
#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;});
45+
#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;});
4646
#else
4747
#define __bi_decl(bi, name, attr)
4848
#define bi_decl_with_attr(_decl, _attr)

src/common/pico_sync/sem.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ void sem_init(semaphore_t *sem, int16_t initial_permits, int16_t max_permits) {
1515
}
1616

1717
int __time_critical_func(sem_available)(semaphore_t *sem) {
18+
#ifdef __GNUC__
1819
return *(volatile typeof(sem->permits) *) &sem->permits;
20+
#else
21+
static_assert(sizeof(sem->permits) == 2, "");
22+
return *(volatile int16_t *) &sem->permits;
23+
#endif
1924
}
2025

2126
void __time_critical_func(sem_acquire_blocking)(semaphore_t *sem) {

src/common/pico_time/time.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ typedef struct alarm_pool_entry {
2222
void *user_data;
2323
} alarm_pool_entry_t;
2424

25-
typedef struct alarm_pool {
25+
struct alarm_pool {
2626
pheap_t *heap;
2727
spin_lock_t *lock;
2828
alarm_pool_entry_t *entries;
@@ -32,7 +32,7 @@ typedef struct alarm_pool {
3232
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
3333
uint8_t hardware_alarm_num;
3434
uint8_t core_num;
35-
} alarm_pool_t;
35+
};
3636

3737
#if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
3838
// To avoid bringing in calloc, we statically allocate the arrays and the heap

src/common/pico_util/include/pico/util/queue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void queue_init_with_spinlock(queue_t *q, uint element_size, uint element_count,
5959
* \param element_count Maximum number of entries in the queue
6060
*/
6161
static inline void queue_init(queue_t *q, uint element_size, uint element_count) {
62-
return queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num());
62+
queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num());
6363
}
6464

6565
/*! \brief Destroy the specified queue.

src/rp2_common/boot_stage2/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ function(pico_define_boot_stage2 NAME SOURCES)
4040
)
4141

4242
# todo bit of an abstraction failure - revisit for Clang support anyway
43-
if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
43+
if (PICO_C_COMPILER_IS_CLANG)
4444
target_link_options(${NAME} PRIVATE "-nostdlib")
45-
else ()
45+
elseif (PICO_C_COMPILER_IS_GNU)
4646
target_link_options(${NAME} PRIVATE "--specs=nosys.specs")
4747
target_link_options(${NAME} PRIVATE "-nostartfiles")
4848
endif ()

src/rp2_common/hardware_claim/claim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include "hardware/claim.h"
88

9-
uint32_t hw_claim_lock() {
9+
uint32_t hw_claim_lock(void) {
1010
return spin_lock_blocking(spin_lock_instance(PICO_SPINLOCK_ID_HARDWARE_CLAIM));
1111
}
1212

src/rp2_common/hardware_clocks/clocks.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc,
7878
// Note XOSC_COUNT is not helpful here because XOSC is not
7979
// necessarily running, nor is timer... so, 3 cycles per loop:
8080
uint delay_cyc = configured_freq[clk_sys] / configured_freq[clk_index] + 1;
81-
asm volatile (
82-
".syntax unified \n\t"
81+
unified_asm (
8382
"1: \n\t"
8483
"subs %0, #1 \n\t"
8584
"bne 1b"

src/rp2_common/hardware_divider/include/hardware/divider.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ static inline void hw_divider_wait_ready(void) {
8585
// we use one less register and instruction than gcc which uses a TST instruction
8686

8787
uint32_t tmp; // allow compiler to pick scratch register
88-
asm volatile (
88+
unified_asm (
8989
"hw_divider_result_loop_%=:"
9090
"ldr %0, [%1, %2]\n\t"
91-
"lsr %0, #1\n\t"
91+
"lsrs %0, %0, #1\n\t"
9292
"bcc hw_divider_result_loop_%=\n\t"
9393
: "=&l" (tmp)
9494
: "l" (sio_hw), "I" (SIO_DIV_CSR_OFFSET)
@@ -105,7 +105,8 @@ static inline void hw_divider_wait_ready(void) {
105105
*/
106106
static inline divmod_result_t hw_divider_result_nowait(void) {
107107
// as ugly as this looks it is actually quite efficient
108-
divmod_result_t rc = (((divmod_result_t) sio_hw->div_remainder) << 32u) | sio_hw->div_quotient;
108+
divmod_result_t rc = ((divmod_result_t) sio_hw->div_remainder) << 32u;
109+
rc |= sio_hw->div_quotient;
109110
return rc;
110111
}
111112

@@ -295,7 +296,7 @@ static inline int32_t hw_divider_remainder_s32(int32_t a, int32_t b) {
295296
* \ingroup hardware_divider
296297
*/
297298
static inline void hw_divider_pause(void) {
298-
asm volatile (
299+
unified_asm (
299300
"b _1_%=\n"
300301
"_1_%=:\n"
301302
"b _2_%=\n"

0 commit comments

Comments
 (0)