From 690bb8af510c0cf4099eac512127948180dbc792 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 6 May 2016 09:32:10 -0400 Subject: [PATCH 1/9] [AVR] Add AVR platform support --- config.toml.example | 2 +- src/bootstrap/native.rs | 2 +- src/librustc_ast_passes/feature_gate.rs | 8 +++++ src/librustc_codegen_llvm/abi.rs | 2 ++ src/librustc_codegen_llvm/llvm/ffi.rs | 2 ++ src/librustc_feature/active.rs | 3 ++ src/librustc_llvm/build.rs | 1 + src/librustc_llvm/lib.rs | 8 +++++ src/librustc_middle/ty/layout.rs | 2 ++ src/librustc_span/symbol.rs | 1 + src/librustc_target/abi/call/avr.rs | 33 +++++++++++++++++++ src/librustc_target/abi/call/mod.rs | 4 +++ src/librustc_target/spec/abi.rs | 8 +++++ .../spec/avr_unknown_unknown.rs | 17 ++++++++++ src/librustc_target/spec/mod.rs | 3 ++ src/librustc_target/spec/none_base.rs | 30 +++++++++++++++++ src/libstd/env.rs | 6 ++++ src/rustllvm/PassWrapper.cpp | 7 ++++ .../feature-gate-abi-avr-interrupt.rs | 9 +++++ .../feature-gate-abi-avr-interrupt.stderr | 11 +++++++ src/tools/compiletest/src/util.rs | 1 + 21 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/librustc_target/abi/call/avr.rs create mode 100644 src/librustc_target/spec/avr_unknown_unknown.rs create mode 100644 src/librustc_target/spec/none_base.rs create mode 100644 src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs create mode 100644 src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr diff --git a/config.toml.example b/config.toml.example index cf8fe4e082a..d995554913f 100644 --- a/config.toml.example +++ b/config.toml.example @@ -69,7 +69,7 @@ # the same format as above, but since these targets are experimental, they are # not built by default and the experimental Rust compilation targets that depend # on them will not work unless the user opts in to building them. -#experimental-targets = "" +#experimental-targets = "AVR" # Cap the number of parallel linker invocations when compiling LLVM. # This can be useful when building LLVM with debug info, which significantly diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 5b6e9534843..252a6316e57 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -144,7 +144,7 @@ impl Step for Llvm { let llvm_exp_targets = match builder.config.llvm_experimental_targets { Some(ref s) => s, - None => "", + None => "AVR", }; let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" }; diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index ffd741a7b37..a7b0c9cf81b 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -121,6 +121,14 @@ impl<'a> PostExpansionVisitor<'a> { "amdgpu-kernel ABI is experimental and subject to change" ); } + "avr-interrupt" | "avr-non-blocking-interrupt" => { + gate_feature_post!( + &self, + abi_avr_interrupt, + span, + "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change" + ); + } "efiapi" => { gate_feature_post!( &self, diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 8e9c5f25ccb..099c402703d 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -375,6 +375,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { match self.conv { Conv::C | Conv::Rust => llvm::CCallConv, Conv::AmdGpuKernel => llvm::AmdGpuKernel, + Conv::AvrInterrupt => llvm::AvrInterrupt, + Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt, Conv::ArmAapcs => llvm::ArmAapcsCallConv, Conv::Msp430Intr => llvm::Msp430Intr, Conv::PtxKernel => llvm::PtxKernel, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 759c2bf1b85..d37cce56fc6 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -45,6 +45,8 @@ pub enum CallConv { X86_64_Win64 = 79, X86_VectorCall = 80, X86_Intr = 83, + AvrNonBlockingInterrupt = 84, + AvrInterrupt = 85, AmdGpuKernel = 91, } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index fd35cb6c3f7..fc64727ad62 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -347,6 +347,9 @@ declare_features! ( /// Allows `extern "msp430-interrupt" fn()`. (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), + /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. + (active, abi_avr_interrupt, "1.41.0", None, None), + /// Allows declarative macros 2.0 (`macro`). (active, decl_macro, "1.17.0", Some(39412), None), diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index e97fa4345fe..ada48bc147e 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -78,6 +78,7 @@ fn main() { "arm", "aarch64", "amdgpu", + "avr", "mips", "powerpc", "systemz", diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index eca1808de3f..79e1a6cc5dc 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -76,6 +76,14 @@ pub fn initialize_available_targets() { LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeAMDGPUAsmParser ); + init_target!( + llvm_component = "avr", + LLVMInitializeAVRTargetInfo, + LLVMInitializeAVRTarget, + LLVMInitializeAVRTargetMC, + LLVMInitializeAVRAsmPrinter, + LLVMInitializeAVRAsmParser + ); init_target!( llvm_component = "mips", LLVMInitializeMipsTargetInfo, diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index e93abd3390a..f5bca90c2bd 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -2529,6 +2529,8 @@ where Msp430Interrupt => Conv::Msp430Intr, X86Interrupt => Conv::X86Intr, AmdGpuKernel => Conv::AmdGpuKernel, + AvrInterrupt => Conv::AvrInterrupt, + AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, // These API constants ought to be more specific... Cdecl => Conv::C, diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index d165409696e..fea5880f01e 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -120,6 +120,7 @@ symbols! { abi_unadjusted, abi_vectorcall, abi_x86_interrupt, + abi_avr_interrupt, abort, aborts, address, diff --git a/src/librustc_target/abi/call/avr.rs b/src/librustc_target/abi/call/avr.rs new file mode 100644 index 00000000000..f681302bc03 --- /dev/null +++ b/src/librustc_target/abi/call/avr.rs @@ -0,0 +1,33 @@ +#![allow(non_upper_case_globals)] + +use crate::abi::call::{ArgAbi, FnAbi}; + +fn classify_ret_ty(ret: &mut ArgAbi<'_, Ty>) { + if ret.layout.is_aggregate() { + ret.make_indirect(); + } else { + ret.extend_integer_width_to(8); // Is 8 correct? + } +} + +fn classify_arg_ty(arg: &mut ArgAbi<'_, Ty>) { + if arg.layout.is_aggregate() { + arg.make_indirect(); + } else { + arg.extend_integer_width_to(8); + } +} + +pub fn compute_abi_info(fty: &mut FnAbi<'_, Ty>) { + if !fty.ret.is_ignore() { + classify_ret_ty(&mut fty.ret); + } + + for arg in &mut fty.args { + if arg.is_ignore() { + continue; + } + + classify_arg_ty(arg); + } +} diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 0303312d057..8f7e2bba5aa 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -5,6 +5,7 @@ use crate::spec::{self, HasTargetSpec}; mod aarch64; mod amdgpu; mod arm; +mod avr; mod hexagon; mod mips; mod mips64; @@ -525,6 +526,8 @@ pub enum Conv { X86_64Win64, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, } /// Metadata describing how the arguments to a native function @@ -580,6 +583,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "aarch64" => aarch64::compute_abi_info(cx, self), "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), + "avr" => avr::compute_abi_info(self), "mips" => mips::compute_abi_info(cx, self), "mips64" => mips64::compute_abi_info(cx, self), "powerpc" => powerpc::compute_abi_info(self), diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs index 226fe0b8bc6..a5c874bb4ac 100644 --- a/src/librustc_target/spec/abi.rs +++ b/src/librustc_target/spec/abi.rs @@ -34,6 +34,8 @@ pub enum Abi { X86Interrupt, AmdGpuKernel, EfiApi, + AvrInterrupt, + AvrNonBlockingInterrupt, // Multiplatform / generic ABIs System, @@ -73,6 +75,12 @@ const AbiDatas: &[AbiData] = &[ AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false }, AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false }, + AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false }, + AbiData { + abi: Abi::AvrNonBlockingInterrupt, + name: "avr-non-blocking-interrupt", + generic: false, + }, // Cross-platform ABIs AbiData { abi: Abi::System, name: "system", generic: true }, AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true }, diff --git a/src/librustc_target/spec/avr_unknown_unknown.rs b/src/librustc_target/spec/avr_unknown_unknown.rs new file mode 100644 index 00000000000..c951c980e2a --- /dev/null +++ b/src/librustc_target/spec/avr_unknown_unknown.rs @@ -0,0 +1,17 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "avr-unknown-unknown".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "16".to_string(), + data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(), + arch: "avr".to_string(), + linker_flavor: LinkerFlavor::Gcc, + target_os: "unknown".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + target_c_int_width: 16.to_string(), + options: super::none_base::opts(), + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f329c8c06cc..833beee3bd4 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -65,6 +65,7 @@ mod linux_kernel_base; mod linux_musl_base; mod msvc_base; mod netbsd_base; +mod none_base; mod openbsd_base; mod redox_base; mod riscv_base; @@ -579,6 +580,8 @@ supported_targets! { ("aarch64-fuchsia", aarch64_fuchsia), ("x86_64-fuchsia", x86_64_fuchsia), + ("avr-unknown-unknown", avr_unknown_unknown), + ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), ("aarch64-unknown-redox", aarch64_unknown_redox), diff --git a/src/librustc_target/spec/none_base.rs b/src/librustc_target/spec/none_base.rs new file mode 100644 index 00000000000..5402ea074fa --- /dev/null +++ b/src/librustc_target/spec/none_base.rs @@ -0,0 +1,30 @@ +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use std::default::Default; + +pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + + args.insert( + LinkerFlavor::Gcc, + vec![ + // We want to be able to strip as much executable code as possible + // from the linker command line, and this flag indicates to the + // linker that it can avoid linking in dynamic libraries that don't + // actually satisfy any symbols up to that point (as with many other + // resolutions the linker does). This option only applies to all + // following libraries so we're sure to pass it as one of the first + // arguments. + "-Wl,--as-needed".to_string(), + ], + ); + + TargetOptions { + dynamic_linking: false, + executables: true, + linker_is_gnu: true, + has_rpath: false, + pre_link_args: args, + position_independent_executables: false, + ..Default::default() + } +} diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 97c20ca9459..0354f7850f5 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -874,6 +874,7 @@ pub mod consts { /// - x86_64 /// - arm /// - aarch64 + /// - avr /// - mips /// - mips64 /// - powerpc @@ -986,6 +987,11 @@ mod arch { pub const ARCH: &str = "aarch64"; } +#[cfg(target_arch = "avr")] +mod arch { + pub const ARCH: &'static str = "avr"; +} + #[cfg(target_arch = "mips")] mod arch { pub const ARCH: &str = "mips"; diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 02dcfb8e829..3d252fe70af 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -203,6 +203,12 @@ void LLVMRustAddLastExtensionPasses( #define SUBTARGET_AARCH64 #endif +#ifdef LLVM_COMPONENT_AVR +#define SUBTARGET_AVR SUBTARGET(AVR) +#else +#define SUBTARGET_AVR +#endif + #ifdef LLVM_COMPONENT_MIPS #define SUBTARGET_MIPS SUBTARGET(Mips) #else @@ -249,6 +255,7 @@ void LLVMRustAddLastExtensionPasses( SUBTARGET_X86 \ SUBTARGET_ARM \ SUBTARGET_AARCH64 \ + SUBTARGET_AVR \ SUBTARGET_MIPS \ SUBTARGET_PPC \ SUBTARGET_SYSTEMZ \ diff --git a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs new file mode 100644 index 00000000000..0d7df8182c4 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -0,0 +1,9 @@ +// Test that the AVR interrupt ABI cannot be used when avr_interrupt +// feature gate is not used. + +extern "avr-interrupt" fn foo() {} +//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change + +fn main() { + foo(); +} diff --git a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr new file mode 100644 index 00000000000..023b6121784 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr @@ -0,0 +1,11 @@ +error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-avr-interrupt.rs:14:1 + | +LL | extern "avr-interrupt" fn foo() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(abi_avr_interrupt)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index c61bee0f8d9..e1c3042edb8 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -47,6 +47,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("armv7", "arm"), ("armv7s", "arm"), ("asmjs", "asmjs"), + ("avr", "avr"), ("hexagon", "hexagon"), ("i386", "x86"), ("i586", "x86"), From 91bff8ccdfddd119a2239e625bfb52703844f227 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Sun, 9 Jun 2019 01:57:40 +1200 Subject: [PATCH 2/9] [AVR] Fix debug printing of function pointers This commit fixes debug printing of function pointers on AVR. AVR does not support `addrspacecast` instructions, and so this patch modifies libcore so that a `ptrtoint` IR instruction is used and the address space cast is avoided. --- src/libcore/ptr/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index ecc70adda41..777284ca5c0 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -1345,14 +1345,24 @@ macro_rules! fnptr_impls_safety_abi { #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Pointer for $FnTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&(*self as *const ()), f) + // HACK: The intermediate cast as usize is required for AVR + // so that the address space of the source function pointer + // is preserved in the final function pointer. + // + // https://github.com/avr-rust/rust/issues/143 + fmt::Pointer::fmt(&(*self as usize as *const ()), f) } } #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Debug for $FnTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&(*self as *const ()), f) + // HACK: The intermediate cast as usize is required for AVR + // so that the address space of the source function pointer + // is preserved in the final function pointer. + // + // https://github.com/avr-rust/rust/issues/143 + fmt::Pointer::fmt(&(*self as usize as *const ()), f) } } } From 13edc57bfa9362ed04d930da3ff267756497cec4 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Tue, 3 Mar 2020 19:36:26 +1300 Subject: [PATCH 3/9] [AVR] Add required references for AVR to the parser test suites --- src/test/ui/codemap_tests/unicode.stderr | 2 +- src/test/ui/parser/issue-8537.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 4d4440fd07f..8b85adb5845 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́` LL | extern "路濫狼á́́" fn foo() {} | ^^^^^^^^^ invalid ABI | - = help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted + = help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted error: aborting due to previous error diff --git a/src/test/ui/parser/issue-8537.stderr b/src/test/ui/parser/issue-8537.stderr index 9ff28ce51e0..e33adb239d7 100644 --- a/src/test/ui/parser/issue-8537.stderr +++ b/src/test/ui/parser/issue-8537.stderr @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize` LL | "invalid-ab_isize" | ^^^^^^^^^^^^^^^^^^ invalid ABI | - = help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted + = help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted error: aborting due to previous error From edc344e8e992c30aa8274db986ced3659147b1a1 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Tue, 3 Mar 2020 21:05:17 +1300 Subject: [PATCH 4/9] [AVR] Raise and link to a tracking issue for the `avr-interrupt` calling convention Also fix the order of the feature gate to fix the tidy errors. --- src/librustc_feature/active.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index fc64727ad62..b4935236b6a 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -347,9 +347,6 @@ declare_features! ( /// Allows `extern "msp430-interrupt" fn()`. (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), - /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. - (active, abi_avr_interrupt, "1.41.0", None, None), - /// Allows declarative macros 2.0 (`macro`). (active, decl_macro, "1.17.0", Some(39412), None), @@ -577,6 +574,9 @@ declare_features! ( /// No longer treat an unsafe function as an unsafe block. (active, unsafe_block_in_unsafe_fn, "1.45.0", Some(71668), None), + /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. + (active, abi_avr_interrupt, "1.45.0", Some(69664), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- From e369cf6b27257eef0c1e64d9e20b32abc98b784b Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Wed, 4 Mar 2020 17:07:45 +1300 Subject: [PATCH 5/9] [AVR] Re-bless the UI tests Patch generated with `./x.py test --stage 1 src/test/ui/feature-gates --bless`. --- .../ui/feature-gates/feature-gate-abi-avr-interrupt.stderr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr index 023b6121784..be7040e1491 100644 --- a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr @@ -1,10 +1,11 @@ error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:14:1 + --> $DIR/feature-gate-abi-avr-interrupt.rs:4:8 | LL | extern "avr-interrupt" fn foo() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_avr_interrupt)] to the crate attributes to enable + = note: see issue #69664 for more information + = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable error: aborting due to previous error From b4a041c0502f2880c875c3dd2155ccc3b98be301 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Thu, 5 Mar 2020 13:18:51 +1300 Subject: [PATCH 6/9] [AVR] Update the compiletest library to recognize AVR as a 16-bit target --- src/tools/compiletest/src/header/tests.rs | 6 ++++++ src/tools/compiletest/src/util.rs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 31d991e0c2f..f7355433463 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -27,6 +27,12 @@ fn test_parse_normalization_string() { let first = parse_normalization_string(&mut s); assert_eq!(first, Some("something (32 bits)".to_owned())); assert_eq!(s, " -> \"something ($WORD bits)."); + + // Nothing to normalize (No quotes, 16-bit) + let mut s = "normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)."; + let first = parse_normalization_string(&mut s); + assert_eq!(first, None); + assert_eq!(s, r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)."#); } fn config() -> Config { diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index e1c3042edb8..ca36a15ffc7 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -115,6 +115,8 @@ pub fn matches_env(triple: &str, name: &str) -> bool { pub fn get_pointer_width(triple: &str) -> &'static str { if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") { "64bit" + } else if triple.starts_with("avr") { + "16bit" } else { "32bit" } From 8ba9cbd5c0a1eed971f1019f1853f6e7d6f71273 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Wed, 1 Apr 2020 20:39:09 +1300 Subject: [PATCH 7/9] [AVR] Remove AVR-specific logic from libstd It is not possible to compile libstd for AVR anyway. --- src/libstd/env.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 0354f7850f5..97c20ca9459 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -874,7 +874,6 @@ pub mod consts { /// - x86_64 /// - arm /// - aarch64 - /// - avr /// - mips /// - mips64 /// - powerpc @@ -987,11 +986,6 @@ mod arch { pub const ARCH: &str = "aarch64"; } -#[cfg(target_arch = "avr")] -mod arch { - pub const ARCH: &'static str = "avr"; -} - #[cfg(target_arch = "mips")] mod arch { pub const ARCH: &str = "mips"; From 1f0652ff67dc477227b48a3ccb3d398e0c492909 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Wed, 1 Apr 2020 20:51:05 +1300 Subject: [PATCH 8/9] [AVR] Rename the 'none_base' target spec module to 'freestanding_base' --- src/librustc_target/spec/avr_unknown_unknown.rs | 2 +- src/librustc_target/spec/{none_base.rs => freestanding_base.rs} | 0 src/librustc_target/spec/mod.rs | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/librustc_target/spec/{none_base.rs => freestanding_base.rs} (100%) diff --git a/src/librustc_target/spec/avr_unknown_unknown.rs b/src/librustc_target/spec/avr_unknown_unknown.rs index c951c980e2a..f90a8def0aa 100644 --- a/src/librustc_target/spec/avr_unknown_unknown.rs +++ b/src/librustc_target/spec/avr_unknown_unknown.rs @@ -12,6 +12,6 @@ pub fn target() -> TargetResult { target_env: "".to_string(), target_vendor: "unknown".to_string(), target_c_int_width: 16.to_string(), - options: super::none_base::opts(), + options: super::freestanding_base::opts(), }) } diff --git a/src/librustc_target/spec/none_base.rs b/src/librustc_target/spec/freestanding_base.rs similarity index 100% rename from src/librustc_target/spec/none_base.rs rename to src/librustc_target/spec/freestanding_base.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 833beee3bd4..29250f21383 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -54,6 +54,7 @@ mod arm_base; mod cloudabi_base; mod dragonfly_base; mod freebsd_base; +mod freestanding_base; mod fuchsia_base; mod haiku_base; mod hermit_base; @@ -65,7 +66,6 @@ mod linux_kernel_base; mod linux_musl_base; mod msvc_base; mod netbsd_base; -mod none_base; mod openbsd_base; mod redox_base; mod riscv_base; From 0340359b2a3e9af1cd94cbf7831f8b77b9bf77a1 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Sun, 17 May 2020 16:36:23 +1200 Subject: [PATCH 9/9] [AVR] Update ABI type classification logic to match the the AVR-Clang ABI This patch brings the AVR calling convention argument classification logic in line with AVR Clang's behaviour. AVR-Clang currently uses the `clang::DefaultABIInfo` ABI implementation. This calling convention promotes all aggregates to indirect, no matter their size. It is also unnecessary to perform any integer width extension for AVR as the minimum argument size matches the minimum describable size of abi::Primitive::Int - 8 bits. At some point in the future, an AVR-GCC compatible argument classification implementation should be adopted in both Clang and Rust. --- src/librustc_target/abi/call/avr.rs | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/librustc_target/abi/call/avr.rs b/src/librustc_target/abi/call/avr.rs index f681302bc03..c1f7a1e3af5 100644 --- a/src/librustc_target/abi/call/avr.rs +++ b/src/librustc_target/abi/call/avr.rs @@ -1,20 +1,46 @@ -#![allow(non_upper_case_globals)] +//! LLVM-frontend specific AVR calling convention implementation. +//! +//! # Current calling convention ABI +//! +//! Inherited from Clang's `clang::DefaultABIInfo` implementation - self described +//! as +//! +//! > the default implementation for ABI specific details. This implementation +//! > provides information which results in +//! > self-consistent and sensible LLVM IR generation, but does not +//! > conform to any particular ABI. +//! > +//! > - Doxygen Doxumentation of `clang::DefaultABIInfo` +//! +//! This calling convention may not match AVR-GCC in all cases. +//! +//! In the future, an AVR-GCC compatible argument classification ABI should be +//! adopted in both Rust and Clang. +//! +//! *NOTE*: Currently, this module implements the same calling convention +//! that clang with AVR currently does - the default, simple, unspecialized +//! ABI implementation available to all targets. This ABI is not +//! binary-compatible with AVR-GCC. Once LLVM [PR46140](https://bugs.llvm.org/show_bug.cgi?id=46140) +//! is completed, this module should be updated to match so that both Clang +//! and Rust emit code to the same AVR-GCC compatible ABI. +//! +//! In particular, both Clang and Rust may not have the same semantics +//! when promoting arguments to indirect references as AVR-GCC. It is important +//! to note that the core AVR ABI implementation within LLVM itself is ABI +//! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount +//! of compiler frontend specific calling convention logic implemented here. use crate::abi::call::{ArgAbi, FnAbi}; fn classify_ret_ty(ret: &mut ArgAbi<'_, Ty>) { if ret.layout.is_aggregate() { ret.make_indirect(); - } else { - ret.extend_integer_width_to(8); // Is 8 correct? } } fn classify_arg_ty(arg: &mut ArgAbi<'_, Ty>) { if arg.layout.is_aggregate() { arg.make_indirect(); - } else { - arg.extend_integer_width_to(8); } }