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 cf8fe4e082ac3..d995554913f84 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 5b6e953484369..252a6316e574b 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 ffd741a7b37b0..a7b0c9cf81be6 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 8e9c5f25ccb71..099c402703d09 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 759c2bf1b85f4..d37cce56fc6fa 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 fd35cb6c3f785..fc64727ad6272 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 e97fa4345fe7c..ada48bc147e47 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 eca1808de3f90..79e1a6cc5dcdb 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 e93abd3390a2d..f5bca90c2bd52 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 d165409696eca..fea5880f01ebd 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 0000000000000..f681302bc0319 --- /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 0303312d057fe..8f7e2bba5aa6d 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 226fe0b8bc69b..a5c874bb4ac05 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 0000000000000..c951c980e2a02 --- /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 f329c8c06cc2e..833beee3bd4f3 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 0000000000000..5402ea074fae1 --- /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 97c20ca9459ef..0354f7850f5bf 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 02dcfb8e82952..3d252fe70afeb 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 0000000000000..0d7df8182c458 --- /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 0000000000000..023b6121784f7 --- /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 c61bee0f8d9ea..e1c3042edb80f 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 ecc70adda4111..777284ca5c096 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 4d4440fd07f22..8b85adb58453f 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 9ff28ce51e047..e33adb239d78d 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 fc64727ad6272..b4935236b6a97 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 023b6121784f7..be7040e1491fe 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 31d991e0c2f87..f7355433463d6 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 e1c3042edb80f..ca36a15ffc7de 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 0354f7850f5bf..97c20ca9459ef 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 c951c980e2a02..f90a8def0aa2f 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 833beee3bd4f3..29250f21383be 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 f681302bc0319..c1f7a1e3af586 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); } }