I'm porting some legacy assembly code to Rust and I need to call it through the asm!
macro. However, the assembly code depends on some constants stored in a C header file. I'd like to keep it similar, define the constants in Rust and have the names of the constants in the asm
macro.
Legacy C header:
#define HCR_VALUE 0xffff0000
Legacy ASM file:
.func
...
ldr x0, =HCR_VALUE
...
Rust code:
pub const HCR_VALUE: u32 = 0xffff0000;
unsafe { asm!("ldr x0, HCR_VALUE":::"x0"); }
Building the application ends up with a linker error:
lld-link: error: undefined symbol: HCR_VALUE
You need to pass the constant with a suitable constraint, like this:
unsafe { asm!("ldr x0, =${0:c}" : : "i" (HCR_VALUE) : "x0"); }
The right constraint depends on the architecture; on RISC CPUs, not all constants can be represented as immediate values. So you may have to use a register constraint instead and have LLVM materialize the constant there.