1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5# Darwin gives a leading '_' to symbols defined in C code. 6#ifdef XP_DARWIN 7#define SYM(x) _ ## x 8#else 9#define SYM(x) x 10#endif 11 12#define CFI_STARTPROC .cfi_startproc 13#define CFI_ENDPROC .cfi_endproc 14#define CFI_DEF_CFA_OFFSET(offset) .cfi_def_cfa_offset offset 15#define CFI_OFFSET(reg, offset) .cfi_offset reg, offset 16#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg 17#define CFI_DEF_CFA(reg, offset) .cfi_def_cfa reg, offset 18 19.intel_syntax noprefix 20 21# nsresult NS_InvokeByIndex(nsISupports* this, uint32_t aVtableIndex, 22# uint32_t argc, nsXPTCVariant* argv); 23.text 24.global SYM(NS_InvokeByIndex) 25#ifndef XP_DARWIN 26.type NS_InvokeByIndex, @function 27#endif 28.align 4 29SYM(NS_InvokeByIndex): 30 CFI_STARTPROC 31 push rbp 32 CFI_DEF_CFA_OFFSET(16) 33 CFI_OFFSET(6, -16) 34 mov rbp, rsp 35 CFI_DEF_CFA_REGISTER(6) 36 37# save r12 and r13 because we use them and they are callee saved. 38 push r12 39 push r13 40 CFI_OFFSET(12, -24) 41 CFI_OFFSET(13, -32) 42 43# save this and the vtable index because we need them after setting up the 44# stack. 45 mov r12, rdi 46 mov r13, rsi 47 48# allocate space for stack arguments, in theory we only need 8 * (argc - 5) 49# bytes because at least 5 arguments will go in registers, but for now it is 50# just simpler to allocate 8 * argc bytes. Note that we treat the this 51# pointer specially. 52 lea eax, [edx * 8] 53 sub rsp, rax 54 55# If there is an odd number of args the stack can be misaligned so realign it. 56 and rsp, 0xfffffffffffffff0 57 58# pass the stack slot area to InvokeCopyToStack. 59 mov r8, rsp 60 61# setup space for the register slots: there are 5 integer ones and 8 floating 62# point ones. So we need 104 bytes of space, but we allocate 112 to keep rsp 63# aligned to 16 bytes. 64 sub rsp, 112 65 66# the first argument to InvokeCopyToStack is the integer register area, and the 67# second is the floating point area. 68 mov rdi, rsp 69 lea rsi, [rsp + 40] 70 71# The 3rd and 4th arguments to InvokeCopyToStack are already in the right 72# registers. So now we can just call InvokeCopyToStack. 73 call SYM(InvokeCopyToStack) 74 75# setup this 76 mov rdi, r12 77 78# copy the integer arguments into place. 79 mov rsi, [rsp] 80 mov rdx, [rsp + 8] 81 mov rcx, [rsp + 16] 82 mov r8, [rsp + 24] 83 mov r9, [rsp + 32] 84 85# copy the float arguments into place 86 movsd xmm0, [rsp + 40] 87 movsd xmm1, [rsp + 48] 88 movsd xmm2, [rsp + 56] 89 movsd xmm3, [rsp + 64] 90 movsd xmm4, [rsp + 72] 91 movsd xmm5, [rsp + 80] 92 movsd xmm6, [rsp + 88] 93 movsd xmm7, [rsp + 96] 94 95# get rid of the scratch space for registers 96 add rsp, 112 97 98# load the function pointer and call 99 lea eax, [r13d * 8] 100 add rax, [rdi] 101 call [rax] 102 103# r12 and r13 were pushed relative to the old stack pointer which is now the 104# frame pointer. 105 mov r12, [rbp - 0x8] 106 mov r13, [rbp - 0x10] 107 108 mov rsp, rbp 109 pop rbp 110 CFI_DEF_CFA(7, 8) 111 ret 112 CFI_ENDPROC 113 114#ifndef XP_DARWIN 115// Magic indicating no need for an executable stack 116.section .note.GNU-stack, "", @progbits ; .previous 117#endif 118