127 строки
3.3 KiB
ArmAsm
127 строки
3.3 KiB
ArmAsm
#
|
|
# store all parameters in a consistent way, and send it off to managed code.
|
|
# we need to store:
|
|
# x0-x9, x16
|
|
# q0-q7
|
|
# x29, x30 (for the stack frame)
|
|
# an unknown amount of stack space, but we can pass a pointer to the start of this area.
|
|
# in total we need 11*64bits registers + 8*128bits registers + 2*64bits register = 232 bytes.
|
|
# the 128 bit registers need to be 16-byte aligned, so there's a register-sized padding before the qX registers, thus total 240 bytes.
|
|
# in addition we store a copy of x0 and x1 as _self and _sel, so that we can get those values even if
|
|
# x0 and x1 change (which they might very well do after processing the return value, so 240 + 2*8 = 256 bytes.
|
|
#
|
|
# upon return we may need to write to:
|
|
# x0, x1
|
|
# q0, q1, q2, q3
|
|
#
|
|
|
|
#if __arm64__
|
|
|
|
.subsections_via_symbols
|
|
.text
|
|
.align 2
|
|
_xamarin_arm64_common_trampoline:
|
|
mov x9, sp ;#Save sp to a temporary register
|
|
sub sp, sp, #256 ;# allocate 224 bytes from the stack (stack must always be 16-byte aligned) + 16 bytes for the stack frame + 8*2 bytes for _self and _sel
|
|
|
|
# Create stack frame
|
|
stp x29, x30, [sp, #0x00]
|
|
mov x29, sp
|
|
|
|
stp x16, x9, [sp, #0x10]
|
|
stp x0, x1, [sp, #0x20]
|
|
stp x2, x3, [sp, #0x30]
|
|
stp x4, x5, [sp, #0x40]
|
|
stp x6, x7, [sp, #0x50]
|
|
str x8, [sp, #0x60]
|
|
|
|
stp q0, q1, [sp, #0x70]
|
|
stp q2, q3, [sp, #0x90]
|
|
stp q4, q5, [sp, #0xb0]
|
|
stp q6, q7, [sp, #0xd0]
|
|
|
|
add x0, sp, #0x10 ;# the first two pointers are the stack frame (x29, x30), the rest is a pointer to a XamarinCallState struct.
|
|
bl _xamarin_arch_trampoline
|
|
|
|
# get return value(s)
|
|
|
|
ldp x16, x9, [sp, #0x10]
|
|
ldp x0, x1, [sp, #0x20]
|
|
ldp x2, x3, [sp, #0x30]
|
|
ldp x4, x5, [sp, #0x40]
|
|
ldp x6, x7, [sp, #0x50]
|
|
ldr x8, [sp, #0x60]
|
|
|
|
ldp q0, q1, [sp, #0x70]
|
|
ldp q2, q3, [sp, #0x90]
|
|
ldp q4, q5, [sp, #0xb0]
|
|
ldp q6, q7, [sp, #0xd0]
|
|
|
|
ldp x29, x30, [sp, #0x00]
|
|
add sp, sp, #256 ;# deallocate 224 bytes from the stack + 16 bytes for stack frame + 8*2 bytes for _self and _sel
|
|
|
|
ret
|
|
|
|
#
|
|
# trampolines
|
|
#
|
|
|
|
.globl _xamarin_trampoline
|
|
_xamarin_trampoline:
|
|
mov x16, #0x0
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_static_trampoline
|
|
_xamarin_static_trampoline:
|
|
mov x16, #0x1
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_ctor_trampoline
|
|
_xamarin_ctor_trampoline:
|
|
mov x16, #0x2
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_fpret_single_trampoline
|
|
_xamarin_fpret_single_trampoline:
|
|
mov x16, #0x4
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_static_fpret_single_trampoline
|
|
_xamarin_static_fpret_single_trampoline:
|
|
mov x16, #0x5
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_fpret_double_trampoline
|
|
_xamarin_fpret_double_trampoline:
|
|
mov x16, #0x8
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_static_fpret_double_trampoline
|
|
_xamarin_static_fpret_double_trampoline:
|
|
mov x16, #0x9
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_stret_trampoline
|
|
_xamarin_stret_trampoline:
|
|
mov x16, #0x10
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_static_stret_trampoline
|
|
_xamarin_static_stret_trampoline:
|
|
mov x16, #0x11
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_longret_trampoline
|
|
_xamarin_longret_trampoline:
|
|
mov x16, #0x20
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
.globl _xamarin_static_longret_trampoline
|
|
_xamarin_static_longret_trampoline:
|
|
mov x16, #0x21
|
|
b _xamarin_arm64_common_trampoline
|
|
|
|
# etc...
|
|
|
|
#endif
|