fx.reflection: optimise darwin dynamic function calling

This commit is contained in:
2026-05-04 20:18:19 +01:00
parent abe1603955
commit dea321acc2
+47 -133
View File
@@ -8,155 +8,69 @@ _callvm_invoke_i:
stp x29, x30, [sp, #-16]!
mov x29, sp
# store function pointer for later
mov x16, x0
mov x15, x1
# preserve callee-saved registers
stp x19, x20, [sp, #-16]!
# First, set up the fixed arguments
# x8 = fixed arg count
ldr x8, [x15, #0]
# store function pointer and callvm context for later
mov x19, x0
mov x20, x1
# arg[0]
cmp x8, #0
ble .iv.idone
ldr x0, [x15, #48]
# arg[1]
cmp x8, #1
ble .iv.idone
ldr x1, [x15, #56]
# arg[2]
cmp x8, #2
ble .iv.idone
ldr x2, [x15, #64]
# arg[3]
cmp x8, #3
ble .iv.idone
ldr x3, [x15, #72]
# arg[4]
cmp x8, #4
ble .iv.idone
ldr x4, [x15, #80]
# arg[5]
cmp x8, #5
ble .iv.idone
ldr x5, [x15, #88]
# arg[6]
cmp x8, #6
ble .iv.idone
ldr x6, [x15, #96]
# arg[7]
cmp x8, #7
ble .iv.idone
ldr x7, [x15, #104]
.iv.idone:
# Next, set up the fixed double arguments
# x8 = fixed double arg count
ldr x8, [x15, #8]
# arg[0]
cmp x8, #0
ble .iv.vdone
ldr d0, [x15, #112]
# arg[1]
cmp x8, #1
ble .iv.vdone
ldr d1, [x15, #120]
# arg[2]
cmp x8, #2
ble .iv.vdone
ldr d2, [x15, #128]
# arg[3]
cmp x8, #3
ble .iv.vdone
ldr d3, [x15, #136]
# arg[4]
cmp x8, #4
ble .iv.vdone
ldr d4, [x15, #144]
# arg[5]
cmp x8, #5
ble .iv.vdone
ldr d5, [x15, #152]
# arg[6]
cmp x8, #6
ble .iv.vdone
ldr d6, [x15, #160]
# arg[7]
cmp x8, #7
ble .iv.vdone
ldr d7, [x15, #168]
.iv.vdone:
# Finally, set up the variable arguments
# First, set up the variable arguments
### calculate the amount of stack space needed for the varargs
# store the original stack pointer, so it can be restored later
mov x0, sp
str x0, [sp, #-16]!
# x8 = excess arg count
ldr x8, [x15, #32]
# calculate the amount of stack space needed for the varargs
mov x10, #0x10
mul x12, x8, x10
# x19 is caller-saved, and we'll need x12 later
str x19, [sp, #-16]!
mov x19, x12
ldr x8, [x20, #32]
# x8 = excess arg buffer size (8 bytes per value)
lsl x8, x8, #3
# allocate the stack space
sub sp, sp, x19
mov x13, sp
sub sp, sp, x8
# get a pointer to the end of the stack vararg buffer
#mov x14, #8
#mul x14, x14, x11
#add x13, x13, x14
# re-align the stack, and take a pointer to the newly-allocated buffer
mov x0, sp
and x0, x0, #0xFFFFFFFFFFFFFFF0
mov sp, x0
# x8: number of var args (decrements with every iteration)
# x9: arg src buffer (increments with every iteration)
# x13: var arg dest pointer (starts at the end, decrements with every iteration)
ldr x9, [x15, #176]
ldr x1, [x20, #176]
mov x2, x8
.iv.loop:
cmp x8, #0
beq .iv.loop.end
# memcpy(stack vararg buffer, callvm excess buffer, arg size)
bl _memcpy
# read the arg value from the src pointer
ldr x14, [x9]
# Next, set up the fixed integer arguments
ldr x0, [x20, #48]
ldr x1, [x20, #56]
ldr x2, [x20, #64]
ldr x3, [x20, #72]
ldr x4, [x20, #80]
ldr x5, [x20, #88]
ldr x6, [x20, #96]
ldr x7, [x20, #104]
# write it to the stack, and increment the dest pointer
str x14, [x13]
add x13, x13, #8
# increment the src pointer, decrement the arg count
sub x8, x8, #1
add x9, x9, #8
b .iv.loop
.iv.loop.end:
# Finally, set up the fixed double arguments
ldr d0, [x20, #112]
ldr d1, [x20, #120]
ldr d2, [x20, #128]
ldr d3, [x20, #136]
ldr d4, [x20, #144]
ldr d5, [x20, #152]
ldr d6, [x20, #160]
ldr d7, [x20, #168]
# call the function implementation
blr x16
blr x19
# de-allocate the stack varargs buffer (the size is now stored in x19)
add sp, sp, x19
# restore the saved stack pointer, and de-allocate the stack varargs buffer
ldr x9, [x29, #-32]
mov sp, x9
# restore the saved value of x19,
ldr x19, [sp], #16
# restore callee-saved registers
ldp x19, x20, [sp], #16
# restore the saved stack frame and link pointer
ldp x29,x30, [sp], #16
ldp x29, x30, [sp], #16
ret