Skip to content

Commit f019526

Browse files
authored
Rollup merge of rust-lang#69478 - avr-rust:avr-support-upstream, r=jonas-schievink
Enable AVR as a Tier 3 target upstream Tracking issue: rust-lang#44052. Things intentionally left out of the initial upstream: * The `target_cpu` flag I have made the cleanup suggestions by @jplatte and @jplatte in avr-rust@043550d. Anybody feel free to give the branch a test and see how it fares, or make suggestions on the code patch itself.
2 parents 0d93d3f + 491bf8c commit f019526

File tree

28 files changed

+210
-15
lines changed

28 files changed

+210
-15
lines changed

config.toml.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
# the same format as above, but since these targets are experimental, they are
7070
# not built by default and the experimental Rust compilation targets that depend
7171
# on them will not work unless the user opts in to building them.
72-
#experimental-targets = ""
72+
#experimental-targets = "AVR"
7373

7474
# Cap the number of parallel linker invocations when compiling LLVM.
7575
# This can be useful when building LLVM with debug info, which significantly

src/bootstrap/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl Step for Llvm {
144144

145145
let llvm_exp_targets = match builder.config.llvm_experimental_targets {
146146
Some(ref s) => s,
147-
None => "",
147+
None => "AVR",
148148
};
149149

150150
let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" };

src/libcore/ptr/mod.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1345,14 +1345,24 @@ macro_rules! fnptr_impls_safety_abi {
13451345
#[stable(feature = "fnptr_impls", since = "1.4.0")]
13461346
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
13471347
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1348-
fmt::Pointer::fmt(&(*self as *const ()), f)
1348+
// HACK: The intermediate cast as usize is required for AVR
1349+
// so that the address space of the source function pointer
1350+
// is preserved in the final function pointer.
1351+
//
1352+
// https://github.com/avr-rust/rust/issues/143
1353+
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
13491354
}
13501355
}
13511356

13521357
#[stable(feature = "fnptr_impls", since = "1.4.0")]
13531358
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
13541359
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1355-
fmt::Pointer::fmt(&(*self as *const ()), f)
1360+
// HACK: The intermediate cast as usize is required for AVR
1361+
// so that the address space of the source function pointer
1362+
// is preserved in the final function pointer.
1363+
//
1364+
// https://github.com/avr-rust/rust/issues/143
1365+
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
13561366
}
13571367
}
13581368
}

src/librustc_ast_passes/feature_gate.rs

+8
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ impl<'a> PostExpansionVisitor<'a> {
121121
"amdgpu-kernel ABI is experimental and subject to change"
122122
);
123123
}
124+
"avr-interrupt" | "avr-non-blocking-interrupt" => {
125+
gate_feature_post!(
126+
&self,
127+
abi_avr_interrupt,
128+
span,
129+
"avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change"
130+
);
131+
}
124132
"efiapi" => {
125133
gate_feature_post!(
126134
&self,

src/librustc_codegen_llvm/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
375375
match self.conv {
376376
Conv::C | Conv::Rust => llvm::CCallConv,
377377
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
378+
Conv::AvrInterrupt => llvm::AvrInterrupt,
379+
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
378380
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
379381
Conv::Msp430Intr => llvm::Msp430Intr,
380382
Conv::PtxKernel => llvm::PtxKernel,

src/librustc_codegen_llvm/llvm/ffi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ pub enum CallConv {
4545
X86_64_Win64 = 79,
4646
X86_VectorCall = 80,
4747
X86_Intr = 83,
48+
AvrNonBlockingInterrupt = 84,
49+
AvrInterrupt = 85,
4850
AmdGpuKernel = 91,
4951
}
5052

src/librustc_feature/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ declare_features! (
574574
/// No longer treat an unsafe function as an unsafe block.
575575
(active, unsafe_block_in_unsafe_fn, "1.45.0", Some(71668), None),
576576

577+
/// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.
578+
(active, abi_avr_interrupt, "1.45.0", Some(69664), None),
579+
577580
// -------------------------------------------------------------------------
578581
// feature-group-end: actual feature gates
579582
// -------------------------------------------------------------------------

src/librustc_llvm/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ fn main() {
7878
"arm",
7979
"aarch64",
8080
"amdgpu",
81+
"avr",
8182
"mips",
8283
"powerpc",
8384
"systemz",

src/librustc_llvm/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ pub fn initialize_available_targets() {
7676
LLVMInitializeAMDGPUAsmPrinter,
7777
LLVMInitializeAMDGPUAsmParser
7878
);
79+
init_target!(
80+
llvm_component = "avr",
81+
LLVMInitializeAVRTargetInfo,
82+
LLVMInitializeAVRTarget,
83+
LLVMInitializeAVRTargetMC,
84+
LLVMInitializeAVRAsmPrinter,
85+
LLVMInitializeAVRAsmParser
86+
);
7987
init_target!(
8088
llvm_component = "mips",
8189
LLVMInitializeMipsTargetInfo,

src/librustc_middle/ty/layout.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2529,6 +2529,8 @@ where
25292529
Msp430Interrupt => Conv::Msp430Intr,
25302530
X86Interrupt => Conv::X86Intr,
25312531
AmdGpuKernel => Conv::AmdGpuKernel,
2532+
AvrInterrupt => Conv::AvrInterrupt,
2533+
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
25322534

25332535
// These API constants ought to be more specific...
25342536
Cdecl => Conv::C,

src/librustc_span/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ symbols! {
120120
abi_unadjusted,
121121
abi_vectorcall,
122122
abi_x86_interrupt,
123+
abi_avr_interrupt,
123124
abort,
124125
aborts,
125126
address,

src/librustc_target/abi/call/avr.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//! LLVM-frontend specific AVR calling convention implementation.
2+
//!
3+
//! # Current calling convention ABI
4+
//!
5+
//! Inherited from Clang's `clang::DefaultABIInfo` implementation - self described
6+
//! as
7+
//!
8+
//! > the default implementation for ABI specific details. This implementation
9+
//! > provides information which results in
10+
//! > self-consistent and sensible LLVM IR generation, but does not
11+
//! > conform to any particular ABI.
12+
//! >
13+
//! > - Doxygen Doxumentation of `clang::DefaultABIInfo`
14+
//!
15+
//! This calling convention may not match AVR-GCC in all cases.
16+
//!
17+
//! In the future, an AVR-GCC compatible argument classification ABI should be
18+
//! adopted in both Rust and Clang.
19+
//!
20+
//! *NOTE*: Currently, this module implements the same calling convention
21+
//! that clang with AVR currently does - the default, simple, unspecialized
22+
//! ABI implementation available to all targets. This ABI is not
23+
//! binary-compatible with AVR-GCC. Once LLVM [PR46140](https://bugs.llvm.org/show_bug.cgi?id=46140)
24+
//! is completed, this module should be updated to match so that both Clang
25+
//! and Rust emit code to the same AVR-GCC compatible ABI.
26+
//!
27+
//! In particular, both Clang and Rust may not have the same semantics
28+
//! when promoting arguments to indirect references as AVR-GCC. It is important
29+
//! to note that the core AVR ABI implementation within LLVM itself is ABI
30+
//! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount
31+
//! of compiler frontend specific calling convention logic implemented here.
32+
33+
use crate::abi::call::{ArgAbi, FnAbi};
34+
35+
fn classify_ret_ty<Ty>(ret: &mut ArgAbi<'_, Ty>) {
36+
if ret.layout.is_aggregate() {
37+
ret.make_indirect();
38+
}
39+
}
40+
41+
fn classify_arg_ty<Ty>(arg: &mut ArgAbi<'_, Ty>) {
42+
if arg.layout.is_aggregate() {
43+
arg.make_indirect();
44+
}
45+
}
46+
47+
pub fn compute_abi_info<Ty>(fty: &mut FnAbi<'_, Ty>) {
48+
if !fty.ret.is_ignore() {
49+
classify_ret_ty(&mut fty.ret);
50+
}
51+
52+
for arg in &mut fty.args {
53+
if arg.is_ignore() {
54+
continue;
55+
}
56+
57+
classify_arg_ty(arg);
58+
}
59+
}

src/librustc_target/abi/call/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::spec::{self, HasTargetSpec};
55
mod aarch64;
66
mod amdgpu;
77
mod arm;
8+
mod avr;
89
mod hexagon;
910
mod mips;
1011
mod mips64;
@@ -525,6 +526,8 @@ pub enum Conv {
525526
X86_64Win64,
526527

527528
AmdGpuKernel,
529+
AvrInterrupt,
530+
AvrNonBlockingInterrupt,
528531
}
529532

530533
/// Metadata describing how the arguments to a native function
@@ -580,6 +583,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
580583
"aarch64" => aarch64::compute_abi_info(cx, self),
581584
"amdgpu" => amdgpu::compute_abi_info(cx, self),
582585
"arm" => arm::compute_abi_info(cx, self),
586+
"avr" => avr::compute_abi_info(self),
583587
"mips" => mips::compute_abi_info(cx, self),
584588
"mips64" => mips64::compute_abi_info(cx, self),
585589
"powerpc" => powerpc::compute_abi_info(self),

src/librustc_target/spec/abi.rs

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum Abi {
2525
X86Interrupt,
2626
AmdGpuKernel,
2727
EfiApi,
28+
AvrInterrupt,
29+
AvrNonBlockingInterrupt,
2830

2931
// Multiplatform / generic ABIs
3032
Rust,
@@ -63,6 +65,12 @@ const AbiDatas: &[AbiData] = &[
6365
AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
6466
AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
6567
AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false },
68+
AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
69+
AbiData {
70+
abi: Abi::AvrNonBlockingInterrupt,
71+
name: "avr-non-blocking-interrupt",
72+
generic: false,
73+
},
6674
// Cross-platform ABIs
6775
AbiData { abi: Abi::Rust, name: "Rust", generic: true },
6876
AbiData { abi: Abi::C, name: "C", generic: true },
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::spec::{LinkerFlavor, Target, TargetResult};
2+
3+
pub fn target() -> TargetResult {
4+
Ok(Target {
5+
llvm_target: "avr-unknown-unknown".to_string(),
6+
target_endian: "little".to_string(),
7+
target_pointer_width: "16".to_string(),
8+
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(),
9+
arch: "avr".to_string(),
10+
linker_flavor: LinkerFlavor::Gcc,
11+
target_os: "unknown".to_string(),
12+
target_env: "".to_string(),
13+
target_vendor: "unknown".to_string(),
14+
target_c_int_width: 16.to_string(),
15+
options: super::freestanding_base::opts(),
16+
})
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
2+
use std::default::Default;
3+
4+
pub fn opts() -> TargetOptions {
5+
let mut args = LinkArgs::new();
6+
7+
args.insert(
8+
LinkerFlavor::Gcc,
9+
vec![
10+
// We want to be able to strip as much executable code as possible
11+
// from the linker command line, and this flag indicates to the
12+
// linker that it can avoid linking in dynamic libraries that don't
13+
// actually satisfy any symbols up to that point (as with many other
14+
// resolutions the linker does). This option only applies to all
15+
// following libraries so we're sure to pass it as one of the first
16+
// arguments.
17+
"-Wl,--as-needed".to_string(),
18+
],
19+
);
20+
21+
TargetOptions {
22+
dynamic_linking: false,
23+
executables: true,
24+
linker_is_gnu: true,
25+
has_rpath: false,
26+
pre_link_args: args,
27+
position_independent_executables: false,
28+
..Default::default()
29+
}
30+
}

src/librustc_target/spec/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mod arm_base;
5454
mod cloudabi_base;
5555
mod dragonfly_base;
5656
mod freebsd_base;
57+
mod freestanding_base;
5758
mod fuchsia_base;
5859
mod haiku_base;
5960
mod hermit_base;
@@ -579,6 +580,8 @@ supported_targets! {
579580
("aarch64-fuchsia", aarch64_fuchsia),
580581
("x86_64-fuchsia", x86_64_fuchsia),
581582

583+
("avr-unknown-unknown", avr_unknown_unknown),
584+
582585
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
583586

584587
("aarch64-unknown-redox", aarch64_unknown_redox),

src/rustllvm/PassWrapper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ void LLVMRustAddLastExtensionPasses(
203203
#define SUBTARGET_AARCH64
204204
#endif
205205

206+
#ifdef LLVM_COMPONENT_AVR
207+
#define SUBTARGET_AVR SUBTARGET(AVR)
208+
#else
209+
#define SUBTARGET_AVR
210+
#endif
211+
206212
#ifdef LLVM_COMPONENT_MIPS
207213
#define SUBTARGET_MIPS SUBTARGET(Mips)
208214
#else
@@ -249,6 +255,7 @@ void LLVMRustAddLastExtensionPasses(
249255
SUBTARGET_X86 \
250256
SUBTARGET_ARM \
251257
SUBTARGET_AARCH64 \
258+
SUBTARGET_AVR \
252259
SUBTARGET_MIPS \
253260
SUBTARGET_PPC \
254261
SUBTARGET_SYSTEMZ \

src/test/ui/codemap_tests/unicode.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
44
LL | extern "路濫狼á́́" fn foo() {}
55
| ^^^^^^^^^ invalid ABI
66
|
7-
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
7+
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
88

99
error: aborting due to previous error
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Test that the AVR interrupt ABI cannot be used when avr_interrupt
2+
// feature gate is not used.
3+
4+
extern "avr-interrupt" fn foo() {}
5+
//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
6+
7+
fn main() {
8+
foo();
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
2+
--> $DIR/feature-gate-abi-avr-interrupt.rs:4:8
3+
|
4+
LL | extern "avr-interrupt" fn foo() {}
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
8+
= help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/parser/issue-8537.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
44
LL | "invalid-ab_isize"
55
| ^^^^^^^^^^^^^^^^^^ invalid ABI
66
|
7-
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
7+
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
88

99
error: aborting due to previous error
1010

src/test/ui/symbol-names/basic.legacy.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: symbol-name(_ZN5basic4main17h81759b0695851718E)
1+
error: symbol-name(_ZN5basic4main17h7bbff4a01206d8c2E)
22
--> $DIR/basic.rs:8:1
33
|
44
LL | #[rustc_symbol_name]
55
| ^^^^^^^^^^^^^^^^^^^^
66

7-
error: demangling(basic::main::h81759b0695851718)
7+
error: demangling(basic::main::h7bbff4a01206d8c2)
88
--> $DIR/basic.rs:8:1
99
|
1010
LL | #[rustc_symbol_name]

0 commit comments

Comments
 (0)