diff --git a/config.toml.example b/config.toml.example index c14adf8ce33c7..ac8c1955feb42 100644 --- a/config.toml.example +++ b/config.toml.example @@ -64,7 +64,7 @@ # 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. By default the # `WebAssembly` and `RISCV` targets are enabled when compiling LLVM from scratch. -#experimental-targets = "WebAssembly;RISCV" +#experimental-targets = "AVR;WebAssembly;RISCV" # 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/config.rs b/src/bootstrap/config.rs index 66f504ea924e9..90d309af09d7b 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -525,7 +525,7 @@ impl Config { set(&mut config.llvm_link_shared, llvm.link_shared); config.llvm_targets = llvm.targets.clone(); config.llvm_experimental_targets = llvm.experimental_targets.clone() - .unwrap_or_else(|| "WebAssembly;RISCV".to_string()); + .unwrap_or_else(|| "AVR;WebAssembly;RISCV".to_string()); config.llvm_link_jobs = llvm.link_jobs; config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index e0c01277801d4..04c8d81317cee 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -106,6 +106,8 @@ impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi { Msp430Interrupt, X86Interrupt, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, Rust, C, System, diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 8e2c3dd3d8ad9..e178213cabd0c 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2389,6 +2389,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_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 38d4b7e3f9d85..5214272ae6ae6 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -371,6 +371,8 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { match self.conv { Conv::C => 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 a71243c7c826b..e4314e3520b19 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -43,6 +43,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_llvm/build.rs b/src/librustc_llvm/build.rs index 7fa83dd977950..dd7237948f6d0 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -70,7 +70,7 @@ fn main() { let is_crossed = target != host; let mut optional_components = - vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", + vec!["x86", "arm", "aarch64", "amdgpu", "avr", "mips", "powerpc", "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; let mut version_cmd = Command::new(&llvm_config); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 292ce8b0a01b0..4b26bca109363 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -41,6 +41,12 @@ pub fn initialize_available_targets() { LLVMInitializeARMTargetMC, LLVMInitializeARMAsmPrinter, LLVMInitializeARMAsmParser); + init_target!(llvm_component = "avr", + LLVMInitializeAVRTargetInfo, + LLVMInitializeAVRTarget, + LLVMInitializeAVRTargetMC, + LLVMInitializeAVRAsmPrinter, + LLVMInitializeAVRAsmParser); init_target!(llvm_component = "aarch64", LLVMInitializeAArch64TargetInfo, LLVMInitializeAArch64Target, diff --git a/src/librustc_target/abi/call/avr.rs b/src/librustc_target/abi/call/avr.rs new file mode 100644 index 0000000000000..060834e12222b --- /dev/null +++ b/src/librustc_target/abi/call/avr.rs @@ -0,0 +1,43 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] + +use crate::abi::call::{FnType, ArgType}; + +fn classify_ret_ty(ret: &mut ArgType<'_, 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 ArgType<'_, Ty>) { + if arg.layout.is_aggregate() { + arg.make_indirect(); + } else { + arg.extend_integer_width_to(8); + } +} + +pub fn compute_abi_info(fty: &mut FnType<'_, 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 fbbd120f934be..84101d526923a 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -6,6 +6,7 @@ mod aarch64; mod amdgpu; mod arm; mod asmjs; +mod avr; mod hexagon; mod mips; mod mips64; @@ -516,6 +517,8 @@ pub enum Conv { X86_64Win64, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, } /// Metadata describing how the arguments to a native function @@ -573,6 +576,7 @@ impl<'a, Ty> FnType<'a, Ty> { wasm32::compute_abi_info(self) } } + "avr" => avr::compute_abi_info(self), "msp430" => msp430::compute_abi_info(self), "sparc" => sparc::compute_abi_info(cx, self), "sparc64" => sparc64::compute_abi_info(cx, self), diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs index c9c41f1092240..96e6ff67d7e02 100644 --- a/src/librustc_target/spec/abi.rs +++ b/src/librustc_target/spec/abi.rs @@ -18,6 +18,8 @@ pub enum Abi { Msp430Interrupt, X86Interrupt, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, // Multiplatform / generic ABIs Rust, @@ -55,6 +57,9 @@ const AbiDatas: &[AbiData] = &[ AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, AbiData {abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", 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::Rust, name: "Rust", 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..4b6fe30b9e53a --- /dev/null +++ b/src/librustc_target/spec/avr_unknown_unknown.rs @@ -0,0 +1,27 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +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 844edbb946a51..8d2ce58fddf3c 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -54,6 +54,7 @@ mod haiku_base; mod hermit_base; mod linux_base; mod linux_musl_base; +mod none_base; mod openbsd_base; mod netbsd_base; mod solaris_base; @@ -411,6 +412,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), ("x86_64-unknown-redox", x86_64_unknown_redox), @@ -496,7 +499,7 @@ pub struct Target { /// Vendor name to use for conditional compilation. pub target_vendor: String, /// Architecture to use for ABI considerations. Valid options: "x86", - /// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64". + /// "x86_64", "arm", "aarch64", "avr", "mips", "powerpc", and "powerpc64". pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, diff --git a/src/librustc_target/spec/none_base.rs b/src/librustc_target/spec/none_base.rs new file mode 100644 index 0000000000000..3ffc4d7b271f0 --- /dev/null +++ b/src/librustc_target/spec/none_base.rs @@ -0,0 +1,37 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::default::Default; +use crate::spec::{LinkerFlavor, LinkArgs, TargetOptions}; + +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: true, + .. Default::default() + } +} diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 00e840a53e9c0..a5247c8de18c4 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -819,6 +819,7 @@ pub mod consts { /// - x86_64 /// - arm /// - aarch64 + /// - avr /// - mips /// - mips64 /// - powerpc @@ -930,6 +931,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/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b41b91c7631f5..ef9979b18e909 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -401,6 +401,9 @@ declare_features! ( // Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), + // `extern "avr-interrupt" fn()` + (active, abi_avr_interrupt, "1.18.0", Some(000), None), + // Allows module-level inline assembly by way of `global_asm!()`. (active, global_asm, "1.18.0", Some(35119), None), @@ -1838,6 +1841,11 @@ impl<'a> PostExpansionVisitor<'a> { Abi::X86Interrupt => { gate_feature_post!(&self, abi_x86_interrupt, span, "x86-interrupt ABI is experimental and subject to change"); + } + Abi::AvrInterrupt | Abi::AvrNonBlockingInterrupt => { + gate_feature_post!(&self, abi_avr_interrupt, span, + "avr-interrupt and avr-non-blocking-interrupt ABIs are \ + experimental and subject to change"); }, Abi::AmdGpuKernel => { gate_feature_post!(&self, abi_amdgpu_kernel, span, diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 49123e4cc30c2..cacb76887be54 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -116,6 +116,7 @@ symbols! { abi_unadjusted, abi_vectorcall, abi_x86_interrupt, + abi_avr_interrupt, aborts, advanced_slice_patterns, adx_target_feature, diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 0ebef82d37680..03de617cf7075 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -117,6 +117,12 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager( #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 @@ -163,6 +169,7 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager( 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..806bff25e7dd8 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// 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 8caf5ca00f505..d7e3edbd02435 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -24,6 +24,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("mingw32", "windows"), ("none", "none"), ("netbsd", "netbsd"), + ("none", "none"), ("openbsd", "openbsd"), ("redox", "redox"), ("sgx", "sgx"), @@ -42,6 +43,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("armv7", "arm"), ("armv7s", "arm"), ("asmjs", "asmjs"), + ("avr", "avr"), ("hexagon", "hexagon"), ("i386", "x86"), ("i586", "x86"),