Skip to content

Commit 043550d

Browse files
shepmasterdylanmckay
authored andcommitted
[AVR] Add AVR platform support
1 parent d71ae5e commit 043550d

File tree

21 files changed

+191
-4
lines changed

21 files changed

+191
-4
lines changed

config.toml.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
# not built by default and the experimental Rust compilation targets that depend
6565
# on them will not work unless the user opts in to building them. By default the
6666
# `WebAssembly` and `RISCV` targets are enabled when compiling LLVM from scratch.
67-
#experimental-targets = "WebAssembly;RISCV"
67+
#experimental-targets = "AVR;WebAssembly;RISCV"
6868

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

src/bootstrap/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ impl Config {
525525
set(&mut config.llvm_link_shared, llvm.link_shared);
526526
config.llvm_targets = llvm.targets.clone();
527527
config.llvm_experimental_targets = llvm.experimental_targets.clone()
528-
.unwrap_or_else(|| "WebAssembly;RISCV".to_string());
528+
.unwrap_or_else(|| "AVR;WebAssembly;RISCV".to_string());
529529
config.llvm_link_jobs = llvm.link_jobs;
530530
config.llvm_version_suffix = llvm.version_suffix.clone();
531531
config.llvm_clang_cl = llvm.clang_cl.clone();

src/librustc/ich/impls_syntax.rs

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
106106
Msp430Interrupt,
107107
X86Interrupt,
108108
AmdGpuKernel,
109+
AvrInterrupt,
110+
AvrNonBlockingInterrupt,
109111
Rust,
110112
C,
111113
System,

src/librustc/ty/layout.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,8 @@ where
23892389
Msp430Interrupt => Conv::Msp430Intr,
23902390
X86Interrupt => Conv::X86Intr,
23912391
AmdGpuKernel => Conv::AmdGpuKernel,
2392+
AvrInterrupt => Conv::AvrInterrupt,
2393+
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
23922394

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

src/librustc_codegen_llvm/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
371371
match self.conv {
372372
Conv::C => llvm::CCallConv,
373373
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
374+
Conv::AvrInterrupt => llvm::AvrInterrupt,
375+
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
374376
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
375377
Conv::Msp430Intr => llvm::Msp430Intr,
376378
Conv::PtxKernel => llvm::PtxKernel,

src/librustc_codegen_llvm/llvm/ffi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub enum CallConv {
4343
X86_64_Win64 = 79,
4444
X86_VectorCall = 80,
4545
X86_Intr = 83,
46+
AvrNonBlockingInterrupt = 84,
47+
AvrInterrupt = 85,
4648
AmdGpuKernel = 91,
4749
}
4850

src/librustc_llvm/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn main() {
7070
let is_crossed = target != host;
7171

7272
let mut optional_components =
73-
vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc",
73+
vec!["x86", "arm", "aarch64", "amdgpu", "avr", "mips", "powerpc",
7474
"systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"];
7575

7676
let mut version_cmd = Command::new(&llvm_config);

src/librustc_llvm/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ pub fn initialize_available_targets() {
4141
LLVMInitializeARMTargetMC,
4242
LLVMInitializeARMAsmPrinter,
4343
LLVMInitializeARMAsmParser);
44+
init_target!(llvm_component = "avr",
45+
LLVMInitializeAVRTargetInfo,
46+
LLVMInitializeAVRTarget,
47+
LLVMInitializeAVRTargetMC,
48+
LLVMInitializeAVRAsmPrinter,
49+
LLVMInitializeAVRAsmParser);
4450
init_target!(llvm_component = "aarch64",
4551
LLVMInitializeAArch64TargetInfo,
4652
LLVMInitializeAArch64Target,

src/librustc_target/abi/call/avr.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(non_upper_case_globals)]
12+
13+
use crate::abi::call::{FnType, ArgType};
14+
15+
fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
16+
if ret.layout.is_aggregate() {
17+
ret.make_indirect();
18+
} else {
19+
ret.extend_integer_width_to(8); // Is 8 correct?
20+
}
21+
}
22+
23+
fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
24+
if arg.layout.is_aggregate() {
25+
arg.make_indirect();
26+
} else {
27+
arg.extend_integer_width_to(8);
28+
}
29+
}
30+
31+
pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
32+
if !fty.ret.is_ignore() {
33+
classify_ret_ty(&mut fty.ret);
34+
}
35+
36+
for arg in &mut fty.args {
37+
if arg.is_ignore() {
38+
continue;
39+
}
40+
41+
classify_arg_ty(arg);
42+
}
43+
}

src/librustc_target/abi/call/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod aarch64;
66
mod amdgpu;
77
mod arm;
88
mod asmjs;
9+
mod avr;
910
mod hexagon;
1011
mod mips;
1112
mod mips64;
@@ -516,6 +517,8 @@ pub enum Conv {
516517
X86_64Win64,
517518

518519
AmdGpuKernel,
520+
AvrInterrupt,
521+
AvrNonBlockingInterrupt,
519522
}
520523

521524
/// Metadata describing how the arguments to a native function
@@ -573,6 +576,7 @@ impl<'a, Ty> FnType<'a, Ty> {
573576
wasm32::compute_abi_info(self)
574577
}
575578
}
579+
"avr" => avr::compute_abi_info(self),
576580
"msp430" => msp430::compute_abi_info(self),
577581
"sparc" => sparc::compute_abi_info(cx, self),
578582
"sparc64" => sparc64::compute_abi_info(cx, self),

src/librustc_target/spec/abi.rs

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub enum Abi {
1818
Msp430Interrupt,
1919
X86Interrupt,
2020
AmdGpuKernel,
21+
AvrInterrupt,
22+
AvrNonBlockingInterrupt,
2123

2224
// Multiplatform / generic ABIs
2325
Rust,
@@ -55,6 +57,9 @@ const AbiDatas: &[AbiData] = &[
5557
AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
5658
AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
5759
AbiData {abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
60+
AbiData {abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
61+
AbiData {abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt",
62+
generic: false },
5863

5964
// Cross-platform ABIs
6065
AbiData {abi: Abi::Rust, name: "Rust", generic: true },
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use crate::spec::{LinkerFlavor, Target, TargetResult};
12+
13+
pub fn target() -> TargetResult {
14+
Ok(Target {
15+
llvm_target: "avr-unknown-unknown".to_string(),
16+
target_endian: "little".to_string(),
17+
target_pointer_width: "16".to_string(),
18+
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(),
19+
arch: "avr".to_string(),
20+
linker_flavor: LinkerFlavor::Gcc,
21+
target_os: "unknown".to_string(),
22+
target_env: "".to_string(),
23+
target_vendor: "unknown".to_string(),
24+
target_c_int_width: 16.to_string(),
25+
options: super::none_base::opts(),
26+
})
27+
}

src/librustc_target/spec/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mod haiku_base;
5454
mod hermit_base;
5555
mod linux_base;
5656
mod linux_musl_base;
57+
mod none_base;
5758
mod openbsd_base;
5859
mod netbsd_base;
5960
mod solaris_base;
@@ -411,6 +412,8 @@ supported_targets! {
411412
("aarch64-fuchsia", aarch64_fuchsia),
412413
("x86_64-fuchsia", x86_64_fuchsia),
413414

415+
("avr-unknown-unknown", avr_unknown_unknown),
416+
414417
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
415418

416419
("x86_64-unknown-redox", x86_64_unknown_redox),
@@ -496,7 +499,7 @@ pub struct Target {
496499
/// Vendor name to use for conditional compilation.
497500
pub target_vendor: String,
498501
/// Architecture to use for ABI considerations. Valid options: "x86",
499-
/// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64".
502+
/// "x86_64", "arm", "aarch64", "avr", "mips", "powerpc", and "powerpc64".
500503
pub arch: String,
501504
/// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
502505
pub data_layout: String,

src/librustc_target/spec/none_base.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::default::Default;
12+
use crate::spec::{LinkerFlavor, LinkArgs, TargetOptions};
13+
14+
pub fn opts() -> TargetOptions {
15+
let mut args = LinkArgs::new();
16+
17+
args.insert(LinkerFlavor::Gcc, vec![
18+
// We want to be able to strip as much executable code as possible
19+
// from the linker command line, and this flag indicates to the
20+
// linker that it can avoid linking in dynamic libraries that don't
21+
// actually satisfy any symbols up to that point (as with many other
22+
// resolutions the linker does). This option only applies to all
23+
// following libraries so we're sure to pass it as one of the first
24+
// arguments.
25+
"-Wl,--as-needed".to_string(),
26+
]);
27+
28+
TargetOptions {
29+
dynamic_linking: false,
30+
executables: true,
31+
linker_is_gnu: true,
32+
has_rpath: false,
33+
pre_link_args: args,
34+
position_independent_executables: true,
35+
.. Default::default()
36+
}
37+
}

src/libstd/env.rs

+6
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ pub mod consts {
819819
/// - x86_64
820820
/// - arm
821821
/// - aarch64
822+
/// - avr
822823
/// - mips
823824
/// - mips64
824825
/// - powerpc
@@ -930,6 +931,11 @@ mod arch {
930931
pub const ARCH: &str = "aarch64";
931932
}
932933

934+
#[cfg(target_arch = "avr")]
935+
mod arch {
936+
pub const ARCH: &'static str = "avr";
937+
}
938+
933939
#[cfg(target_arch = "mips")]
934940
mod arch {
935941
pub const ARCH: &str = "mips";

src/libsyntax/feature_gate.rs

+8
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ declare_features! (
401401
// Allows `extern "x86-interrupt" fn()`.
402402
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
403403

404+
// `extern "avr-interrupt" fn()`
405+
(active, abi_avr_interrupt, "1.18.0", Some(000), None),
406+
404407
// Allows module-level inline assembly by way of `global_asm!()`.
405408
(active, global_asm, "1.18.0", Some(35119), None),
406409

@@ -1838,6 +1841,11 @@ impl<'a> PostExpansionVisitor<'a> {
18381841
Abi::X86Interrupt => {
18391842
gate_feature_post!(&self, abi_x86_interrupt, span,
18401843
"x86-interrupt ABI is experimental and subject to change");
1844+
}
1845+
Abi::AvrInterrupt | Abi::AvrNonBlockingInterrupt => {
1846+
gate_feature_post!(&self, abi_avr_interrupt, span,
1847+
"avr-interrupt and avr-non-blocking-interrupt ABIs are \
1848+
experimental and subject to change");
18411849
},
18421850
Abi::AmdGpuKernel => {
18431851
gate_feature_post!(&self, abi_amdgpu_kernel, span,

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ symbols! {
116116
abi_unadjusted,
117117
abi_vectorcall,
118118
abi_x86_interrupt,
119+
abi_avr_interrupt,
119120
aborts,
120121
advanced_slice_patterns,
121122
adx_target_feature,

src/rustllvm/PassWrapper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
117117
#define SUBTARGET_AARCH64
118118
#endif
119119

120+
#ifdef LLVM_COMPONENT_AVR
121+
#define SUBTARGET_AVR SUBTARGET(AVR)
122+
#else
123+
#define SUBTARGET_AVR
124+
#endif
125+
120126
#ifdef LLVM_COMPONENT_MIPS
121127
#define SUBTARGET_MIPS SUBTARGET(Mips)
122128
#else
@@ -163,6 +169,7 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
163169
SUBTARGET_X86 \
164170
SUBTARGET_ARM \
165171
SUBTARGET_AARCH64 \
172+
SUBTARGET_AVR \
166173
SUBTARGET_MIPS \
167174
SUBTARGET_PPC \
168175
SUBTARGET_SYSTEMZ \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the AVR interrupt ABI cannot be used when avr_interrupt
12+
// feature gate is not used.
13+
14+
extern "avr-interrupt" fn foo() {}
15+
//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
16+
17+
fn main() {
18+
foo();
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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:14:1
3+
|
4+
LL | extern "avr-interrupt" fn foo() {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: add #![feature(abi_avr_interrupt)] to the crate attributes to enable
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0658`.

src/tools/compiletest/src/util.rs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[
2424
("mingw32", "windows"),
2525
("none", "none"),
2626
("netbsd", "netbsd"),
27+
("none", "none"),
2728
("openbsd", "openbsd"),
2829
("redox", "redox"),
2930
("sgx", "sgx"),
@@ -42,6 +43,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
4243
("armv7", "arm"),
4344
("armv7s", "arm"),
4445
("asmjs", "asmjs"),
46+
("avr", "avr"),
4547
("hexagon", "hexagon"),
4648
("i386", "x86"),
4749
("i586", "x86"),

0 commit comments

Comments
 (0)