diff --git a/fx.reflection/sys/darwin/arm64/callvm.S b/fx.reflection/sys/darwin/arm64/callvm.S index 8af5497..faffce7 100644 --- a/fx.reflection/sys/darwin/arm64/callvm.S +++ b/fx.reflection/sys/darwin/arm64/callvm.S @@ -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