aarch64/macOS: error: invalid asm template string: expected `}`, found `.` + unsupported architectural extension: dit
There are couple issues when compiling crate rustls-graviola, which utilises a lot of inline assembly.
Compiled on aarch64/macOS with latest Nightly/cranelift.
Compiling graviola v0.2.1
error: invalid asm template string: expected `}`, found `.`
Compiling rustls-graviola v0.2.1
--> <anon>:5041:15
|
5041 | st1 {q0.16b}, [x0]
| - ^ expected `}` in asm template string
| |
| because of this opening brace
|
= note: if you intended to print `{`, you can escape it using `{{`
error: aborting due to 1 previous error
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:8:17
|
8 | .arch_extension dit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:10:17
|
10 | .arch_extension nodit
See minimal example here to reproduce: https://github.com/Nicceboy/cranelift-graviola/.
There are two issues:
- I didn't escape
{and}before passing the generatedglobal_asm!()to cg_llvm. - Graviola expects a register name like
v0to be used forout(vreg)to combine with.16bto formv0.16b, cg_clif however usesq0as it enables theqmodifier by default since https://github.com/rust-lang/rustc_codegen_cranelift/pull/1564. It seems like I was a bit too eager using theqmodifier everywhere though. I think it is only necessary for the loads/stores that cg_clif inserts for clobbered registers. Not for user references to vector registers. - Enabling support for the
ditfeature using.arch_extensionisn't supported by LLVM for whatever reason. That is going to be an issue for#[naked]functions too as those also use.arch_extension. cc @folkertdev In any case removing#[target_feature(enable = "dit")]in graviola doesn't work either as the DIT msr is not accessible.
Opened https://github.com/rust-lang/rustc_codegen_cranelift/pull/1587 for the first two issues.
Fun. I guess I'll open an LLVM error for that one and hope for the best?
this works apparently https://godbolt.org/z/jWvxGKjPG
#[unsafe(no_mangle)]
#[unsafe(naked)]
//#[target_feature(enable = "dit")]
unsafe extern "C" fn write() {
core::arch::naked_asm!(
".arch armv8.4-a",
"msr DIT, #0",
"ret"
)
}
Still that seems really inconsistent
I believe this is related to https://github.com/rust-lang/rust/issues/113221. Also arm's target features are just an absolute mess, and the above isn't really workable because there is no way to "pop" the .arch to go back to the previous state.
Same error.
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:8:17
|
8 | .arch_extension dit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:10:17
|
10 | .arch_extension nodit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:49:17
|
49 | .arch_extension dit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:51:17
|
51 | .arch_extension nodit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:65:17
|
65 | .arch_extension dit
| ^
error: unsupported architectural extension: dit
|
note: instantiated into assembly here
--> <inline asm>:67:17
|
67 | .arch_extension nodit
| ^
error: aborting due to 6 previous errors
error: Failed to assemble `.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n0
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n0:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
.arch_extension dit
msr dit, #1
.arch_extension nodit
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n1
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n1:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
.arch_extension sb
sb
.arch_extension nosb
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n2
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n2:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
dsb nsh
isb sy
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n3
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n3:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
.arch_extension dit
mrs x0, dit
.arch_extension nodit
str x0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n4
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n4:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr x0, [x19, 0x0]
.arch_extension dit
msr dit, x0
.arch_extension nodit
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n5
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n5:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr q0, [x19, 0x0]
ldr q1, [x19, 0x10]
and v0.16b, v0.16b, v1.16b
str q0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n6
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n6:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr q0, [x19, 0x0]
ldr q1, [x19, 0x10]
cmeq v0.16b, v0.16b, v1.16b
str q0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n7
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n7:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr q0, [x19, 0x0]
shrn v0.8b, v0.8h, #4
str q0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n8
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n8:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr x0, [x19, 0x0]
/* x0 */
str x0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n9
___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n9:
stp fp, lr, [sp, #-32]!
mov fp, sp
str x19, [sp, #24]
mov x19, x0
ldr x0, [x19, 0x0]
/* x0 */
str x0, [x19, 0x0]
ldr x19, [sp, #24]
ldp fp, lr, [sp], #32
ret
`
error: could not compile `constant_time_eq` (lib) due to 1 previous error
There is not much I can do about this. LLVM's assembler just doesn't support .arch_extension dit and without .arch_extension dit the assembler rejects setting the instruction to set the dit flag due to the dit target feature not being enabled for the assembly block.
The fix has landed in LLVM. We will now have to wait for the next LLVM release and have rustc update LLVM.