blob: 47aba9769a077323ba3adc781e7b6e1101685ffc [file] [log] [blame]
#if defined(__aarch64__) /* HOST_ARCH_ARM64 */
.text
.global FfiTrampolineCall
.type FfiTrampolineCall, %function
FfiTrampolineCall:
/* Save argument in scratch register. */
stp x19, x20, [sp, #-16]! /* Push x19 and x20, we use x19 as scratch. */
mov x19, x0 /* Save argument in scratch register. */
/* Enter frame. */
stp fp, lr, [sp, #-16]!
mov fp, sp
/* Reserve framespace for arguments. */
ldr x9, [x19, #(8*18)] /* Load number of stack arguments. */
lsl x9, x9, #3 /* Multiply by size (8 bytes). */
sub sp, sp, x9 /* Reserve num_stack_args stack slots. */
/* Stack alignment. */
ldr x10, [x19, #(8*17)] /* Load stack alignment mask. */
mov x11, sp
and x11, x11, x10 /* Align stack. */
mov sp, x11
/* Copy stack arguments. */
cmp x9, #0 /* Check if number of stack arguments is 0. */
beq .done /* Skip loop if no stack arguments. */
add x19, x19, #(8*19) /* Offset r19 to point to stack arguments. */
.loop: /* Copy stack arguments loop. */
sub x9, x9, #8 /* Decrement stack argument iterator. */
ldr x10, [x19, x9] /* Load value from ffi_marshalled_args. */
str x10, [sp, x9] /* Store value on stack. */
cmp x9, #0 /* Compare iterator with 0 */
bne .loop /* Loop while iterator is not 0 */
sub x19, x19, #(8*19) /* Restore r19 to original value. */
.done: /* End stack arguments loop. */
/* Copy registers and fpu registers. */
ldp x0, x1, [x19, #(8*1)] /* and #(8*2) */
ldp x2, x3, [x19, #(8*3)] /* and #(8*4) */
ldp x4, x5, [x19, #(8*5)] /* ... */
ldp x6, x7, [x19, #(8*7)]
ldp d0, d1, [x19, #(8*9)]
ldp d2, d3, [x19, #(8*11)]
ldp d4, d5, [x19, #(8*13)]
ldp d6, d7, [x19, #(8*15)]
/* Do call. */
ldr x9, [x19] /* Load function address. */
blr x9 /* Call the function. */
/* Copy results back. */
str x0, [x19, #(8*0)] /* Move integer result in kOffsetIntResult. */
str d0, [x19, #(8*1)] /* Move double result in kOffsetDoubleResult. */
/* Leave frame. */
mov sp, fp
ldp fp, lr, [sp], #16
/* Restore caller saved register. */
ldp x19, x20, [sp], #16 /* Pop x19 and x20. */
ret
#endif /* HOST_ARCH_ARM64 */