Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_call_x86.S @ 663:127b569978cc default tip
- another tweak handling clang trying to be too smart (see last commit)
author | Tassilo Philipp |
---|---|
date | Sun, 24 Mar 2024 13:52:44 +0100 |
parents | e5ad8cf0aa72 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncall | |
5 File: dyncall/dyncall_call_x86.S | |
6 Description: All - except Plan9 - x86 abi call kernel implementation | |
7 License: | |
8 | |
281 | 9 Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 | |
27 | |
28 #include "../portasm/portasm-x86.S" | |
29 BEGIN_ASM | |
30 /* ============================================================================ | |
31 DynCall Call Kernels for X86 Architecture | |
32 ---------------------------------------------------------------------------- | |
33 C Interface: | |
34 dcCall_x86_XXX(void* target, void* args, size_t size); | |
35 ddCall_x86_sys_XXX(int_ptr target, void* args, size_t size); | |
36 | |
37 Where XXX is one of calling-conventions, | |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
38 cdecl, win32_msthis, win32_std, win32_fastcall. |
0 | 39 |
40 Parameter Stack layout: | |
41 size := EBP + 16 | |
42 args := EBP + 12 | |
43 target := EBP + 8 | |
44 | |
45 NOTES: | |
46 - epilog restore ESP serves callee cleanup | |
47 - 16 byte alignment (to be compatible with darwin). | |
48 */ | |
49 | |
50 | |
51 /*--- default / cdecl -------------------------------------------------------- | |
52 | |
53 Details: | |
54 - caller clean-up | |
55 | |
56 */ | |
57 | |
58 GLOBAL(dcCall_x86_cdecl) | |
59 BEGIN_PROC(dcCall_x86_cdecl) | |
610 | 60 PUSH(EBP) /* prolog. */ |
0 | 61 MOVL(ESP,EBP) |
610 | 62 PUSH(ESI) /* save preserved registers. */ |
0 | 63 PUSH(EDI) |
610 | 64 MOVL(DWORD(EBP,12),ESI) /* ESI = arg buffer ptr */ |
65 MOVL(DWORD(EBP,16),ECX) /* ECX = arg buffer size */ | |
66 ADDL(LIT(15),ECX) /* ECX = align(ECX,16) */ | |
0 | 67 ANDL(LIT(-16),ECX) |
610 | 68 MOVL(ECX,DWORD(EBP,16)) /* save ECX. */ |
69 SUBL(ECX,ESP) /* allocate stack size */ | |
70 MOVL(ESP,EDI) /* EDI = stack ptr */ | |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
71 |
0 | 72 /* |
73 work around for rep movsd (not supported by SunPro) | |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
74 |
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
75 SHRL(LIT(2),ECX) |
0 | 76 REP(MOVSD) |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
77 |
0 | 78 */ |
79 | |
80 REP(MOVSB) | |
81 CALL_DWORD(EBP,8) | |
82 ADDL(DWORD(EBP,16),ESP) | |
83 POP(EDI) | |
84 POP(ESI) | |
85 MOVL(EBP,ESP) | |
86 POP(EBP) | |
87 RET() | |
88 END_PROC(dcCall_x86_cdecl) | |
610 | 89 |
90 | |
0 | 91 /* ---- C++ this calls (microsoft) ------------------------------------------ |
92 | |
93 Details: | |
94 - this pointer is in ECX | |
95 | |
96 */ | |
97 | |
98 GLOBAL(dcCall_x86_win32_msthis) | |
99 BEGIN_PROC(dcCall_x86_win32_msthis) | |
610 | 100 PUSH(EBP) /* prolog. */ |
0 | 101 MOVL(ESP,EBP) |
610 | 102 PUSH(ESI) /* save preserved. */ |
0 | 103 PUSH(EDI) |
610 | 104 MOVL(DWORD(EBP,12),ESI) /* ESI = pointer on args. */ |
105 MOVL(DWORD(EBP,16),ECX) /* ECX = size. */ | |
106 MOVL(DWORD(ESI,0),EAX) /* EAX = this pointer. */ | |
107 ADDL(LIT(4),ESI) /* increment args pointer by thisptr. */ | |
108 SUBL(LIT(4),ECX) /* decrement size by sizeof(thisptr). */ | |
109 SUBL(ECX,ESP) /* allocate argument-block on stack. */ | |
110 MOVL(ESP,EDI) /* EDI = stack args. */ | |
111 REP(MOVSB) /* copy arguments. */ | |
112 MOVL(EAX,ECX) /* ECX = this pointer. */ | |
113 CALL_DWORD(EBP,8) /* call function. */ | |
114 POP(EDI) /* restore preserved. */ | |
0 | 115 POP(ESI) |
610 | 116 MOVL(EBP,ESP) /* epilog. */ |
0 | 117 POP(EBP) |
118 RET() | |
119 END_PROC(dcCall_x86_win32_msthis) | |
120 | |
610 | 121 |
0 | 122 /*---- win32 stdcall --------------------------------------------------------- |
123 | |
124 Details: | |
125 - callee cleans up stack | |
126 | |
127 */ | |
128 | |
129 GLOBAL(dcCall_x86_win32_std) | |
130 BEGIN_PROC(dcCall_x86_win32_std) | |
610 | 131 PUSH(EBP) /* prolog. */ |
0 | 132 MOVL(ESP,EBP) |
610 | 133 PUSH(ESI) /* save ESI, EDI. */ |
0 | 134 PUSH(EDI) |
610 | 135 MOVL(DWORD(EBP,12),ESI) /* ESI = args. */ |
136 MOVL(DWORD(EBP,16),ECX) /* ECX = size. */ | |
137 SUBL(ECX,ESP) /* allocate size bytes on stack. */ | |
138 MOVL(ESP,EDI) /* EDI = copy destination stack. */ | |
139 REP(MOVSB) /* copy BYTEs. */ | |
140 CALL_DWORD(EBP,8) /* call target. */ | |
141 POP(EDI) /* restore EDI, ESI. */ | |
0 | 142 POP(ESI) |
610 | 143 MOVL(EBP,ESP) /* epilog. */ |
0 | 144 POP(EBP) |
145 RET() | |
146 END_PROC(dcCall_x86_win32_std) | |
147 | |
610 | 148 |
0 | 149 /*---- win32 fastcall (GNU/Microsoft) ---------------------------------------- |
150 | |
151 Details: | |
152 - callee cleans up stack | |
153 - first two integer (up to 32bits) are passed in ECX and EDX | |
154 | |
155 */ | |
156 | |
157 GLOBAL(dcCall_x86_win32_fast) | |
158 BEGIN_PROC(dcCall_x86_win32_fast) | |
610 | 159 PUSH(EBP) /* prolog. */ |
0 | 160 MOVL(ESP,EBP) |
610 | 161 PUSH(ESI) /* save preserved. */ |
0 | 162 PUSH(EDI) |
610 | 163 MOVL(DWORD(EBP,12),ESI) /* ESI = copy source args. */ |
164 MOVL(DWORD(EBP,16),ECX) /* ECX = size. */ | |
165 MOVL(DWORD(ESI,0),EAX) /* EAX = first argument. */ | |
166 MOVL(DWORD(ESI,4),EDX) /* EDX = second argument. */ | |
167 ADDL(LIT(8),ESI) /* skip registers. */ | |
0 | 168 SUBL(LIT(8),ECX) |
610 | 169 MOVL(ECX,DWORD(EBP,16)) /* save stack alloc size. */ |
170 SUBL(ECX,ESP) /* allocate stack. */ | |
171 MOVL(ESP,EDI) /* EDI = stack args. */ | |
172 REP(MOVSB) /* copy BYTEs. */ | |
173 MOVL(EAX,ECX) /* ECX = first argument. */ | |
174 CALL_DWORD(EBP,8) /* call target. */ | |
175 POP(EDI) /* restore preserved. */ | |
0 | 176 POP(ESI) |
610 | 177 MOVL(EBP,ESP) /* epilog. */ |
0 | 178 POP(EBP) |
179 RET() | |
180 END_PROC(dcCall_x86_win32_fast) | |
181 | |
610 | 182 |
0 | 183 /*--- syscall int80 linux --------------------------------------------------- |
184 | |
185 Details: | |
186 - all arguments are passed via registers | |
187 | |
188 */ | |
189 | |
341 | 190 GLOBAL(dcCall_x86_syscall_int80h_linux) |
191 BEGIN_PROC(dcCall_x86_syscall_int80h_linux) | |
610 | 192 PUSH(EBP) /* prolog. */ |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
193 MOVL(ESP,EBP) |
610 | 194 PUSH(EBX) /* save preserved. */ |
0 | 195 PUSH(ESI) |
196 PUSH(EDI) | |
610 | 197 MOVL(DWORD(EBP,12),EAX) /* EAX = argument buffer. */ |
198 MOVL(DWORD(EAX,0),EBX) /* move first five arguments. */ | |
199 MOVL(DWORD(EAX,4),ECX) | |
0 | 200 MOVL(DWORD(EAX,8),EDX) |
201 MOVL(DWORD(EAX,12),ESI) | |
202 MOVL(DWORD(EAX,16),EDI) | |
610 | 203 MOVL(DWORD(EBP,8),EAX) /* EAX = syscall id. */ |
0 | 204 INT(LIT(HEX(80))) |
610 | 205 POP(EDI) /* restore preserved. */ |
0 | 206 POP(ESI) |
207 POP(EBX) | |
610 | 208 MOVL(EBP,ESP) /* epilog. */ |
0 | 209 POP(EBP) |
210 RET() | |
341 | 211 END_PROC(dcCall_x86_syscall_int80h_linux) |
0 | 212 |
610 | 213 |
0 | 214 /*--- syscall int80 bsd ----------------------------------------------------- |
215 | |
216 Details: | |
217 - all arguments are passed via stack | |
218 | |
219 */ | |
220 | |
341 | 221 GLOBAL(dcCall_x86_syscall_int80h_bsd) |
222 BEGIN_PROC(dcCall_x86_syscall_int80h_bsd) | |
610 | 223 PUSH(EBP) /* prolog. */ |
165
572aff021627
- file name/layout cleanup, removed "-att" from x64 .S filenames, as unnecessary and also misleading
cslag
parents:
0
diff
changeset
|
224 MOVL(ESP,EBP) |
610 | 225 PUSH(ESI) /* save preserved. */ |
0 | 226 PUSH(EDI) |
610 | 227 MOVL(DWORD(EBP,12),ESI) /* ESI = pointer on args. */ |
228 MOVL(DWORD(EBP,16),ECX) /* ECX = size. */ | |
229 SUBL(ECX,ESP) /* allocate stack space. */ | |
230 MOVL(ESP,EDI) /* EDI = stack args. */ | |
0 | 231 REP(MOVSB) |
610 | 232 MOVL(DWORD(EBP,8),EAX) /* load system call id. */ |
0 | 233 CALL(_do_int) |
631 | 234 ADDL(DWORD(EBP,16),ESP) |
610 | 235 POP(EDI) /* restore preserved. */ |
0 | 236 POP(ESI) |
610 | 237 MOVL(EBP,ESP) /* epilog. */ |
0 | 238 POP(EBP) |
239 RET() | |
240 _do_int: | |
241 INT(LIT(HEX(80))) | |
242 RET() | |
341 | 243 END_PROC(dcCall_x86_syscall_int80h_bsd) |
0 | 244 |
245 END_ASM | |
246 |