Skip to content

Commit 4bbe715

Browse files
committed
Create a generic AVR target: avr-none
This commit removes the `avr-unknown-gnu-atmega328` target and replaces it with a more generic `avr-none` variant that must be specialized with the `-C target-cpu` flag (e.g. `-C target-cpu=atmega328p`).
1 parent 9e48dfe commit 4bbe715

File tree

17 files changed

+146
-61
lines changed

17 files changed

+146
-61
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,10 +1986,20 @@ fn add_post_link_objects(
19861986

19871987
/// Add arbitrary "pre-link" args defined by the target spec or from command line.
19881988
/// FIXME: Determine where exactly these args need to be inserted.
1989-
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
1989+
fn add_pre_link_args(
1990+
cmd: &mut dyn Linker,
1991+
sess: &Session,
1992+
flavor: LinkerFlavor,
1993+
codegen_results: &CodegenResults,
1994+
) {
19901995
if let Some(args) = sess.target.pre_link_args.get(&flavor) {
19911996
cmd.verbatim_args(args.iter().map(Deref::deref));
19921997
}
1998+
1999+
if sess.target.arch == "avr" {
2000+
cmd.verbatim_arg(format!("-mmcu={}", codegen_results.crate_info.target_cpu));
2001+
}
2002+
19932003
cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args);
19942004
}
19952005

@@ -2281,7 +2291,7 @@ fn linker_with_args(
22812291
// FIXME: In practice built-in target specs use this for arbitrary order-independent options,
22822292
// introduce a target spec option for order-independent linker options and migrate built-in
22832293
// specs to it.
2284-
add_pre_link_args(cmd, sess, flavor);
2294+
add_pre_link_args(cmd, sess, flavor, codegen_results);
22852295

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

compiler/rustc_target/src/spec/base/avr_gnu.rs renamed to compiler/rustc_target/src/spec/base/avr.rs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,5 @@
11
use object::elf;
22

3-
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
4-
5-
/// A base target for AVR devices using the GNU toolchain.
6-
///
7-
/// Requires GNU avr-gcc and avr-binutils on the host system.
8-
/// FIXME: Remove the second parameter when const string concatenation is possible.
9-
pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
10-
Target {
11-
arch: "avr".into(),
12-
metadata: crate::spec::TargetMetadata {
13-
description: None,
14-
tier: None,
15-
host_tools: None,
16-
std: None,
17-
},
18-
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
19-
llvm_target: "avr-unknown-unknown".into(),
20-
pointer_width: 16,
21-
options: TargetOptions {
22-
env: "gnu".into(),
23-
24-
c_int_width: "16".into(),
25-
cpu: target_cpu.into(),
26-
exe_suffix: ".elf".into(),
27-
28-
linker: Some("avr-gcc".into()),
29-
eh_frame_header: false,
30-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
31-
late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
32-
"-lgcc",
33-
]),
34-
max_atomic_width: Some(16),
35-
atomic_cas: false,
36-
relocation_model: RelocModel::Static,
37-
..TargetOptions::default()
38-
},
39-
}
40-
}
41-
423
/// Resolve the value of the EF_AVR_ARCH field for AVR ELF files, given the
434
/// name of the target CPU / MCU.
445
///

compiler/rustc_target/src/spec/base/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub(crate) mod aix;
22
pub(crate) mod android;
33
pub(crate) mod apple;
4-
pub(crate) mod avr_gnu;
4+
pub(crate) mod avr;
55
pub(crate) mod bpf;
66
pub(crate) mod dragonfly;
77
pub(crate) mod freebsd;

compiler/rustc_target/src/spec/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub mod abi {
6868
mod base;
6969
mod json;
7070

71-
pub use base::avr_gnu::ef_avr_arch;
71+
pub use base::avr::ef_avr_arch;
7272

7373
/// Linker is called through a C/C++ compiler.
7474
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -1766,7 +1766,7 @@ supported_targets! {
17661766
("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia),
17671767
("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
17681768

1769-
("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328),
1769+
("avr-none", avr_none),
17701770

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

@@ -3029,7 +3029,10 @@ impl Target {
30293029
&self.post_link_args,
30303030
] {
30313031
for (&flavor, flavor_args) in args {
3032-
check!(!flavor_args.is_empty(), "linker flavor args must not be empty");
3032+
check!(
3033+
!flavor_args.is_empty() || self.arch == "avr",
3034+
"linker flavor args must not be empty"
3035+
);
30333036
// Check that flavors mentioned in link args are compatible with the default flavor.
30343037
match self.linker_flavor {
30353038
LinkerFlavor::Gnu(..) => {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
2+
3+
pub(crate) fn target() -> Target {
4+
Target {
5+
arch: "avr".into(),
6+
metadata: crate::spec::TargetMetadata {
7+
description: None,
8+
tier: None,
9+
host_tools: None,
10+
std: None,
11+
},
12+
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
13+
llvm_target: "avr-unknown-unknown".into(),
14+
pointer_width: 16,
15+
options: TargetOptions {
16+
c_int_width: "16".into(),
17+
exe_suffix: ".elf".into(),
18+
linker: Some("avr-gcc".into()),
19+
eh_frame_header: false,
20+
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[]),
21+
late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
22+
"-lgcc",
23+
]),
24+
max_atomic_width: Some(16),
25+
atomic_cas: false,
26+
relocation_model: RelocModel::Static,
27+
need_explicit_cpu: true,
28+
..TargetOptions::default()
29+
},
30+
}
31+
}

compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/doc/rustc/src/platform-support.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ target | std | host | notes
300300
[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat
301301
[`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX
302302
[`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat
303-
`avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core`
303+
`avr-none` | * | | AVR. Requires `-Z build-std=core`
304304
`bpfeb-unknown-none` | * | | BPF (big endian)
305305
`bpfel-unknown-none` | * | | BPF (little endian)
306306
`csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# `avr-none`
2+
3+
Series of microcontrollers from Atmel: ATmega8, ATmega328p etc.
4+
5+
**Tier: 3**
6+
7+
## Target maintainers
8+
9+
- [Patryk Wychowaniec](https://github.com/Patryk27) <[email protected]>
10+
11+
## Requirements
12+
13+
This target is only cross-compiled; x86-64 Linux, x86-64 macOS and aarch64 macOS
14+
hosts are confirmed to work, but in principle any machine able to run rustc and
15+
avr-gcc should be good.
16+
17+
Compiling for this target requires `avr-gcc` installed, because a couple of
18+
intrinsics (like 32-bit multiplication) rely on [`libgcc`](https://github.com/gcc-mirror/gcc/blob/3269a722b7a03613e9c4e2862bc5088c4a17cc11/libgcc/config/avr/lib1funcs.S)
19+
and can't be provided through `compiler-builtins` yet. This is a limitation that
20+
[we hope to lift in the future](https://github.com/rust-lang/compiler-builtins/issues/711).
21+
22+
You'll also need to setup the `.cargo/config` file - see below for details.
23+
24+
## Building the target
25+
26+
Rust comes with AVR support enabled, you don't have to rebuild the compiler.
27+
28+
## Building Rust programs
29+
30+
Install `avr-gcc`:
31+
32+
```console
33+
# Ubuntu:
34+
$ sudo apt-get install gcc-avr
35+
36+
# Mac:
37+
$ brew tap osx-cross/avr && brew install avr-gcc
38+
39+
# NixOS (takes a couple of minutes, since it's not provided through Hydra):
40+
$ nix shell nixpkgs#pkgsCross.avr.buildPackages.gcc11
41+
```
42+
43+
... setup `.cargo/config` for your project:
44+
45+
```toml
46+
[build]
47+
target = "avr-none"
48+
rustflags = ["-C", "target-cpu=atmega328p"]
49+
50+
[unstable]
51+
build-std = ["core"]
52+
```
53+
54+
... and then simply run:
55+
56+
```console
57+
$ cargo build --release
58+
```
59+
60+
The final binary will be placed into
61+
`./target/avr-none/release/your-project.elf`.
62+
63+
Note that since AVRs have rather small amounts of registers, ROM and RAM, it's
64+
recommended to always use `--release` to avoid running out of space.
65+
66+
Also, please note that specifying `-C target-cpu` is required - here's a list of
67+
the possible variants:
68+
69+
https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32
70+
71+
## Testing
72+
73+
You can use [`simavr`](https://github.com/buserror/simavr) to emulate the
74+
resulting firmware on your machine:
75+
76+
```console
77+
$ simavr -m atmega328p ./target/avr-none/release/your-project.elf
78+
```
79+
80+
Alternatively, if you want to write a couple of actual `#[test]`s, you can use
81+
[`avr-tester`](https://github.com/Patryk27/avr-tester).

src/tools/compiletest/src/header/tests.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,10 @@ fn profiler_runtime() {
456456
#[test]
457457
fn asm_support() {
458458
let asms = [
459+
#[cfg(bootstrap)]
459460
("avr-unknown-gnu-atmega328", false),
461+
#[cfg(not(bootstrap))]
462+
("avr-none", false),
460463
("i686-unknown-netbsd", true),
461464
("riscv32gc-unknown-linux-gnu", true),
462465
("riscv64imac-unknown-none-elf", true),

tests/assembly/asm/avr-modifiers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ add-core-stubs
22
//@ assembly-output: emit-asm
3-
//@ compile-flags: --target avr-unknown-gnu-atmega328
3+
//@ compile-flags: --target avr-none -C target-cpu=atmega328p
44
//@ needs-llvm-components: avr
55

66
#![feature(no_core, asm_experimental_arch)]

0 commit comments

Comments
 (0)