I tried compiling this code with a target of riscv32im-unknown-none-elf:
#![no_std]
static mut MY_BUFFER: [u32; 4] = [0u32; 4];
#[no_mangle]
unsafe fn using_inout() {
let mut start = MY_BUFFER.as_mut_ptr();
::core::arch::asm!(
"ecall",
inout("a0") start);
_ = start;
}
The assembly generated is incorrect, since it doesn't add in the lower 16 bits of the address of MY_BUFFER before calling the ecall:
using_inout:
lui a0, %hi(example::MY_BUFFER::he36bd30b506a9b69)
ecall
ret
As a workaround, changing the inout to inlateout seems to fix the problem:
using_inlateout:
lui a0, %hi(example::MY_BUFFER::he36bd30b506a9b69)
addi a0, a0, %lo(example::MY_BUFFER::he36bd30b506a9b69)
ecall
ret
Here is a compiler explorer link for rust nightly that demonstrates the problem:
https://godbolt.org/z/xMjoTo5oY
(For reference in case it gets fixed in nightly, it's also present in rust 1.80.0)
I tried compiling this code with a target of
riscv32im-unknown-none-elf:The assembly generated is incorrect, since it doesn't add in the lower 16 bits of the address of
MY_BUFFERbefore calling theecall:As a workaround, changing the
inouttoinlateoutseems to fix the problem:Here is a compiler explorer link for rust nightly that demonstrates the problem:
https://godbolt.org/z/xMjoTo5oY
(For reference in case it gets fixed in nightly, it's also present in rust 1.80.0)