about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/librustc_ast_passes/feature_gate.rs8
-rw-r--r--src/librustc_codegen_llvm/abi.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs2
-rw-r--r--src/librustc_feature/active.rs3
-rw-r--r--src/librustc_llvm/build.rs1
-rw-r--r--src/librustc_llvm/lib.rs8
-rw-r--r--src/librustc_middle/ty/layout.rs2
-rw-r--r--src/librustc_span/symbol.rs1
-rw-r--r--src/librustc_target/abi/call/avr.rs33
-rw-r--r--src/librustc_target/abi/call/mod.rs4
-rw-r--r--src/librustc_target/spec/abi.rs8
-rw-r--r--src/librustc_target/spec/avr_unknown_unknown.rs17
-rw-r--r--src/librustc_target/spec/mod.rs3
-rw-r--r--src/librustc_target/spec/none_base.rs30
-rw-r--r--src/libstd/env.rs6
-rw-r--r--src/rustllvm/PassWrapper.cpp7
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs9
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr11
-rw-r--r--src/tools/compiletest/src/util.rs1
20 files changed, 157 insertions, 1 deletions
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
@@ -77,6 +77,14 @@ pub fn initialize_available_targets() {
         LLVMInitializeAMDGPUAsmParser
     );
     init_target!(
+        llvm_component = "avr",
+        LLVMInitializeAVRTargetInfo,
+        LLVMInitializeAVRTarget,
+        LLVMInitializeAVRTargetMC,
+        LLVMInitializeAVRAsmPrinter,
+        LLVMInitializeAVRAsmParser
+    );
+    init_target!(
         llvm_component = "mips",
         LLVMInitializeMipsTargetInfo,
         LLVMInitializeMipsTarget,
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<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<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<Ty>(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"),