179 lines
2.8 KiB
ArmAsm
179 lines
2.8 KiB
ArmAsm
|
|
.global _callvm_invoke_i
|
||
|
|
.align 4
|
||
|
|
|
||
|
|
# x0 = (function ptr) impl
|
||
|
|
# x1 = (struct callvm) context
|
||
|
|
_callvm_invoke_i:
|
||
|
|
# save the stack frame and link pointer
|
||
|
|
stp x29, x30, [sp, #-16]!
|
||
|
|
mov x29, sp
|
||
|
|
|
||
|
|
# store function pointer for later
|
||
|
|
mov x16, x0
|
||
|
|
mov x15, x1
|
||
|
|
|
||
|
|
# First, set up the fixed arguments
|
||
|
|
# x8 = fixed arg count
|
||
|
|
ldr x8, [x15, #0]
|
||
|
|
|
||
|
|
# 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
|
||
|
|
|
||
|
|
# 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
|
||
|
|
|
||
|
|
# allocate the stack space
|
||
|
|
sub sp, sp, x19
|
||
|
|
mov x13, sp
|
||
|
|
|
||
|
|
# get a pointer to the end of the stack vararg buffer
|
||
|
|
#mov x14, #8
|
||
|
|
#mul x14, x14, x11
|
||
|
|
#add x13, x13, x14
|
||
|
|
|
||
|
|
# 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]
|
||
|
|
|
||
|
|
.iv.loop:
|
||
|
|
cmp x8, #0
|
||
|
|
beq .iv.loop.end
|
||
|
|
|
||
|
|
# read the arg value from the src pointer
|
||
|
|
ldr x14, [x9]
|
||
|
|
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
# call the function implementation
|
||
|
|
blr x16
|
||
|
|
|
||
|
|
# de-allocate the stack varargs buffer (the size is now stored in x19)
|
||
|
|
add sp, sp, x19
|
||
|
|
|
||
|
|
# restore the saved value of x19,
|
||
|
|
ldr x19, [sp], #16
|
||
|
|
|
||
|
|
# restore the saved stack frame and link pointer
|
||
|
|
ldp x29,x30, [sp], #16
|
||
|
|
ret
|
||
|
|
|
||
|
|
|
||
|
|
.global _callvm_invoke_d
|
||
|
|
.align 4
|
||
|
|
|
||
|
|
# x0 = (function ptr) impl
|
||
|
|
# x1 = (struct callvm) context
|
||
|
|
_callvm_invoke_d:
|
||
|
|
b _callvm_invoke_i
|
||
|
|
|
||
|
|
|
||
|
|
.global _callvm_invoke_v
|
||
|
|
.align 4
|
||
|
|
|
||
|
|
# x0 = (function ptr) impl
|
||
|
|
# x1 = (struct callvm) context
|
||
|
|
_callvm_invoke_v:
|
||
|
|
b _callvm_invoke_i
|