<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/146866>146866</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            aarch64: `dit` target feature cannot be reliably en/disabled from assembly
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          folkertdev
      </td>
    </tr>
</table>

<pre>
    The rust [graviola](https://github.com/ctz/graviola/blob/3fe81f602eaf454e5e7fde18f6978913fabd18d5/graviola/src/low/aarch64/cpu.rs#L220-L229) crate defines this function

```rust
#[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 in inline assembly. The standard mechanism doesn't work: 

```rust
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`

```rust
#[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 https://github.com/llvm/llvm-project/issues/129053.

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

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUVkuP4rgT_zTmUmqUOOTBgQP9QDNSj_6HGf2lPbUcu0K87diR7cD0fvpVOUDTbO9Iqz0tYoBJyvX6PToiBL23iBtW3rPycSGm2Du_6Zx5RR8VHhatU2-bHz2Cn0IEVt7vvThoZwQrHxlv-hjHwIot4zvGd3sd-6ldSjcwvpPxD7p0Due71riW8V3RYZN3VcZRdKtyhSXWncK86ap13azzohOtyhtVfjwcvGR8Z9yR8Z0QXvbVimqM09IHxotnzrO7Z87XjK9BehERFHbaYoDY6wDdZGXUzrJsS-8qm980FP2fF6y8j8LvMb50KOLkkfEGrWgNAisegXGudGScM76mybPtZIPoEDoLR68jhTvLii1MBcUAq-9ZtgUA0B04C6x4guzqKr3mpcH37e7px290llXZEDw8fv3B-AO8sCoDHU6DKHDWvFE2VmXUS5WBHCc4tUuBYRpH5yMqqnHqj9X3IJ1HwqjY0uJOv8LAeM54wzi_qsl4kc9TAqsfT72y-hHQBPxPtJ991j5hPH-ekZ-JQMRmVXaDfJWBsNZFQYyBQbwmFuH1fDSaDdFPiVUBjs6_0hWtMIWSbJbw1YK4UA-OOvZuihB7Ea8KUN_Pz___Bkc3GQXovfPLub37KdJdHUFO3qON5g3EOKLwAaKDFkEPowtBE02jm5n4kfDg0WjR0uotaGu0RRAh4NCatyXQ_CEKq4RXMKDshdVhAOUwWMbrmOZK0H6qmxDVLTB741phXq7xWdLdF_wZ0Qbq6F1Ixf0NJGn4kDb12Z2kL3vhCVBiHVHGyQsDlwoURkUIflY_sGxrXSQKJcyEjVrQaW2ju-wCevRIJ-7uSKqseLgsa2DFEyu2Of2rr5Lm9A2fTXeKgdsXK5_-ysH_WYSjeIMjMl4fEDo3WUVoEvESmaRT9DGM2iShRAdTSHRMxS-ZPre1WUmMN1a8orr1L2rcW_K3B8b5tZ19dLHPRJgSXkF9bQ0z6iD8cGiWqzuREH_4GPKZcG9CPCaunIRMHf2Nkr-4Ix7QXy8FehHAOiK4fL0z-hWvKB4dpR_dSFMLiokIwirwGCdv6b6A0eNBuymAs7iEL2glpmavasgkZJLiFFBd1LaErYyTMOYN8ID2cuSdKHT4XWe9OCCEiTb23uQSvgn7Bi726GH2qADKnczhu6NepLCze4zeHch9xLmHmVXRQXT7vTnZwpzl4rqdd8OtK1DW0WOHPtlGcAPGXts9pA0eyby8DvKQtjW6I_pRgnJJtPMm5Su47lwjLCEU6-wneJQnB1MK1dntoXOeTulBG-GvAPrFk4Uxh_PX3ejd7ygj4zsdwoSB8V3O11lZnLYUEEGY4H6Vj-RyZ4Tdn34zvhsnYyhVUdc8Sz3iTzGMBgON1rvjLSoozLyBtG1a18dVB_Lfa-PVAaSz0mNEwq41OIAUA8I0Uug_aFe-kEHs0b5ILywa3X1cR9lULNsu1KZQ62ItFrjJ6zIvV0W1yhb9piu79Vqu12tZKs6rhlertsKi6lBWlWiyhd7wjJdZnRV5Xq6ybJnLtm7bTpWqaRTmNVtlOAhtloTI0vn9IhXf5KuqqaqFES2akB4xObd4hHSXZF0-LvwmwdhO-8BWmdEhhvc0UUeDm_Pj3vyEcXp2uCHyuwwvf-_QMr5TOpAU1Mz08_4Xkzebf0Gwea7Dhv8ZAAD__yJmg_Y">