fx.reflection: optimise darwin dynamic function calling
This commit is contained in:
@@ -8,155 +8,69 @@ _callvm_invoke_i:
|
|||||||
stp x29, x30, [sp, #-16]!
|
stp x29, x30, [sp, #-16]!
|
||||||
mov x29, sp
|
mov x29, sp
|
||||||
|
|
||||||
# store function pointer for later
|
# preserve callee-saved registers
|
||||||
mov x16, x0
|
stp x19, x20, [sp, #-16]!
|
||||||
mov x15, x1
|
|
||||||
|
|
||||||
# First, set up the fixed arguments
|
# store function pointer and callvm context for later
|
||||||
# x8 = fixed arg count
|
mov x19, x0
|
||||||
ldr x8, [x15, #0]
|
mov x20, x1
|
||||||
|
|
||||||
# arg[0]
|
# First, set up the variable arguments
|
||||||
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
|
|
||||||
|
|
||||||
|
### 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
|
# x8 = excess arg count
|
||||||
ldr x8, [x15, #32]
|
ldr x8, [x20, #32]
|
||||||
|
# x8 = excess arg buffer size (8 bytes per value)
|
||||||
# calculate the amount of stack space needed for the varargs
|
lsl x8, x8, #3
|
||||||
mov x10, #0x10
|
|
||||||
mul x12, x8, x10
|
|
||||||
|
|
||||||
# x19 is caller-saved, and we'll need x12 later
|
|
||||||
str x19, [sp, #-16]!
|
|
||||||
mov x19, x12
|
|
||||||
|
|
||||||
# allocate the stack space
|
# allocate the stack space
|
||||||
sub sp, sp, x19
|
sub sp, sp, x8
|
||||||
mov x13, sp
|
|
||||||
|
|
||||||
# get a pointer to the end of the stack vararg buffer
|
# re-align the stack, and take a pointer to the newly-allocated buffer
|
||||||
#mov x14, #8
|
mov x0, sp
|
||||||
#mul x14, x14, x11
|
and x0, x0, #0xFFFFFFFFFFFFFFF0
|
||||||
#add x13, x13, x14
|
mov sp, x0
|
||||||
|
|
||||||
# x8: number of var args (decrements with every iteration)
|
ldr x1, [x20, #176]
|
||||||
# x9: arg src buffer (increments with every iteration)
|
mov x2, x8
|
||||||
# x13: var arg dest pointer (starts at the end, decrements with every iteration)
|
|
||||||
ldr x9, [x15, #176]
|
|
||||||
|
|
||||||
.iv.loop:
|
# memcpy(stack vararg buffer, callvm excess buffer, arg size)
|
||||||
cmp x8, #0
|
bl _memcpy
|
||||||
beq .iv.loop.end
|
|
||||||
|
|
||||||
# read the arg value from the src pointer
|
# Next, set up the fixed integer arguments
|
||||||
ldr x14, [x9]
|
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
|
# Finally, set up the fixed double arguments
|
||||||
str x14, [x13]
|
ldr d0, [x20, #112]
|
||||||
add x13, x13, #8
|
ldr d1, [x20, #120]
|
||||||
|
ldr d2, [x20, #128]
|
||||||
# increment the src pointer, decrement the arg count
|
ldr d3, [x20, #136]
|
||||||
sub x8, x8, #1
|
ldr d4, [x20, #144]
|
||||||
add x9, x9, #8
|
ldr d5, [x20, #152]
|
||||||
b .iv.loop
|
ldr d6, [x20, #160]
|
||||||
.iv.loop.end:
|
ldr d7, [x20, #168]
|
||||||
|
|
||||||
# call the function implementation
|
# call the function implementation
|
||||||
blr x16
|
blr x19
|
||||||
|
|
||||||
# de-allocate the stack varargs buffer (the size is now stored in x19)
|
# restore the saved stack pointer, and de-allocate the stack varargs buffer
|
||||||
add sp, sp, x19
|
ldr x9, [x29, #-32]
|
||||||
|
mov sp, x9
|
||||||
|
|
||||||
# restore the saved value of x19,
|
# restore callee-saved registers
|
||||||
ldr x19, [sp], #16
|
ldp x19, x20, [sp], #16
|
||||||
|
|
||||||
# restore the saved stack frame and link pointer
|
# restore the saved stack frame and link pointer
|
||||||
ldp x29,x30, [sp], #16
|
ldp x29, x30, [sp], #16
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user