summaryrefslogtreecommitdiff
path: root/src/vm/amd64/calldescrworkeramd64.S
blob: 7b108dc402c8a742c33280db8b398cff3742f215 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
//

.intel_syntax noprefix
#include "unixasmmacros.inc"
#include "asmconstants.h"

#define real4 dword
#define real8 qword

//extern CallDescrWorkerUnwindFrameChainHandler:proc

//
//      EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr);
//
NESTED_ENTRY FastCallFinalizeWorker, _TEXT, CallDescrWorkerUnwindFrameChainHandler
        alloc_stack     0x28     // alloc callee scratch and align the stack
        END_PROLOGUE
        
        //
        // RDI: already contains obj*
        // RSI: address of finalizer method to call
        //

        // !!!!!!!!!
        // NOTE:  you cannot tail call here because we must have the CallDescrWorkerUnwindFrameChainHandler
        //        personality routine on the stack.
        // !!!!!!!!!
        call    rsi
        xor     rax, rax
        
        // epilog
        add     rsp, 0x28
        ret


NESTED_END FastCallFinalizeWorker, _TEXT

//extern "C" void CallDescrWorkerInternal(CallDescrData * pCallDescrData);

NESTED_ENTRY CallDescrWorkerInternal, _TEXT, CallDescrWorkerUnwindFrameChainHandler
        push_nonvol_reg rbx             // save nonvolatile registers
        .cfi_def_cfa_offset 16          //
        push_nonvol_reg rbp             // 
        .cfi_adjust_cfa_offset 8        //
        .cfi_offset rbp, -24            //
        set_frame rbp, 0                // set frame pointer
        .cfi_def_cfa_register rbp       //
        lea     rsp, [rsp - 8]          // ensure proper alignment of the rsp

        END_PROLOGUE

        mov     rbx, rdi                // save pCallDescrData in rbx

        mov     ecx, dword ptr [rbx + CallDescrData__numStackSlots]

        and     ecx, ecx
        jz      .LNoStackArguments

        test    ecx, 1
        jz      .LStackAligned
        push    rax
.LStackAligned:

        mov     rsi, [rbx + CallDescrData__pSrc] // set source argument list address
        lea     rsi, [rsi + 8 * rcx]

.LStackCopyLoop:                          // copy the arguments to stack top-down to carefully probe for sufficient stack space
        sub     rsi, 8
        push    qword ptr [rsi]
        dec     ecx
        jnz     .LStackCopyLoop
.LNoStackArguments:
        // All argument registers are loaded regardless of the actual number
        // of arguments.

        mov     rax, [rbx + CallDescrData__pArgumentRegisters] 
        mov     rdi, [rax + 0] 
        mov     rsi, [rax + 8]
        mov     rdx, [rax + 16]
        mov     rcx, [rax + 24]
        mov     r8, [rax + 32]
        mov     r9, [rax + 40]

        // All float argument registers are loaded regardless of the actual number
        // of arguments.

        mov     rax, [rbx + CallDescrData__pFloatArgumentRegisters] 
        and     rax, rax
        jz      .LNoFloatArguments
        movsd   xmm0, [rax + 0]
        movsd   xmm1, [rax + 16]
        movsd   xmm2, [rax + 32]
        movsd   xmm3, [rax + 48]
        movsd   xmm4, [rax + 64]
        movsd   xmm5, [rax + 80]
        movsd   xmm6, [rax + 96]
        movsd   xmm7, [rax + 112]
.LNoFloatArguments:
        call    qword ptr [rbx + CallDescrData__pTarget]     // call target function

        // Save FP return value

        mov     ecx, dword ptr [rbx + CallDescrData__fpReturnSize]
        test    ecx, ecx
        jz      .LReturnsInt
        
        cmp     ecx, 4
        je      .LReturnsFloat
        cmp     ecx, 8
        je      .LReturnsDouble
        // unexpected
        jmp     .LEpilog

.LReturnsInt:
        mov     [rbx+CallDescrData__returnValue], rax

.LEpilog:
        lea     rsp, 0[rbp]             // deallocate argument list
        .cfi_def_cfa_register rsp
        pop     rbp                     // restore nonvolatile register
        .cfi_adjust_cfa_offset -8       //
        pop     rbx                     //
        .cfi_adjust_cfa_offset -8       //
        ret

.LReturnsFloat:
        movss   real4 ptr [rbx+CallDescrData__returnValue], xmm0
        jmp     .LEpilog

.LReturnsDouble:
        movsd   real8 ptr [rbx+CallDescrData__returnValue], xmm0
        jmp     .LEpilog

NESTED_END CallDescrWorkerInternal, _TEXT