Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a generic AVR target: avr-unknown-unknown #131651

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1920,10 +1920,20 @@ fn add_post_link_objects(

/// Add arbitrary "pre-link" args defined by the target spec or from command line.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
fn add_pre_link_args(
cmd: &mut dyn Linker,
sess: &Session,
flavor: LinkerFlavor,
codegen_results: &CodegenResults,
) {
if let Some(args) = sess.target.pre_link_args.get(&flavor) {
cmd.verbatim_args(args.iter().map(Deref::deref));
}

if sess.target.arch == "avr" {
cmd.verbatim_arg(format!("-mmcu={}", codegen_results.crate_info.target_cpu));
}

cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args);
}

Expand Down Expand Up @@ -2215,7 +2225,7 @@ fn linker_with_args(
// FIXME: In practice built-in target specs use this for arbitrary order-independent options,
// introduce a target spec option for order-independent linker options and migrate built-in
// specs to it.
add_pre_link_args(cmd, sess, flavor);
add_pre_link_args(cmd, sess, flavor, codegen_results);

// ------------ Object code and libraries, order-dependent ------------

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,5 @@
use object::elf;

use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};

/// A base target for AVR devices using the GNU toolchain.
///
/// Requires GNU avr-gcc and avr-binutils on the host system.
/// FIXME: Remove the second parameter when const string concatenation is possible.
pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: None,
host_tools: None,
std: None,
},
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
llvm_target: "avr-unknown-unknown".into(),
pointer_width: 16,
options: TargetOptions {
env: "gnu".into(),

c_int_width: "16".into(),
cpu: target_cpu.into(),
exe_suffix: ".elf".into(),

linker: Some("avr-gcc".into()),
eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
"-lgcc",
]),
max_atomic_width: Some(16),
atomic_cas: false,
relocation_model: RelocModel::Static,
..TargetOptions::default()
},
}
}

/// Resolve the value of the EF_AVR_ARCH field for AVR ELF files, given the
/// name of the target CPU / MCU.
///
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/base/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub(crate) mod aix;
pub(crate) mod android;
pub(crate) mod apple;
pub(crate) mod avr_gnu;
pub(crate) mod avr;
pub(crate) mod bpf;
pub(crate) mod dragonfly;
pub(crate) mod freebsd;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub use base::apple::{
deployment_target_for_target as current_apple_deployment_target,
platform as current_apple_platform,
};
pub use base::avr_gnu::ef_avr_arch;
pub use base::avr::ef_avr_arch;

/// Linker is called through a C/C++ compiler.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -1734,7 +1734,7 @@ supported_targets! {
("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia),
("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),

("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328),
("avr-unknown-unknown", avr_unknown_unknown),

("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),

Expand Down

This file was deleted.

30 changes: 30 additions & 0 deletions compiler/rustc_target/src/spec/targets/avr_unknown_unknown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};

pub(crate) fn target() -> Target {
Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: None,
host_tools: None,
std: None,
},
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
llvm_target: "avr-unknown-unknown".into(),
pointer_width: 16,
options: TargetOptions {
c_int_width: "16".into(),
exe_suffix: ".elf".into(),
linker: Some("avr-gcc".into()),
eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[]),
late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
"-lgcc",
]),
max_atomic_width: Some(16),
atomic_cas: false,
relocation_model: RelocModel::Static,
..TargetOptions::default()
},
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/tests/tests_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Target {
&self.post_link_args,
] {
for (&flavor, flavor_args) in args {
assert!(!flavor_args.is_empty());
Patryk27 marked this conversation as resolved.
Show resolved Hide resolved
assert!(!flavor_args.is_empty() || self.arch == "avr");
// Check that flavors mentioned in link args are compatible with the default flavor.
match self.linker_flavor {
LinkerFlavor::Gnu(..) => {
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ target | std | host | notes
[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS
[`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS
[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat
`avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core`
`avr-unknown-unknown` | * | | AVR
`bpfeb-unknown-none` | * | | BPF (big endian)
`bpfel-unknown-none` | * | | BPF (little endian)
`csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian)
Expand Down
78 changes: 78 additions & 0 deletions src/doc/rustc/src/platform-support/avr-unknown-unknown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# `avr-unknown-unknown`

Series of microcontrollers from Atmel: ATmega8, ATmega328p etc.

**Tier: 3**

## Target maintainers

-[Patryk Wychowaniec](https://github.com/Patryk27) <pwychowaniec@pm.me>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
-[Patryk Wychowaniec](https://github.com/Patryk27) <pwychowaniec@pm.me>
- [Patryk Wychowaniec](https://github.com/Patryk27) <pwychowaniec@pm.me>


## Requirements

This target is only cross-compiled; x86\_64 Linux, x86\_64 MacOS and aarch64
MacOS hosts are confirmed to work, but in principle any machine able to run
Comment on lines +13 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
This target is only cross-compiled; x86\_64 Linux, x86\_64 MacOS and aarch64
MacOS hosts are confirmed to work, but in principle any machine able to run
This target is only cross-compiled; x86\_64 Linux, x86\_64 macOS and Aarch64
macOS hosts are confirmed to work, but in principle any machine able to run

rustc and avr-gcc should be good.

Compiling for this target requires `avr-gcc`, because a couple of intrinsics
(like 32-bit multiplication) rely on [`libgcc`](https://github.com/gcc-mirror/gcc/blob/3269a722b7a03613e9c4e2862bc5088c4a17cc11/libgcc/config/avr/lib1funcs.S)
and can't be provided through `compiler-builtins` yet. This is a limitation that
[we hope to lift in the future](https://github.com/rust-lang/compiler-builtins/issues/711).

## Building the target

Rust comes with AVR support enabled, you don't have to rebuild the compiler.

## Building Rust programs

Install `avr-gcc`:

```console
# Ubuntu:
$ sudo apt-get install gcc-avr

# Mac:
$ brew tap osx-cross/avr && brew install avr-gcc

# NixOS (takes a couple of minutes, since Hydra doesn't build it):
$ nix shell nixpkgs#pkgsCross.avr.buildPackages.gcc11
```

... setup `.cargo/config` for your project:

```toml
[build]
target = "avr-unknown-unknown"
rustflags = ["-C", "target-cpu=atmega328p"]
Patryk27 marked this conversation as resolved.
Show resolved Hide resolved

[unstable]
build-std = ["core"]
```

... and then simply run:

```console
$ cargo build --release
```

The final binary will be placed into
`./target/avr-unknown-unknown/release/your-project.elf`.

Note that since AVRs have rather small amounts of registers, ROM and RAM, it's
recommended to always use `--release` to avoid running out of space.

### Supported microcontrollers (target-cpu)

https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32

## Testing

You can use [`simavr`](https://github.com/buserror/simavr) to emulate the
resulting firmware on your machine:

```console
$ simavr -m atmega328p ./target/avr-unknown-unknown/release/your-project.elf
```

Alternatively, if you want to write a couple of actual `#[test]`s, you can use
[`avr-tester`](https://github.com/Patryk27/avr-tester).
3 changes: 3 additions & 0 deletions src/tools/compiletest/src/header/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,10 @@ fn profiler_runtime() {
#[test]
fn asm_support() {
let asms = [
#[cfg(bootstrap)]
("avr-unknown-gnu-atmega328", false),
#[cfg(not(bootstrap))]
("avr-unknown-unknown", false),
("i686-unknown-netbsd", true),
("riscv32gc-unknown-linux-gnu", true),
("riscv64imac-unknown-none-elf", true),
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/asm/avr-modifiers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ assembly-output: emit-asm
//@ compile-flags: --target avr-unknown-gnu-atmega328
//@ compile-flags: --target avr-unknown-unknown -C target-cpu=atmega328p
//@ needs-llvm-components: avr

#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/asm/avr-types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ assembly-output: emit-asm
//@ compile-flags: --target avr-unknown-gnu-atmega328
//@ compile-flags: --target avr-unknown-unknown -C target-cpu=atmega328p
//@ needs-llvm-components: avr

#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
Expand Down
6 changes: 3 additions & 3 deletions tests/assembly/targets/targets-pe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
//@ revisions: arm64ec_pc_windows_msvc
//@ [arm64ec_pc_windows_msvc] compile-flags: --target arm64ec-pc-windows-msvc
//@ [arm64ec_pc_windows_msvc] needs-llvm-components: aarch64
//@ revisions: avr_unknown_gnu_atmega328
//@ [avr_unknown_gnu_atmega328] compile-flags: --target avr-unknown-gnu-atmega328
//@ [avr_unknown_gnu_atmega328] needs-llvm-components: avr
//@ revisions: avr_unknown_unknown
//@ [avr_unknown_unknown] compile-flags: --target avr-unknown-unknown -C target-cpu=atmega328p
//@ [avr_unknown_unknown] needs-llvm-components: avr
//@ revisions: bpfeb_unknown_none
//@ [bpfeb_unknown_none] compile-flags: --target bpfeb-unknown-none
//@ [bpfeb_unknown_none] needs-llvm-components: bpf
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ compile-flags: -O --target=avr-unknown-gnu-atmega328 --crate-type=rlib -C panic=abort
//@ compile-flags: -O --target=avr-unknown-unknown -C target-cpu=atmega328p --crate-type=rlib -C panic=abort
//@ needs-llvm-components: avr

// This test validates that function pointers can be stored in global variables
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ needs-llvm-components: avr
//@ compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
//@ compile-flags: --target=avr-unknown-unknown -C target-cpu=atmega328p --crate-type=rlib
#![no_core]
#![feature(no_core, lang_items)]
#[lang="sized"]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/repr/16-bit-repr-c-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@ revisions: avr msp430
//
//@ [avr] needs-llvm-components: avr
//@ [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
//@ [avr] compile-flags: --target=avr-unknown-unknown -C target-cpu=atmega328p --crate-type=rlib
//@ [msp430] needs-llvm-components: msp430
//@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib
#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)]
Expand Down
Loading