Skip to content

aarch64: dit target feature cannot be reliably en/disabled from assembly #146866

Open
@folkertdev

Description

@folkertdev

The rust graviola crate defines this function

#[target_feature(enable = "dit")]
unsafe fn write(on: u32) {
    if on > 0 {
        // SAFETY: `msr DIT, _` is defined only if `dit` cpu feature is supported
        unsafe { core::arch::asm!("msr DIT, #1") }
    } else {
        // SAFETY: `msr DIT, _` is defined only if `dit` cpu feature is supported
        unsafe { core::arch::asm!("msr DIT, #0") }
    }
}

The target_feature annotation makes the msr DIT instructions work inside the body. In a function without that annotation, LLVM would error.

But, it currently appears to be impossible to write this function reliably using global inline assembly. The standard mechanism doesn't work:

std::arch::global_asm!(".arch_extension dit");

errors with

error: unsupported architectural extension: dit
  |
note: instantiated into assembly here
 --> <inline asm>:1:17
  |
1 | .arch_extension dit
  |                 ^

One way we've found to make the code compile is to use .arch

#[unsafe(naked)]
unsafe extern "C" fn write() {
    core::arch::naked_asm!(
        ".arch armv8.4-a",
        "msr DIT, #0",
        "ret"
    ) 
}

However .arch has no stack-like mechanism to "pop" a state and return to a previous one. Hence, .arch cannot be used reliably. Actually even .arch_extension doesn't have such a mechanism. Many other targets do.

So, can LLVM provide a reliable way to toggle this target feature from inline assembly, preferably something like what riscv and powerpc do with a stack of features. s390x recently added support for a similar mechanism #129053.

see also rust-lang/rust#137720 for examples of how other targets deal with toggling target features in assembly. This concrete problem came up in rust-lang/rustc_codegen_cranelift#1586

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions