xref: /reactos/dll/win32/rpcrt4/msvc.S (revision cce399e7)
1
2#if defined(_M_IX86) || defined(_M_AMD64)
3#include <asm.inc>
4#elif defined(_M_ARM)
5#include <kxarm.h>
6#endif
7
8#ifdef _M_IX86
9.code32
10
11EXTERN _ndr_client_call:PROC
12
13PUBLIC _call_stubless_func
14_call_stubless_func:
15
16    mov ecx, [esp+4]                /* This Pointer */
17    mov ecx, [ecx]                  /* This->lpVtbl */
18    mov ecx, [ecx-8]                /* MIDL_STUBLESS_PROXY_INFO */
19    mov edx, [ecx+8]                /* Info->FormatStringOffset */
20    movzx edx, word ptr [edx+eax*2] /* FormatStringOffset[index] */
21    add edx, [ecx+4]                /* info->ProcFormatString + offset */
22    movzx eax, byte ptr [edx+1]     /* Oi_flags */
23    and eax, 8                      /* Oi_HAS_RPCFLAGS */
24    shr eax, 1
25    movzx eax, word ptr [edx+eax+4] /* arguments size */
26    push eax
27    lea eax, [esp+8]                /* &This */
28    push eax
29    push edx                        /* format string */
30    push [ecx]                      /* info->pstubdesc */
31    call _ndr_client_call
32    lea esp, [esp+12]
33    pop edx                         /* arguments size */
34    mov ecx, [esp]                  /* return address */
35    add esp, edx
36    jmp ecx
37
38#elif _M_AMD64
39.code64
40
41EXTERN ndr_client_call:PROC
42
43PUBLIC call_stubless_func
44FUNC call_stubless_func
45    mov [rsp + 8], rcx
46    .SAVEREG rcx, 8
47    mov [rsp + 10h], rdx
48    .SAVEREG rdx, 10h
49    mov [rsp + 18h], r8
50    .SAVEREG r8, 18h
51    mov [rsp + 20h], r9
52    .SAVEREG r9, 20h
53    sub rsp, 38h
54    .ALLOCSTACK 38h
55    .ENDPROLOG
56
57    lea r8, [rsp +38h + 8]   /* &This */
58    mov rcx, [rcx]           /* This->lpVtbl */
59    mov rcx, [rcx - 10h]     /* MIDL_STUBLESS_PROXY_INFO */
60    mov rdx, [rcx + 10h]     /* info->FormatStringOffset */
61    movzx rdx, word ptr [rdx+r10*2] /* FormatStringOffset[index] */
62    add rdx, [rcx + 8]       /* info->ProcFormatString + offset */
63    mov rcx, [rcx]           /* info->pStubDesc */
64
65    movsd qword ptr [rsp + 20h], xmm1
66    movsd qword ptr [rsp + 28h], xmm2
67    movsd qword ptr [rsp + 30h], xmm3
68    lea r9, [rsp + 18h]      /* fpu_args */
69    call ndr_client_call
70    add rsp, 38h
71    ret
72ENDFUNC
73
74PUBLIC call_server_func
75FUNC call_server_func
76    push rbp
77    .PUSHREG rbp
78    mov rbp, rsp
79    push rsi
80    .PUSHREG rsi
81    push rdi
82    .PUSHREG rdi
83    .ENDPROLOG
84
85    mov rax, rcx   /* function to call */
86    mov rcx, 32    /* allocate max(32,stack_size) bytes of stack space */
87    cmp r8, rcx
88    cmovg rcx, r8
89    sub rsp, rcx
90    and rsp, NOT 15
91    mov rcx, r8
92    shr rcx, 3
93    mov rdi, rsp
94    mov rsi, rdx
95    rep movsq       /* copy arguments */
96    mov rcx, [rsp]
97    mov rdx, [rsp + 8]
98    mov r8, [rsp + 16]
99    mov r9, [rsp + 24]
100
101    /* Usually the 64 bit SSE2 version of movd is called movq, as in GCC code
102       (see https://www.felixcloutier.com/x86/movd:movq). But there is another
103       movq with different encoding, which does not accept an integer register
104       as source (see https://www.felixcloutier.com/x86/movq). Older versions
105       of ML64 get confused and do not accept movq with integer registers,
106       but they translate movd to 64 bit, when 64 bit registers are used as
107       source, so we use that here. */
108    movd xmm0, rcx
109    movd xmm1, rdx
110    movd xmm2, r8
111    movd xmm3, r9
112    call rax
113
114    lea rsp, [rbp - 16] /* restore stack */
115    pop rdi
116    pop rsi
117    pop rbp
118    ret
119ENDFUNC
120
121
122PUBLIC NdrClientCall2
123FUNC NdrClientCall2
124    mov [rsp + 18h], r8
125    .SAVEREG r8, 18h
126    mov [rsp + 20h], r9
127    .SAVEREG r9, 20h
128    sub rsp, 28h
129    .ALLOCSTACK 28h
130    .ENDPROLOG
131
132    lea r8, [rsp + 28h + 18h]
133    xor r9, r9
134    call ndr_client_call
135
136    add rsp, 28h
137    ret
138ENDFUNC
139
140EXTERN ndr_async_client_call:PROC
141PUBLIC NdrAsyncClientCall
142FUNC NdrAsyncClientCall
143    mov [rsp + 18h], r8
144    .SAVEREG r8, 18h
145    mov [rsp + 20h], r9
146    .SAVEREG r9, 20h
147    sub rsp, 28h
148    .ALLOCSTACK 28h
149    .ENDPROLOG
150
151    lea r8, [rsp + 28h + 18h]
152    call ndr_async_client_call
153
154    add rsp, 28h
155    ret
156ENDFUNC
157
158#elif _M_ARM
159TEXTAREA
160
161    LEAF_ENTRY call_stubless_func
162
163    /* Unimplemented */
164    __assertfail
165    bx lr
166
167    LEAF_END call_stubless_func
168
169    LEAF_ENTRY call_server_func
170
171    /* Unimplemented */
172    __assertfail
173    bx lr
174
175    LEAF_END call_server_func
176
177#endif
178
179END
180