Rollup merge of #150863 - ferrocene:add-aarch64v8r-targets, r=wesleywiser

Adds two new Tier 3 targets - `aarch64v8r-unknown-none{,-softfloat}`

## New Tier 3 targets - `aarch64v8r-unknown-none` and `aarch64v8r-unknown-none-softfloat`

This PR adds two new Tier 3 targets - `aarch64v8r-unknown-none` and `aarch64v8r-unknown-none-softfloat`.

The existing `aarch64-unknown-none` target assumes Armv8.0-A as a baseline. However, Arm recently released the Arm Cortex-R82 processor which is the first to implement the Armv8-R AArch64 mode architecture. This architecture is similar to Armv8-A AArch64, however it has a different set of mandatory features, and is based off of Armv8.4. It is largely unrelated to the existing Armv8-R architecture target (`armv8r-none-eabihf`), which only operates in AArch32 mode.

The second `aarch64v8r-unknown-none-softfloat` target allows for possible Armv8-R AArch64 CPUs with no FPU, or for use-cases where FPU register stacking is not desired. As with the existing `aarch64-unknown-none` target we have coupled FPU support and Neon support together - there is no 'has FPU but does not have NEON' target proposed even though the architecture technically allows for it.

These targets are in support of firmware development on upcoming systems using the Arm Cortex-R82, particularly safety-critical firmware development. For now, it can be tested using the Arm's Armv8-R AArch64 Fixed Virtual Platform emulator, which we have used to test this target. We are also in the process of testing this target with the full compiler test suite as part of Ferrocene, in the same way we test `aarch64-unknown-none` to a safety-qualified standard. We have not identified any issues as yet, but if we do, we will send the fixes upstream to you.

## Ownership

This PR was developed by Ferrous Systems on behalf of Arm. Arm is the owner of these changes.

## Tier 3 Policy Notes

To cover off the Tier 3 requirements:

> A tier 3 target must have a designated developer or developers

Arm will maintain this target, and I have presumed the Embedded Devices Working Group will also take an interest, as they maintain the existing Arm bare-metal targets.

> Targets must use naming consistent with any existing targets

We prefix this target with `aarch64` because it generates A64 machine code (like `arm*` generates A32 and `thumb*` generates T32). In an ideal world I'd get to rename the existing target `aarch64v8a-unknown-none` but that's basically impossible at this point. You can assume `v6` for any `arm*` target where unspecified, and you can assume `v8a` for any `aarch64*` target where not specified.

> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.

It works just like the existing AArch64 bare-metal target.

> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.

Noted.

> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate.

It's a bare-metal target, offering libcore and liballoc.

> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible.

Done

> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target.

AArch64 is a Tier 1 architecture, so I don't expect this target to cause any issues.

> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.

Noted.

> Tier 3 targets must be able to produce assembly using at least one of rustc's supported backends from any host target.

It's AArch64 and so works with LLVM.
This commit is contained in:
Stuart Cook 2026-01-27 12:50:51 +11:00 committed by GitHub
commit db654cb421
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 401 additions and 15 deletions

View file

@ -1709,6 +1709,8 @@ supported_targets! {
("aarch64-unknown-none-softfloat", aarch64_unknown_none_softfloat),
("aarch64_be-unknown-none-softfloat", aarch64_be_unknown_none_softfloat),
("aarch64-unknown-nuttx", aarch64_unknown_nuttx),
("aarch64v8r-unknown-none", aarch64v8r_unknown_none),
("aarch64v8r-unknown-none-softfloat", aarch64v8r_unknown_none_softfloat),
("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),

View file

@ -0,0 +1,37 @@
use crate::spec::{
Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target,
TargetMetadata, TargetOptions,
};
pub(crate) fn target() -> Target {
let opts = TargetOptions {
// based off the aarch64-unknown-none target at time of addition
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
stack_probes: StackProbeType::Inline,
panic_strategy: PanicStrategy::Abort,
default_uwtable: true,
// deviations from aarch64-unknown-none: `+v8a` -> `+v8r`; `+v8r` implies `+neon`
features: "+v8r,+strict-align".into(),
..Default::default()
};
Target {
llvm_target: "aarch64-unknown-none".into(),
metadata: TargetMetadata {
description: Some("Bare Armv8-R AArch64, hardfloat".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 64,
// $ clang-21 -S -emit-llvm -target aarch64 -mcpu=cortex-r82 stub.c
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: Arch::AArch64,
options: opts,
}
}

View file

@ -0,0 +1,36 @@
use crate::spec::{
Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType,
Target, TargetMetadata, TargetOptions,
};
pub(crate) fn target() -> Target {
let opts = TargetOptions {
abi: Abi::SoftFloat,
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
stack_probes: StackProbeType::Inline,
panic_strategy: PanicStrategy::Abort,
default_uwtable: true,
// deviations from aarch64-unknown-none: `+v8a` -> `+v8r`
features: "+v8r,+strict-align,-neon".into(),
..Default::default()
};
Target {
llvm_target: "aarch64-unknown-none".into(),
metadata: TargetMetadata {
description: Some("Bare Armv8-R AArch64, softfloat".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 64,
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: Arch::AArch64,
options: opts,
}
}

View file

@ -46,6 +46,8 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
"armv6-none-eabi",
"armv6-none-eabihf",
"thumbv6-none-eabi",
"aarch64v8r-unknown-none",
"aarch64v8r-unknown-none-softfloat",
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM

View file

@ -50,6 +50,7 @@
- [aarch64-unknown-linux-gnu](platform-support/aarch64-unknown-linux-gnu.md)
- [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md)
- [aarch64-unknown-none*](platform-support/aarch64-unknown-none.md)
- [aarch64v8r-unknown-none*](platform-support/aarch64v8r-unknown-none.md)
- [aarch64_be-unknown-none-softfloat](platform-support/aarch64_be-unknown-none-softfloat.md)
- [aarch64_be-unknown-linux-musl](platform-support/aarch64_be-unknown-linux-musl.md)
- [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)

View file

@ -275,6 +275,8 @@ target | std | host | notes
[`aarch64-unknown-trusty`](platform-support/trusty.md) | ✓ | |
[`aarch64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | |
[`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS
[`aarch64v8r-unknown-none`](platform-support/aarch64v8r-unknown-none.md) | * | | Bare Armv8-R in AArch64 mode, hardfloat
[`aarch64v8r-unknown-none-softfloat`](platform-support/aarch64v8r-unknown-none.md) | * | | Bare Armv8-R in AArch64 mode, softfloat
[`aarch64_be-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit (big-endian)
`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)

View file

@ -0,0 +1,84 @@
# `aarch64v8r-unknown-none` and `aarch64v8r-unknown-none-softfloat`
* **Tier: 3**
* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
Bare-metal target for CPUs in the Armv8-R architecture family, running in
AArch64 mode. Processors in this family include the
[Arm Cortex-R82][cortex-r82].
For Armv8-R CPUs running in AArch32 mode (such as the Arm Cortex-R52), see
[`armv8r-none-eabihf`](armv8r-none-eabihf.md) instead.
[cortex-r82]: https://developer.arm.com/processors/Cortex-R82
## Target maintainers
- [Rust Embedded Devices Working Group Arm Team]
- [@rust-lang/arm-maintainers][arm_maintainers] ([rust@arm.com][arm_email])
[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team
[arm_maintainers]: https://github.com/rust-lang/team/blob/master/teams/arm-maintainers.toml
[arm_email]: mailto:rust@arm.com
## Target CPU and Target Feature options
Unlike AArch64 v8-A processors, not all AArch64 v8-R processors include an FPU
(that is, not all Armv8-R AArch64 processors implement the optional Armv8
`FEAT_FP` extension). If you do not have an FPU, or have an FPU but wish to use
a soft-float ABI anyway, you should use the `aarch64v8r-unknown-none-softfloat`
target. If you wish to use the standard hard-float Arm AArch64 calling
convention, and you have an FPU, you can use the `aarch64v8r-unknown-none`
target.
When using the `aarch64v8r-unknown-none` target, the minimum floating-point
features assumed are the Advanced SIMD features (`FEAT_AdvSIMD`, or `+neon`),
the implementation of which is branded Arm NEON.
If your processor supports a different set of floating-point features than the
default expectations then these should also be enabled or disabled as needed
with [`-C target-feature=(+/-)`][target-feature]. However, note that currently
Rust does not support building hard-float AArch64 targets with Advanced SIMD
support disabled. It is also possible to tell Rust (or LLVM) that you have a
specific model of Arm processor, using the [`-Ctarget-cpu`][target-cpu] option.
Doing so may change the default set of target-features enabled.
[target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature
[target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu
## Requirements
These targets are cross-compiled and use static linking.
By default, the `lld` linker included with Rust will be used; however, you may
want to use the GNU linker instead. This can be obtained for Windows/Mac/Linux
from the [Arm Developer Website][arm-gnu-toolchain], or possibly from your OS's
package manager. To use it, add the following to your `.cargo/config.toml`:
```toml
[target.aarch64-unknown-none]
linker = "aarch64-none-elf-ld"
```
The GNU linker can also be used by specifying `aarch64-none-elf-gcc` as the
linker. This is needed when using GCC's link time optimization.
These targets don't provide a linker script, so you'll need to bring your own
according to the specific device you are using. Pass
`-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use
`your_script.ld` during linking.
[arm-gnu-toolchain]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain
## Cross-compilation toolchains and C code
This target supports C code compiled with the `aarch64-none-elf` target
triple and a suitable `-march` or `-mcpu` flag.
## Start-up and Low-Level Code
The [Rust Embedded Devices Working Group Arm Team] maintain the
[`aarch64-cpu`] crate, which may be useful for writing bare-metal code using
this target.
[`aarch64-cpu`]: https://docs.rs/aarch64-cpu

View file

@ -15,6 +15,9 @@ and [Cortex-R52+][cortex-r52-plus].
See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
`arm-none-eabi` targets.
For Armv8-R CPUs running in AArch64 mode (such as the Arm Cortex-R82), see
[`aarch64v8r-unknown-none`](aarch64v8r-unknown-none.md) instead.
[cortex-r52]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52
[cortex-r52-plus]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52-plus

View file

@ -98,7 +98,7 @@ fn arch_to_llvm_component(arch: &str) -> String {
// enough for the purpose of this tidy check.
match arch {
"amdgcn" => "amdgpu".into(),
"aarch64_be" | "arm64_32" | "arm64e" | "arm64ec" => "aarch64".into(),
"aarch64v8r" | "aarch64_be" | "arm64_32" | "arm64e" | "arm64ec" => "aarch64".into(),
"i386" | "i586" | "i686" | "x86" | "x86_64" | "x86_64h" => "x86".into(),
"loongarch32" | "loongarch64" => "loongarch".into(),
"nvptx64" => "nvptx".into(),

View file

@ -67,6 +67,12 @@
//@ revisions: aarch64_unknown_none_softfloat
//@ [aarch64_unknown_none_softfloat] compile-flags: --target aarch64-unknown-none-softfloat
//@ [aarch64_unknown_none_softfloat] needs-llvm-components: aarch64
//@ revisions: aarch64v8r_unknown_none
//@ [aarch64v8r_unknown_none] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r_unknown_none] needs-llvm-components: aarch64
//@ revisions: aarch64v8r_unknown_none_softfloat
//@ [aarch64v8r_unknown_none_softfloat] compile-flags: --target aarch64v8r-unknown-none-softfloat
//@ [aarch64v8r_unknown_none_softfloat] needs-llvm-components: aarch64
//@ revisions: aarch64_unknown_nto_qnx700
//@ [aarch64_unknown_nto_qnx700] compile-flags: --target aarch64-unknown-nto-qnx700
//@ [aarch64_unknown_nto_qnx700] needs-llvm-components: aarch64

View file

@ -0,0 +1,45 @@
//@ add-minicore
//@ compile-flags: --target aarch64v8r-unknown-none-softfloat -Zmerge-functions=disabled
//@ needs-llvm-components: aarch64
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]
extern crate minicore;
use minicore::*;
// CHECK: i64 @pass_f64_C(i64 {{[^,]*}})
#[no_mangle]
extern "C" fn pass_f64_C(x: f64) -> f64 {
x
}
// CHECK: i64 @pass_f32_pair_C(i64 {{[^,]*}})
#[no_mangle]
extern "C" fn pass_f32_pair_C(x: (f32, f32)) -> (f32, f32) {
x
}
// CHECK: [2 x i64] @pass_f64_pair_C([2 x i64] {{[^,]*}})
#[no_mangle]
extern "C" fn pass_f64_pair_C(x: (f64, f64)) -> (f64, f64) {
x
}
// CHECK: i64 @pass_f64_Rust(i64 {{[^,]*}})
#[no_mangle]
fn pass_f64_Rust(x: f64) -> f64 {
x
}
// CHECK: i64 @pass_f32_pair_Rust(i64 {{[^,]*}})
#[no_mangle]
fn pass_f32_pair_Rust(x: (f32, f32)) -> (f32, f32) {
x
}
// CHECK: void @pass_f64_pair_Rust(ptr {{.*}}%{{[^ ]+}}, ptr {{.*}}%{{[^ ]+}})
#[no_mangle]
fn pass_f64_pair_Rust(x: (f64, f64)) -> (f64, f64) {
x
}

View file

@ -2,9 +2,11 @@
//@ add-minicore
//@ compile-flags: -Zsanitizer=kernel-address -Copt-level=0
//@ revisions: aarch64 riscv64imac riscv64gc x86_64
//@ revisions: aarch64 aarch64v8r riscv64imac riscv64gc x86_64
//@[aarch64] compile-flags: --target aarch64-unknown-none
//@[aarch64] needs-llvm-components: aarch64
//@[aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@[aarch64v8r] needs-llvm-components: aarch64
//@[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf
//@[riscv64imac] needs-llvm-components: riscv
//@[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf

View file

@ -1,9 +1,11 @@
// Verifies that "cfi-normalize-integers" module flag is added.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers

View file

@ -1,9 +1,11 @@
// Verifies that "kcfi" module flag is added.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi

View file

@ -1,9 +1,11 @@
// Verifies that "kcfi-offset" module flag is added.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Z patchable-function-entry=4,3

View file

@ -1,9 +1,11 @@
// Verifies that KCFI operand bundles are omitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0

View file

@ -1,9 +1,11 @@
// Verifies that generalized KCFI type metadata for functions are emitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-generalize-pointers

View file

@ -1,9 +1,11 @@
// Verifies that normalized and generalized KCFI type metadata for functions are emitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers

View file

@ -1,9 +1,11 @@
// Verifies that normalized KCFI type metadata for functions are emitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers

View file

@ -1,9 +1,11 @@
// Verifies that KCFI type metadata for functions are emitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0

View file

@ -1,9 +1,11 @@
// Verifies that KCFI operand bundles are emitted.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0

View file

@ -1,9 +1,11 @@
// Verifies that type metadata identifiers for trait objects are emitted correctly.
//
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64v8r aarch64 x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0

View file

@ -1,7 +1,9 @@
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0

View file

@ -1,7 +1,9 @@
//@ add-minicore
//@ revisions: aarch64 x86_64
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0

View file

@ -3,9 +3,11 @@
//
//@ add-minicore
//@ compile-flags: -Zsanitizer=kernel-address -Ctarget-feature=-crt-static -Copt-level=0
//@ revisions: aarch64 riscv64imac riscv64gc x86_64
//@ revisions: aarch64 aarch64v8r riscv64imac riscv64gc x86_64
//@[aarch64] compile-flags: --target aarch64-unknown-none
//@[aarch64] needs-llvm-components: aarch64
//@[aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@[aarch64v8r] needs-llvm-components: aarch64
//@[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf
//@[riscv64imac] needs-llvm-components: riscv
//@[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf

140
tests/ui/asm/aarch64v8r.rs Normal file
View file

@ -0,0 +1,140 @@
// Codegen test of mandatory Armv8-R AArch64 extensions
//@ add-minicore
//@ revisions: hf sf
//@ [hf] compile-flags: --target aarch64v8r-unknown-none
//@ [hf] needs-llvm-components: aarch64
//@ [sf] compile-flags: --target aarch64v8r-unknown-none-softfloat
//@ [sf] needs-llvm-components: aarch64
//@ build-pass
//@ ignore-backends: gcc
#![feature(no_core)]
#![no_core]
#![no_main]
#![crate_type = "rlib"]
#![deny(dead_code)] // ensures we call all private functions from the public one
extern crate minicore;
use minicore::*;
/* # Mandatory extensions
*
* A comment indicates that the extension has no associated assembly instruction and cannot be
* codegen tested
*
* ## References:
*
* - Arm Architecture Reference Manual for R-profile AArch64 architecture (DDI 0628) -- has the
* list of mandatory extensions
* - Arm Architecture Reference Manual for A-profile architecture (ARM DDI 0487) -- has the
* mapping from features to instructions
* - Feature names in A-profile architecture (109697_0100_02_en Version 1.0) -- overview of
* what each extension mean
* */
pub fn mandatory_extensions() {
/* ## ARMv8.0 */
feat_aa64();
// FEAT_AA64EL0
// FEAT_AA64EL1
// FEAT_AA64EL2
feat_crc32();
// FEAT_EL0
// FEAT_EL1
// FEAT_EL2
// FEAT_IVIPT
/* ## ARMv8.1 */
// FEAT_HPDS
feat_lse();
feat_pan();
/* ## ARMv8.2 */
feat_asmv8p2();
feat_dpb();
// FEAT_Debugv8p2
// FEAT_PAN2
feat_ras();
// FEAT_TTCNP
feat_uao();
// FEAT_XNX
/* ## ARMv8.3 */
feat_lrcpc();
feat_pauth();
/* ## ARMv8.4 */
feat_dit();
// FEAT_Debugv8p4
feat_flagm();
// FEAT_IDST
feat_lrcpc2();
// FEAT_LSE2
// FEAT_S2FWB
feat_tlbios();
feat_tlbirange();
// FEAT_TTL
}
fn feat_aa64() {
// CurrentEL register only present when FEAT_AA64 is implemented
unsafe { asm!("mrs x0, CurrentEL") }
}
fn feat_crc32() {
// instruction is present when FEAT_CRC32 is implemented
unsafe { asm!("crc32b w0, w1, w2") }
}
fn feat_lse() {
// instruction is present when FEAT_LSE is implemented
unsafe { asm!("casp w0, w1, w2, w3, [x4]") }
}
fn feat_pan() {
unsafe { asm!("mrs x0, PAN") }
}
fn feat_asmv8p2() {
unsafe { asm!("BFC w0, #0, #1") }
}
fn feat_dpb() {
unsafe { asm!("DC CVAP, x0") }
}
fn feat_ras() {
unsafe { asm!("ESB") }
}
fn feat_uao() {
unsafe { asm!("mrs x0, UAO") }
}
fn feat_lrcpc() {
unsafe { asm!("ldaprb w0, [x1]") }
}
fn feat_pauth() {
unsafe { asm!("xpacd x0") }
}
fn feat_dit() {
unsafe { asm!("mrs x0, DIT") }
}
fn feat_flagm() {
unsafe { asm!("cfinv") }
}
fn feat_lrcpc2() {
unsafe { asm!("stlurb w0, [x1]") }
}
fn feat_tlbios() {
unsafe { asm!("tlbi VMALLE1OS") }
}
fn feat_tlbirange() {
unsafe { asm!("tlbi RVAE1IS, x0") }
}