How do I use a constant in Rust's inline assembly macro?

3

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
rust
inline-assembly
arm64
asked on Stack Overflow Sep 28, 2018 by phodina • edited Oct 23, 2019 by Florian Weimer

1 Answer

3

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.

answered on Stack Overflow Sep 28, 2018 by Florian Weimer • edited Sep 29, 2018 by Florian Weimer

User contributions licensed under CC BY-SA 3.0