Memory offsets in inline assembly
There are various ways of specifying addresses in A64 assembler.
/*
[base{,#0}] Simple register (exclusive) - Immediate Offset
[base{,#imm}] Offset - Immediate Offset
[base,Xm{,LSL #imm}] Offset - Register Offset
[base,Wm,(S|U)XTW {#imm}] Offset - Extended Register Offset
[base,#imm]! Pre-indexed - Immediate Offset
[base],#imm Post-indexed - Immediate Offset
label PC-relative (literal) load - Immediate Offset
*/
I would like to use "Offset - Immediate Offset" in inline assembly.
__asm__("ldp x8, x9, %0, 16 \n\t"
:
: "m" (*somePointer)
: "x8", "x9");
This translates to
ldp x8, x9, [x0], 16
My goal is to achieve
ldp x8, x9, [x0, 16]
How to write such instructions with inline assembler?
source to share
I don't have a 64-bit ARM toolchain to test this, but you should do something like this:
asm("ldp x8, x9, %0\n\t"
:
: "Ump" (*((__int128 *) somePointer + 1))
: "x8", "x9");
The constraint Ump
limits the memory operand to those permitted by the integer LDP instruction, otherwise it acts as a constraint m
. If it is somePointer
already a pointer to a 128-bit type, you can simply use somePointer[1]
as an operand.
If the above doesn't work, David Wolferd's suggestion should:
asm("ldp x8, x9, [%0, %1]"
:
: "r" (somePointer), "i"(16), "m" (*somePointer)
: "x8", "x9");
source to share