This question already has an answer here:
In the ARM64 architecture, if the size of the result exceeds 16 bytes, it is transmitted in the X8 register. I need to call the function in such a way as to pass this register.
typedef struct{char a[16 + 1];} retptr;
typedef retptr (*Func)(void* x0, void* x1, void* x2, void* x3);
void call(void* x0, void* x1, void* x2, void* x3, void* x8, void* address)
{
retptr* r = (retptr*)x8;
*r = ((Func)(address))(x0, x1, x2, x3);
}
The problem is that the value is not passed to the register - a pointer to the stack is passed, and then the data is copied. https://godbolt.org/z/D-zAnt
call: // @call
sub sp, sp, #64 // =64
str x19, [sp, #32] // 8-byte Folded Spill
stp x29, x30, [sp, #48] // 16-byte Folded Spill
add x29, sp, #48 // =48
add x8, sp, #8 // =8
mov x19, x4
blr x5
ldrb w8, [sp, #24]
ldur q0, [sp, #8]
strb w8, [x19, #16]
str q0, [x19]
ldp x29, x30, [sp, #48] // 16-byte Folded Reload
ldr x19, [sp, #32] // 8-byte Folded Reload
add sp, sp, #64 // =64
ret