ReactOS 0.4.17-dev-540-g8f54750
thunks.c
Go to the documentation of this file.
1/*
2 * oleaut32 thunking
3 *
4 * Copyright 2019, 2024 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 */
21
22#if 0
23#pragma makedep arm64ec_x64
24#endif
25
26#define COBJMACROS
27
28#include <stdarg.h>
29
30#include "windef.h"
31#include "wine/asm.h"
32
33#ifdef __i386__
34
35__ASM_GLOBAL_FUNC( call_method,
36 "pushl %ebp\n\t"
37 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
38 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
39 "movl %esp,%ebp\n\t"
40 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
41 "pushl %esi\n\t"
42 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
43 "pushl %edi\n\t"
44 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
45 "movl 12(%ebp),%edx\n\t"
46 "movl %esp,%edi\n\t"
47 "shll $2,%edx\n\t"
48 "jz 1f\n\t"
49 "subl %edx,%edi\n\t"
50 "andl $~15,%edi\n\t"
51 "movl %edi,%esp\n\t"
52 "movl 12(%ebp),%ecx\n\t"
53 "movl 16(%ebp),%esi\n\t"
54 "cld\n\t"
55 "rep; movsl\n"
56 "1:\tcall *8(%ebp)\n\t"
57 "subl %esp,%edi\n\t"
58 "movl 20(%ebp),%ecx\n\t"
59 "movl %edi,(%ecx)\n\t"
60 "leal -8(%ebp),%esp\n\t"
61 "popl %edi\n\t"
62 __ASM_CFI(".cfi_same_value %edi\n\t")
63 "popl %esi\n\t"
64 __ASM_CFI(".cfi_same_value %esi\n\t")
65 "popl %ebp\n\t"
66 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
67 __ASM_CFI(".cfi_same_value %ebp\n\t")
68 "ret" )
69__ASM_GLOBAL_FUNC( call_double_method,
70 "jmp " __ASM_NAME("call_method") )
71
72#elif defined __x86_64__
73
74__ASM_GLOBAL_FUNC( call_method,
75 "pushq %rbp\n\t"
76 __ASM_SEH(".seh_pushreg %rbp\n\t")
77 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
78 __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
79 "movq %rsp,%rbp\n\t"
80 __ASM_SEH(".seh_setframe %rbp,0\n\t")
81 __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
82 "pushq %rsi\n\t"
83 __ASM_SEH(".seh_pushreg %rsi\n\t")
84 __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t")
85 "pushq %rdi\n\t"
86 __ASM_SEH(".seh_pushreg %rdi\n\t")
87 __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t")
88 __ASM_SEH(".seh_endprologue\n\t")
89 "movq %rcx,%rax\n\t"
90 "movq $4,%rcx\n\t"
91 "cmp %rcx,%rdx\n\t"
92 "cmovgq %rdx,%rcx\n\t"
93 "leaq 0(,%rcx,8),%rdx\n\t"
94 "subq %rdx,%rsp\n\t"
95 "andq $~15,%rsp\n\t"
96 "movq %rsp,%rdi\n\t"
97 "movq %r8,%rsi\n\t"
98 "rep; movsq\n\t"
99 "movq 0(%rsp),%rcx\n\t"
100 "movq 8(%rsp),%rdx\n\t"
101 "movq 16(%rsp),%r8\n\t"
102 "movq 24(%rsp),%r9\n\t"
103 "movq 0(%rsp),%xmm0\n\t"
104 "movq 8(%rsp),%xmm1\n\t"
105 "movq 16(%rsp),%xmm2\n\t"
106 "movq 24(%rsp),%xmm3\n\t"
107 "callq *%rax\n\t"
108 "leaq -16(%rbp),%rsp\n\t"
109 "popq %rdi\n\t"
110 __ASM_CFI(".cfi_same_value %rdi\n\t")
111 "popq %rsi\n\t"
112 __ASM_CFI(".cfi_same_value %rsi\n\t")
113 __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
114 "popq %rbp\n\t"
115 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
116 __ASM_CFI(".cfi_same_value %rbp\n\t")
117 "ret" )
118__ASM_GLOBAL_FUNC( call_double_method,
119 "jmp " __ASM_NAME("call_method") )
120
121#elif defined __aarch64__
122
123__ASM_GLOBAL_FUNC( call_method,
124 "stp x29, x30, [sp, #-16]!\n\t"
125 ".seh_save_fplr_x 16\n\t"
126 "mov x29, sp\n\t"
127 ".seh_set_fp\n\t"
128 ".seh_endprologue\n\t"
129 "sub sp, sp, x1, lsl #3\n\t"
130 "cbz x1, 2f\n"
131 "1:\tsub x1, x1, #1\n\t"
132 "ldr x4, [x2, x1, lsl #3]\n\t"
133 "str x4, [sp, x1, lsl #3]\n\t"
134 "cbnz x1, 1b\n"
135 "2:\tmov x16, x0\n\t"
136 "mov x9, x3\n\t"
137 "ldp d0, d1, [x9]\n\t"
138 "ldp d2, d3, [x9, #0x10]\n\t"
139 "ldp d4, d5, [x9, #0x20]\n\t"
140 "ldp d6, d7, [x9, #0x30]\n\t"
141 "ldp x0, x1, [x9, #0x40]\n\t"
142 "ldp x2, x3, [x9, #0x50]\n\t"
143 "ldp x4, x5, [x9, #0x60]\n\t"
144 "ldp x6, x7, [x9, #0x70]\n\t"
145 "ldr x8, [x9, #0x80]\n\t"
146 "blr x16\n\t"
147 "mov sp, x29\n\t"
148 "ldp x29, x30, [sp], #16\n\t"
149 "ret" )
150__ASM_GLOBAL_FUNC( call_float_method,
151 "b " __ASM_NAME("call_method") )
152__ASM_GLOBAL_FUNC( call_double_method,
153 "b " __ASM_NAME("call_method") )
154
155#elif defined __arm__
156
157__ASM_GLOBAL_FUNC( call_method,
158 /* r0 = *func
159 * r1 = nb_stk_args
160 * r2 = *stk_args (pointer to 'nb_stk_args' DWORD values to push on stack)
161 * r3 = *reg_args (pointer to 8, 64-bit d0-d7 (double) values OR as 16, 32-bit s0-s15 (float) values, followed by 4, 32-bit (DWORD) r0-r3 values)
162 */
163 "push {fp, lr}\n\t"
164 ".seh_save_regs_w {fp,lr}\n\t"
165 "mov fp, sp\n\t"
166 ".seh_save_sp fp\n\t"
167 ".seh_endprologue\n\t"
168 "lsls r1, r1, #2\n\t" /* r1 = nb_stk_args * sizeof(DWORD) */
169 "beq 1f\n\t" /* Skip allocation if no stack args */
170 "add r2, r2, r1\n" /* Calculate ending address of incoming stack data */
171 "2:\tldr ip, [r2, #-4]!\n\t" /* Get next value */
172 "str ip, [sp, #-4]!\n\t" /* Push it on the stack */
173 "subs r1, r1, #4\n\t" /* Decrement count */
174 "bgt 2b\n\t" /* Loop till done */
175 "1:\n\t"
176 "vldm r3!, {s0-s15}\n\t" /* Load the s0-s15/d0-d7 arguments */
177 "mov ip, r0\n\t" /* Save the function call address to ip before we nuke r0 with arguments to pass */
178 "ldm r3, {r0-r3}\n\t" /* Load the r0-r3 arguments */
179 "blx ip\n\t" /* Call the target function */
180 "mov sp, fp\n\t" /* Clean the stack using fp */
181 "pop {fp, pc}" ) /* Restore fp and return */
182__ASM_GLOBAL_FUNC( call_float_method,
183 "b " __ASM_NAME("call_method") )
184__ASM_GLOBAL_FUNC( call_double_method,
185 "b " __ASM_NAME("call_method") )
186
187#endif
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define __ASM_NAME(name)
Definition: config.h:934
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
#define __ASM_CFI(str)
Definition: asm.h:39
#define __ASM_SEH(str)
Definition: asm.h:45