mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
[AVR] Add AVR platform support
This commit is contained in:
parent
5d39f1fa29
commit
690bb8af51
@ -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
|
||||
|
@ -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" };
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -45,6 +45,8 @@ pub enum CallConv {
|
||||
X86_64_Win64 = 79,
|
||||
X86_VectorCall = 80,
|
||||
X86_Intr = 83,
|
||||
AvrNonBlockingInterrupt = 84,
|
||||
AvrInterrupt = 85,
|
||||
AmdGpuKernel = 91,
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
||||
|
@ -78,6 +78,7 @@ fn main() {
|
||||
"arm",
|
||||
"aarch64",
|
||||
"amdgpu",
|
||||
"avr",
|
||||
"mips",
|
||||
"powerpc",
|
||||
"systemz",
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -120,6 +120,7 @@ symbols! {
|
||||
abi_unadjusted,
|
||||
abi_vectorcall,
|
||||
abi_x86_interrupt,
|
||||
abi_avr_interrupt,
|
||||
abort,
|
||||
aborts,
|
||||
address,
|
||||
|
33
src/librustc_target/abi/call/avr.rs
Normal file
33
src/librustc_target/abi/call/avr.rs
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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 },
|
||||
|
17
src/librustc_target/spec/avr_unknown_unknown.rs
Normal file
17
src/librustc_target/spec/avr_unknown_unknown.rs
Normal file
@ -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(),
|
||||
})
|
||||
}
|
@ -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),
|
||||
|
30
src/librustc_target/spec/none_base.rs
Normal file
30
src/librustc_target/spec/none_base.rs
Normal file
@ -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()
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
@ -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 \
|
||||
|
@ -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();
|
||||
}
|
@ -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`.
|
@ -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"),
|
||||
|
Loading…
Reference in New Issue
Block a user