From 4a423264f7e46b6b84cd217232bb0a8c69509408 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 15 Dec 2022 07:37:26 +0900 Subject: [PATCH] Improve support for AVR and MSP430 custom targets --- .cspell.json | 1 + CHANGELOG.md | 4 + src/imp/mod.rs | 95 +++++++++------------ target-specs/avr-unknown-gnu-atmega168.json | 20 +++++ target-specs/msp430-unknown-none-elf.json | 18 ++++ tools/build.sh | 4 +- 6 files changed, 87 insertions(+), 55 deletions(-) create mode 100644 target-specs/avr-unknown-gnu-atmega168.json create mode 100644 target-specs/msp430-unknown-none-elf.json diff --git a/.cspell.json b/.cspell.json index 44b7a9f31..0b05d9ed8 100644 --- a/.cspell.json +++ b/.cspell.json @@ -48,6 +48,7 @@ "ignorePaths": [ // TODO "src/imp/**", + "target-specs/**", "**/linker.ld" ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 45ef699b0..e21516b93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com ## [Unreleased] +- Fix build error when not using `portable_atomic_unsafe_assume_single_core` cfg on AVR and MSP430 custom targets. + + Since 0.3.11, atomic CAS was supported without the cfg on AVR and MSP430 builtin targets, but that change was not applied to custom targets. + ## [0.3.17] - 2022-12-14 - Optimize x86_64 128-bit atomic load/store on AMD CPU with AVX. ([#49](https://github.com/taiki-e/portable-atomic/pull/49)) diff --git a/src/imp/mod.rs b/src/imp/mod.rs index c82c9e6c6..9e60daf4c 100644 --- a/src/imp/mod.rs +++ b/src/imp/mod.rs @@ -2,7 +2,12 @@ // Lock-free implementations // cfg(target_has_atomic_load_store = "ptr") -#[cfg(not(portable_atomic_no_atomic_load_store))] +#[cfg(not(any( + portable_atomic_no_atomic_load_store, + portable_atomic_unsafe_assume_single_core, + target_arch = "avr", + target_arch = "msp430", +)))] #[cfg_attr( not(portable_atomic_no_cfg_target_has_atomic), cfg(not(all( @@ -10,7 +15,6 @@ not(target_has_atomic = "ptr") ))) )] -#[cfg(any(test, not(portable_atomic_unsafe_assume_single_core)))] mod core_atomic; // Miri and Sanitizer do not support inline assembly. @@ -137,38 +141,27 @@ pub(crate) mod float; // ----------------------------------------------------------------------------- // Atomic{Isize,Usize,Bool,Ptr}, Atomic{I,U}{8,16} -#[cfg_attr( - portable_atomic_no_cfg_target_has_atomic, - cfg(any( - not(portable_atomic_no_atomic_cas), - all( - not(portable_atomic_no_atomic_load_store), - not(portable_atomic_unsafe_assume_single_core) - ) - )) -)] +#[cfg(not(any( + portable_atomic_no_atomic_load_store, + portable_atomic_unsafe_assume_single_core, + target_arch = "avr", + target_arch = "msp430", +)))] #[cfg_attr( not(portable_atomic_no_cfg_target_has_atomic), - cfg(any( - target_has_atomic = "ptr", - all( - not(portable_atomic_no_atomic_load_store), - not(portable_atomic_unsafe_assume_single_core), - not(all( - any(target_arch = "riscv32", target_arch = "riscv64"), - not(target_has_atomic = "ptr") - )) - ) - )) + cfg(not(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + not(target_has_atomic = "ptr") + ))) )] pub(crate) use self::core_atomic::{ AtomicBool, AtomicI16, AtomicI8, AtomicIsize, AtomicPtr, AtomicU16, AtomicU8, AtomicUsize, }; // RISC-V without A-extension #[cfg(not(portable_atomic_unsafe_assume_single_core))] -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(portable_atomic_no_atomic_cas))] #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not(target_has_atomic = "ptr")))] +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] pub(crate) use self::riscv::{ AtomicBool, AtomicI16, AtomicI8, AtomicIsize, AtomicPtr, AtomicU16, AtomicU8, AtomicUsize, }; @@ -185,37 +178,25 @@ pub(crate) use self::interrupt::{ }; // Atomic{I,U}32 -#[cfg(not(target_pointer_width = "16"))] -#[cfg_attr( - portable_atomic_no_cfg_target_has_atomic, - cfg(any( - not(portable_atomic_no_atomic_cas), - all( - not(portable_atomic_no_atomic_load_store), - not(portable_atomic_unsafe_assume_single_core) - ) - )) -)] +#[cfg(not(any( + portable_atomic_no_atomic_load_store, + portable_atomic_unsafe_assume_single_core, + target_arch = "avr", + target_arch = "msp430", +)))] #[cfg_attr( not(portable_atomic_no_cfg_target_has_atomic), - cfg(any( - target_has_atomic = "ptr", - all( - not(portable_atomic_no_atomic_load_store), - not(portable_atomic_unsafe_assume_single_core), - not(all( - any(target_arch = "riscv32", target_arch = "riscv64"), - not(target_has_atomic = "ptr") - )) - ) - )) + cfg(not(all( + any(target_arch = "riscv32", target_arch = "riscv64"), + not(target_has_atomic = "ptr") + ))) )] pub(crate) use self::core_atomic::{AtomicI32, AtomicU32}; // RISC-V without A-extension #[cfg(not(portable_atomic_unsafe_assume_single_core))] -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(portable_atomic_no_atomic_cas))] #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not(target_has_atomic = "ptr")))] +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] pub(crate) use self::riscv::{AtomicI32, AtomicU32}; // no core Atomic{I,U}32 & no CAS & assume single core => critical section based fallback #[cfg(any(not(target_pointer_width = "16"), feature = "fallback"))] @@ -229,6 +210,10 @@ pub(crate) use self::riscv::{AtomicI32, AtomicU32}; pub(crate) use self::interrupt::{AtomicI32, AtomicU32}; // Atomic{I,U}64 +#[cfg(not(any( + portable_atomic_no_atomic_load_store, + portable_atomic_unsafe_assume_single_core, +)))] #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_64)))] #[cfg_attr( not(portable_atomic_no_cfg_target_has_atomic), @@ -236,8 +221,6 @@ pub(crate) use self::interrupt::{AtomicI32, AtomicU32}; target_has_atomic = "64", all( not(any(target_pointer_width = "16", target_pointer_width = "32")), - not(portable_atomic_no_atomic_load_store), - not(portable_atomic_unsafe_assume_single_core), not(all( any(target_arch = "riscv32", target_arch = "riscv64"), not(target_has_atomic = "ptr") @@ -248,16 +231,20 @@ pub(crate) use self::interrupt::{AtomicI32, AtomicU32}; pub(crate) use self::core_atomic::{AtomicI64, AtomicU64}; // RISC-V without A-extension #[cfg(not(portable_atomic_unsafe_assume_single_core))] -#[cfg(target_arch = "riscv64")] #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(portable_atomic_no_atomic_cas))] #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not(target_has_atomic = "ptr")))] +#[cfg(target_arch = "riscv64")] pub(crate) use self::riscv::{AtomicI64, AtomicU64}; // no core Atomic{I,U}64 & has CAS => use lock-base fallback #[cfg(feature = "fallback")] -#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(portable_atomic_no_atomic_64))] -#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not(target_has_atomic = "64")))] -#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_cas)))] -#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = "ptr"))] +#[cfg_attr( + portable_atomic_no_cfg_target_has_atomic, + cfg(all(portable_atomic_no_atomic_64, not(portable_atomic_no_atomic_cas))) +)] +#[cfg_attr( + not(portable_atomic_no_cfg_target_has_atomic), + cfg(all(not(target_has_atomic = "64"), target_has_atomic = "ptr")) +)] pub(crate) use self::fallback::{AtomicI64, AtomicU64}; // no core Atomic{I,U}64 & no CAS & assume single core => critical section based fallback #[cfg(any( diff --git a/target-specs/avr-unknown-gnu-atmega168.json b/target-specs/avr-unknown-gnu-atmega168.json new file mode 100644 index 000000000..8b7d31838 --- /dev/null +++ b/target-specs/avr-unknown-gnu-atmega168.json @@ -0,0 +1,20 @@ +{ + "arch": "avr", + "atomic-cas": false, + "cpu": "atmega168", + "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", + "eh-frame-header": false, + "exe-suffix": ".elf", + "late-link-args": { + "gcc": ["-lgcc"] + }, + "linker": "avr-gcc", + "llvm-target": "avr-unknown-unknown", + "max-atomic-width": 0, + "pre-link-args": { + "gcc": ["-mmcu=atmega168"] + }, + "relocation-model": "static", + "target-c-int-width": "16", + "target-pointer-width": "16" +} diff --git a/target-specs/msp430-unknown-none-elf.json b/target-specs/msp430-unknown-none-elf.json new file mode 100644 index 000000000..2170e7a15 --- /dev/null +++ b/target-specs/msp430-unknown-none-elf.json @@ -0,0 +1,18 @@ +{ + "arch": "msp430", + "asm-args": ["-mcpu=msp430"], + "atomic-cas": false, + "data-layout": "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16", + "default-codegen-units": 1, + "eh-frame-header": false, + "emit-debug-gdb-scripts": false, + "linker": "msp430-elf-gcc", + "linker-is-gnu": false, + "llvm-target": "msp430-none-elf", + "max-atomic-width": 0, + "panic-strategy": "abort", + "relocation-model": "static", + "target-c-int-width": "16", + "target-pointer-width": "16", + "trap-unreachable": false +} diff --git a/tools/build.sh b/tools/build.sh index 4cea993e0..b2dbad135 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -9,14 +9,16 @@ trap -- 'exit 0' SIGINT default_targets=( # no atomic load/store (16-bit) + avr-unknown-gnu-atmega168 # for checking custom target avr-unknown-gnu-atmega328 msp430-none-elf + msp430-unknown-none-elf # same as msp430-none-elf, but for checking custom target # no atomic load/store (32-bit) riscv32i-unknown-none-elf riscv32im-unknown-none-elf riscv32imc-unknown-none-elf # no atomic load/store (64-bit) - riscv64i-unknown-none-elf + riscv64i-unknown-none-elf # custom target # no atomic CAS (32-bit) thumbv4t-none-eabi