1; Licensed to the .NET Foundation under one or more agreements. 2; The .NET Foundation licenses this file to you under the MIT license. 3; See the LICENSE file in the project root for more information. 4 5include <AsmMacros.inc> 6include <AsmConstants.inc> 7 8extern CallDescrWorkerUnwindFrameChainHandler:proc 9 10;; 11;; EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr); 12;; 13 NESTED_ENTRY FastCallFinalizeWorker, _TEXT, CallDescrWorkerUnwindFrameChainHandler 14 alloc_stack 28h ;; alloc callee scratch and align the stack 15 END_PROLOGUE 16 17 ; 18 ; RCX: already contains obj* 19 ; RDX: address of finalizer method to call 20 ; 21 22 ; !!!!!!!!! 23 ; NOTE: you cannot tail call here because we must have the CallDescrWorkerUnwindFrameChainHandler 24 ; personality routine on the stack. 25 ; !!!!!!!!! 26 call rdx 27 xor rax, rax 28 29 ; epilog 30 add rsp, 28h 31 ret 32 33 34 NESTED_END FastCallFinalizeWorker, _TEXT 35 36;;extern "C" void CallDescrWorkerInternal(CallDescrData * pCallDescrData); 37 38 NESTED_ENTRY CallDescrWorkerInternal, _TEXT, CallDescrWorkerUnwindFrameChainHandler 39 40 push_nonvol_reg rbx ; save nonvolatile registers 41 push_nonvol_reg rsi ; 42 push_nonvol_reg rbp ; 43 set_frame rbp, 0 ; set frame pointer 44 45 END_PROLOGUE 46 47 mov rbx, rcx ; save pCallDescrData in rbx 48 49 mov ecx, dword ptr [rbx + CallDescrData__numStackSlots] 50 51 test ecx, 1 52 jz StackAligned 53 push rax 54StackAligned: 55 56 mov rsi, [rbx + CallDescrData__pSrc] ; set source argument list address 57 lea rsi, [rsi + 8 * rcx] 58 59StackCopyLoop: ; copy the arguments to stack top-down to carefully probe for sufficient stack space 60 sub rsi, 8 61 push qword ptr [rsi] 62 dec ecx 63 jnz StackCopyLoop 64 65 ; 66 ; N.B. All four argument registers are loaded regardless of the actual number 67 ; of arguments. 68 ; 69 70 mov rax, [rbx + CallDescrData__dwRegTypeMap] ; save the reg (arg) type map 71 72 mov rcx, 0[rsp] ; load first four argument registers 73 movss xmm0, real4 ptr 0[rsp] ; 74 cmp al, ASM_ELEMENT_TYPE_R8 ; 75 jnz Arg2 ; 76 movsd xmm0, real8 ptr 0[rsp] ; 77Arg2: 78 mov rdx, 8[rsp] ; 79 movss xmm1, real4 ptr 8[rsp] ; 80 cmp ah, ASM_ELEMENT_TYPE_R8 ; 81 jnz Arg3 ; 82 movsd xmm1, real8 ptr 8[rsp] ; 83Arg3: 84 mov r8, 10h[rsp] ; 85 movss xmm2, real4 ptr 10h[rsp]; 86 shr eax, 16 ; 87 cmp al, ASM_ELEMENT_TYPE_R8 ; 88 jnz Arg4 ; 89 movsd xmm2, real8 ptr 10h[rsp]; 90Arg4: 91 mov r9, 18h[rsp] ; 92 movss xmm3, real4 ptr 18h[rsp]; 93 cmp ah, ASM_ELEMENT_TYPE_R8 ; 94 jnz DoCall ; 95 movsd xmm3, real8 ptr 18h[rsp]; 96DoCall: 97 call qword ptr [rbx+CallDescrData__pTarget] ; call target function 98 99 ; Save FP return value 100 101 mov ecx, dword ptr [rbx+CallDescrData__fpReturnSize] 102 test ecx, ecx 103 jz ReturnsInt 104 105 cmp ecx, 4 106 je ReturnsFloat 107 cmp ecx, 8 108 je ReturnsDouble 109 ; unexpected 110 jmp Epilog 111 112ReturnsInt: 113 mov [rbx+CallDescrData__returnValue], rax 114 115Epilog: 116 lea rsp, 0[rbp] ; deallocate argument list 117 pop rbp ; restore nonvolatile register 118 pop rsi ; 119 pop rbx ; 120 ret 121 122ReturnsFloat: 123 movss real4 ptr [rbx+CallDescrData__returnValue], xmm0 124 jmp Epilog 125 126ReturnsDouble: 127 movsd real8 ptr [rbx+CallDescrData__returnValue], xmm0 128 jmp Epilog 129 130 NESTED_END CallDescrWorkerInternal, _TEXT 131 132 end 133