1 | /*␊ |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. The rights granted to you under the License␊ |
10 | * may not be used to create, or enable the creation or redistribution of,␊ |
11 | * unlawful or unlicensed copies of an Apple operating system, or to␊ |
12 | * circumvent, violate, or enable the circumvention or violation of, any␊ |
13 | * terms of an Apple operating system software license agreement.␊ |
14 | * ␊ |
15 | * Please obtain a copy of the License at␊ |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.␊ |
17 | * ␊ |
18 | * The Original Code and all software distributed under the License are␊ |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
23 | * Please see the License for the specific language governing rights and␊ |
24 | * limitations under the License.␊ |
25 | * ␊ |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@␊ |
27 | */␊ |
28 | /*␊ |
29 | * @OSF_COPYRIGHT@␊ |
30 | */␊ |
31 | /* ␊ |
32 | * Mach Operating System␊ |
33 | * Copyright (c) 1991,1990,1989 Carnegie Mellon University␊ |
34 | * All Rights Reserved.␊ |
35 | * ␊ |
36 | * Permission to use, copy, modify and distribute this software and its␊ |
37 | * documentation is hereby granted, provided that both the copyright␊ |
38 | * notice and this permission notice appear in all copies of the␊ |
39 | * software, derivative works or modified versions, and any portions␊ |
40 | * thereof, and that both notices appear in supporting documentation.␊ |
41 | * ␊ |
42 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"␊ |
43 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR␊ |
44 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.␊ |
45 | * ␊ |
46 | * Carnegie Mellon requests users of this software to return to␊ |
47 | * ␊ |
48 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU␊ |
49 | * School of Computer Science␊ |
50 | * Carnegie Mellon University␊ |
51 | * Pittsburgh PA 15213-3890␊ |
52 | * ␊ |
53 | * any improvements or extensions that they make and grant Carnegie Mellon␊ |
54 | * the rights to redistribute these changes.␊ |
55 | */␊ |
56 | ␊ |
57 | #ifndef␉_I386_ASM_H_␊ |
58 | #define␉_I386_ASM_H_␊ |
59 | ␊ |
60 | #ifdef _KERNEL␊ |
61 | #include <gprof.h>␊ |
62 | #endif␉/* _KERNEL */␊ |
63 | ␊ |
64 | #if␉defined(MACH_KERNEL) || defined(_KERNEL)␊ |
65 | #include <gprof.h>␊ |
66 | #endif␉/* MACH_KERNEL || _KERNEL */␊ |
67 | ␊ |
68 | #if defined(__i386__)␊ |
69 | ␊ |
70 | #define S_PC␉ (%esp)␊ |
71 | #define S_ARG0␉ 4(%esp)␊ |
72 | #define S_ARG1␉ 8(%esp)␊ |
73 | #define S_ARG2␉12(%esp)␊ |
74 | #define S_ARG3␉16(%esp)␊ |
75 | #define S_ARG4␉20(%esp)␊ |
76 | ␊ |
77 | #define FRAME␉pushl %ebp; movl %esp, %ebp␊ |
78 | #define EMARF␉leave␊ |
79 | ␊ |
80 | #define B_LINK␉ (%ebp)␊ |
81 | #define B_PC␉ 4(%ebp)␊ |
82 | #define B_ARG0␉ 8(%ebp)␊ |
83 | #define B_ARG1␉12(%ebp)␊ |
84 | #define B_ARG2␉16(%ebp)␊ |
85 | #define B_ARG3␉20(%ebp)␊ |
86 | ␊ |
87 | #elif defined(__x86_64__)␊ |
88 | ␊ |
89 | #define S_PC␉ (%rsp)␊ |
90 | ␊ |
91 | #define FRAME␉pushq %rbp; movq %rsp, %rbp␊ |
92 | #define EMARF␉leave␊ |
93 | ␊ |
94 | #define B_LINK␉ (%rbp)␊ |
95 | #define B_PC␉ 8(%rbp)␊ |
96 | ␊ |
97 | #else␊ |
98 | #error unsupported architecture␊ |
99 | #endif␊ |
100 | ␊ |
101 | /* There is another definition of ALIGN for .c sources */␊ |
102 | #ifdef ASSEMBLER␊ |
103 | #define ALIGN 4,0x90␊ |
104 | #endif /* ASSEMBLER */␊ |
105 | ␊ |
106 | #ifndef FALIGN␊ |
107 | #define FALIGN ALIGN␊ |
108 | #endif␊ |
109 | ␊ |
110 | #define LB(x,n) n␊ |
111 | #if␉__STDC__␊ |
112 | #ifndef __NO_UNDERSCORES__␊ |
113 | #define␉LCL(x)␉L ## x␊ |
114 | #define EXT(x) _ ## x␊ |
115 | #define LEXT(x) _ ## x ## :␊ |
116 | #else␊ |
117 | #define␉LCL(x)␉.L ## x␊ |
118 | #define EXT(x) x␊ |
119 | #define LEXT(x) x ## :␊ |
120 | #endif␊ |
121 | #define LBc(x,n) n ## :␊ |
122 | #define LBb(x,n) n ## b␊ |
123 | #define LBf(x,n) n ## f␊ |
124 | #else /* __STDC__ */␊ |
125 | #ifndef __NO_UNDERSCORES__␊ |
126 | #define LCL(x) L/**/x␊ |
127 | #define EXT(x) _/**/x␊ |
128 | #define LEXT(x) _/**/x/**/:␊ |
129 | #else /* __NO_UNDERSCORES__ */␊ |
130 | #define␉LCL(x)␉.L/**/x␊ |
131 | #define EXT(x) x␊ |
132 | #define LEXT(x) x/**/:␊ |
133 | #endif /* __NO_UNDERSCORES__ */␊ |
134 | #define LBc(x,n) n/**/:␊ |
135 | #define LBb(x,n) n/**/b␊ |
136 | #define LBf(x,n) n/**/f␊ |
137 | #endif /* __STDC__ */␊ |
138 | ␊ |
139 | #define SVC .byte 0x9a; .long 0; .word 0x7␊ |
140 | ␊ |
141 | #define RPC_SVC .byte 0x9a; .long 0; .word 0xf␊ |
142 | ␊ |
143 | #define String␉.asciz␊ |
144 | #define Value␉.word␊ |
145 | #define Times(a,b) (a*b)␊ |
146 | #define Divide(a,b) (a/b)␊ |
147 | ␊ |
148 | #define INB␉inb␉%dx, %al␊ |
149 | #define OUTB␉outb␉%al, %dx␊ |
150 | #define INL␉inl␉%dx, %eax␊ |
151 | #define OUTL␉outl␉%eax, %dx␊ |
152 | ␊ |
153 | #define data16␉.byte 0x66␊ |
154 | #define addr16␉.byte 0x67␊ |
155 | ␊ |
156 | #if !GPROF␊ |
157 | #define MCOUNT␊ |
158 | ␊ |
159 | #elif defined(__SHARED__)␊ |
160 | #define MCOUNT␉␉; .data;\␊ |
161 | ␉␉␉.align ALIGN;\␊ |
162 | ␉␉␉LBc(x, 8) .long 0;\␊ |
163 | ␉␉␉.text;\␊ |
164 | ␉␉␉Gpush;\␊ |
165 | ␉␉␉Gload;\␊ |
166 | ␉␉␉leal Gotoff(LBb(x,8)),%edx;\␊ |
167 | ␉␉␉Egaddr(%eax,_mcount_ptr);\␊ |
168 | ␉␉␉Gpop;\␊ |
169 | ␉␉␉call *(%eax);␊ |
170 | ␊ |
171 | #else␉/* !GPROF, !__SHARED__ */␊ |
172 | #define MCOUNT␉␉; call mcount;␊ |
173 | #endif /* GPROF */␊ |
174 | ␊ |
175 | #ifdef __ELF__␊ |
176 | #define ELF_FUNC(x)␉.type x,@function␊ |
177 | #define ELF_DATA(x)␉.type x,@object␊ |
178 | #define ELF_SIZE(x,s)␉.size x,s␊ |
179 | #else␊ |
180 | #define ELF_FUNC(x)␊ |
181 | #define ELF_DATA(x)␊ |
182 | #define ELF_SIZE(x,s)␊ |
183 | #endif␊ |
184 | ␊ |
185 | #define␉Entry(x)␉.globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x)␊ |
186 | #define␉ENTRY(x)␉Entry(x) MCOUNT␊ |
187 | #define␉ENTRY2(x,y)␉.globl EXT(x); .globl EXT(y); \␊ |
188 | ␉␉␉ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \␊ |
189 | ␉␉␉.align FALIGN; LEXT(x); LEXT(y) \␊ |
190 | ␉␉␉MCOUNT␊ |
191 | #if __STDC__␊ |
192 | #define␉ASENTRY(x) ␉.globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT␊ |
193 | #else␊ |
194 | #define␉ASENTRY(x) ␉.globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT␊ |
195 | #endif /* __STDC__ */␊ |
196 | ␊ |
197 | #define␉DATA(x)␉␉.globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x)␊ |
198 | ␊ |
199 | #define End(x)␉␉ELF_SIZE(x,.-x)␊ |
200 | #define END(x)␉␉End(EXT(x))␊ |
201 | #define ENDDATA(x)␉END(x)␊ |
202 | #define Enddata(x)␉End(x)␊ |
203 | ␊ |
204 | /*␊ |
205 | * ELF shared library accessor macros.␊ |
206 | * Gpush saves the %ebx register used for the GOT address␊ |
207 | * Gpop pops %ebx if we need a GOT␊ |
208 | * Gload loads %ebx with the GOT address if shared libraries are used␊ |
209 | * Gcall calls an external function.␊ |
210 | * Gotoff allows you to reference local labels.␊ |
211 | * Gotoff2 allows you to reference local labels with an index reg.␊ |
212 | * Gotoff3 allows you to reference local labels with an index reg & size.␊ |
213 | * Gaddr loads up a register with an address of an external item.␊ |
214 | * Gstack is the number of bytes that Gpush pushes on the stack.␊ |
215 | *␊ |
216 | * Varients of the above with E or L prefixes do EXT(name) or LCL(name)␊ |
217 | * respectively.␊ |
218 | */␊ |
219 | ␊ |
220 | #ifndef __SHARED__␊ |
221 | #define Gpush␊ |
222 | #define Gpop␊ |
223 | #define Gload␊ |
224 | #define Gcall(func)␉␉call func␊ |
225 | #define Gotoff(lab)␉␉lab␊ |
226 | #define Gotoff2(l,r)␉␉l(r)␊ |
227 | #define Gotoff3(l,r,s)␉␉l(,r,s)␊ |
228 | #define Gaddr(to,lab)␉␉movl $lab,to␊ |
229 | #define Gcmp(lab,reg)␉␉cmpl $lab,reg␊ |
230 | #define Gmemload(lab,reg)␉movl lab,reg␊ |
231 | #define Gmemstore(reg,lab,tmp)␉movl reg,lab␊ |
232 | #define Gstack␉␉␉0␊ |
233 | ␊ |
234 | #else␊ |
235 | #ifdef __ELF__␉␉␉/* ELF shared libraries */␊ |
236 | #define Gpush␉␉␉pushl %ebx␊ |
237 | #define Gpop␉␉␉popl %ebx␊ |
238 | #define Gload␉␉␉call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx␊ |
239 | #define Gcall(func)␉␉call EXT(func)@PLT␊ |
240 | #define Gotoff(lab)␉␉lab@GOTOFF(%ebx)␊ |
241 | #define Gotoff2(l,r)␉␉l@GOTOFF(%ebx,r)␊ |
242 | #define Gotoff3(l,r,s)␉␉l@GOTOFF(%ebx,r,s)␊ |
243 | #define Gaddr(to,lab)␉␉movl lab@GOT(%ebx),to␊ |
244 | #define Gcmp(lab,reg)␉␉cmpl reg,lab@GOT(%ebx)␊ |
245 | #define Gmemload(lab,reg)␉movl lab@GOT(%ebx),reg; movl (reg),reg␊ |
246 | #define Gmemstore(reg,lab,tmp)␉movl lab@GOT(%ebx),tmp; movl reg,(tmp)␊ |
247 | #define Gstack␉␉␉4␊ |
248 | ␊ |
249 | #else␉␉␉␉/* ROSE shared libraries */␊ |
250 | #define Gpush␊ |
251 | #define Gpop␊ |
252 | #define Gload␊ |
253 | #define Gcall(func)␉␉call *9f; .data; .align ALIGN; 9: .long func; .text␊ |
254 | #define Gotoff(lab)␉␉lab␊ |
255 | #define Gotoff2(l,r)␉␉l(r)␊ |
256 | #define Gotoff3(l,r,s)␉␉l(,r,s)␊ |
257 | #define Gaddr(to,lab)␉␉movl 9f,to; .data; .align ALIGN; 9: .long lab; .text␊ |
258 | #define Gcmp(lab,reg)␉␉cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text␊ |
259 | #define Gmemload(lab,reg)␉movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text␊ |
260 | #define Gmemstore(reg,lab,tmp)␉movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text␊ |
261 | #define Gstack␉␉␉0␊ |
262 | #endif␉/* __ELF__ */␊ |
263 | #endif␉/* __SHARED__ */␊ |
264 | ␊ |
265 | /* Egotoff is not provided, since external symbols should not use @GOTOFF␊ |
266 | relocations. */␊ |
267 | #define Egcall(func)␉␉Gcall(EXT(func))␊ |
268 | #define Egaddr(to,lab)␉␉Gaddr(to,EXT(lab))␊ |
269 | #define Egcmp(lab,reg)␉␉Gcmp(EXT(lab),reg)␊ |
270 | #define Egmemload(lab,reg)␉Gmemload(EXT(lab),reg)␊ |
271 | #define Egmemstore(reg,lab,tmp)␉Gmemstore(reg,EXT(lab),tmp)␊ |
272 | ␊ |
273 | #define Lgotoff(lab)␉␉Gotoff(LCL(lab))␊ |
274 | #define Lgotoff2(l,r)␉␉Gotoff2(LCL(l),r)␊ |
275 | #define Lgotoff3(l,r,s)␉␉Gotoff3(LCL(l),r,s)␊ |
276 | #define Lgcmp(lab,reg)␉␉Gcmp(LCL(lab),reg)␊ |
277 | #define Lgmemload(lab,reg)␉movl Lgotoff(lab),reg␊ |
278 | #define Lgmemstore(reg,lab,tmp)␉movl reg,Lgotoff(lab)␊ |
279 | ␊ |
280 | #ifndef ASSEMBLER␊ |
281 | /* These defines are here for .c files that wish to reference global symbols␊ |
282 | * within __asm__ statements. ␊ |
283 | */␊ |
284 | #ifndef __NO_UNDERSCORES__␊ |
285 | #define CC_SYM_PREFIX "_"␊ |
286 | #else␊ |
287 | #define CC_SYM_PREFIX ""␊ |
288 | #endif /* __NO_UNDERSCORES__ */␊ |
289 | #endif /* ASSEMBLER */␊ |
290 | ␊ |
291 | /*␊ |
292 | * The following macros make calls into C code.␊ |
293 | * They dynamically align the stack to 16 bytes.␊ |
294 | */␊ |
295 | #if defined(__i386__)␊ |
296 | /*␊ |
297 | * Arguments are moved (not pushed) onto the correctly aligned stack.␊ |
298 | * NOTE: ESI is destroyed in the process, and hence cannot␊ |
299 | * be directly used as a parameter. Users of this macro must␊ |
300 | * independently preserve ESI (a non-volatile) if the routine is␊ |
301 | * intended to be called from C, for instance.␊ |
302 | */␊ |
303 | ␊ |
304 | #define CCALL(fn)␉␉␉\␊ |
305 | ␉movl␉%esp, %esi␉␉;\␊ |
306 | ␉andl␉$0xFFFFFFF0, %esp␉;\␊ |
307 | ␉call␉EXT(fn)␉␉␉;\␊ |
308 | ␉movl␉%esi, %esp␊ |
309 | ␊ |
310 | #define CCALL1(fn, arg1)␉␉\␊ |
311 | ␉movl␉%esp, %esi␉␉;\␊ |
312 | ␉subl␉$4, %esp␉␉;\␊ |
313 | ␉andl␉$0xFFFFFFF0, %esp␉;\␊ |
314 | ␉movl␉arg1, (%esp)␉␉;\␊ |
315 | ␉call␉EXT(fn)␉␉␉;\␊ |
316 | ␉movl␉%esi, %esp␊ |
317 | ␊ |
318 | #define CCALL2(fn, arg1, arg2)␉␉\␊ |
319 | ␉movl␉%esp, %esi␉␉;\␊ |
320 | ␉subl␉$8, %esp␉␉;\␊ |
321 | ␉andl␉$0xFFFFFFF0, %esp␉;\␊ |
322 | ␉movl␉arg2, 4(%esp)␉␉;\␊ |
323 | ␉movl␉arg1, (%esp)␉␉;\␊ |
324 | ␉call␉EXT(fn)␉␉␉;\␊ |
325 | ␉movl␉%esi, %esp␊ |
326 | ␊ |
327 | /* This variant exists to permit adjustment of the stack by "dtrace" */␊ |
328 | #define CCALL1WITHSP(fn, arg1)␉␉\␊ |
329 | ␉movl␉%esp, %esi␉␉;\␊ |
330 | ␉subl␉$12, %esp␉␉;\␊ |
331 | ␉andl␉$0xFFFFFFF0, %esp␉;\␊ |
332 | ␉movl␉%esi, 8(%esp)␉␉;\␊ |
333 | ␉leal␉8(%esp), %esi␉␉;\␊ |
334 | ␉movl␉%esi, 4(%esp)␉␉;\␊ |
335 | ␉movl␉arg1, (%esp)␉␉;\␊ |
336 | ␉call␉EXT(fn)␉␉␉;\␊ |
337 | ␉movl␉8(%esp), %esp␊ |
338 | ␊ |
339 | /*␊ |
340 | * CCALL5 is used for callee functions with 3 arguments but␊ |
341 | * where arg2 (a3:a2) and arg3 (a5:a4) are 64-bit values.␊ |
342 | */␊ |
343 | #define CCALL5(fn, a1, a2, a3, a4, a5)␉\␊ |
344 | ␉movl␉%esp, %esi␉␉;\␊ |
345 | ␉subl␉$20, %esp␉␉;\␊ |
346 | ␉andl␉$0xFFFFFFF0, %esp␉;\␊ |
347 | ␉movl␉a5, 16(%esp)␉␉;\␊ |
348 | ␉movl␉a4, 12(%esp)␉␉;\␊ |
349 | ␉movl␉a3, 8(%esp)␉␉;\␊ |
350 | ␉movl␉a2, 4(%esp)␉␉;\␊ |
351 | ␉movl␉a1, (%esp)␉␉;\␊ |
352 | ␉call␉EXT(fn)␉␉␉;\␊ |
353 | ␉movl␉%esi, %esp␊ |
354 | ␊ |
355 | #elif defined(__x86_64__)␊ |
356 | ␊ |
357 | /* This variant exists to permit adjustment of the stack by "dtrace" */␊ |
358 | #define CCALLWITHSP(fn)␉␉␉␉ \␊ |
359 | ␉mov␉%rsp, %r12␉␉␉;\␊ |
360 | ␉sub␉$8, %rsp␉␉␉;\␊ |
361 | ␉and␉$0xFFFFFFFFFFFFFFF0, %rsp␉;\␊ |
362 | ␉mov␉%r12, (%rsp)␉␉␉;\␊ |
363 | ␉leaq␉(%rsp), %rsi␉␉␉;\␊ |
364 | ␉call␉EXT(fn)␉␉␉␉;\␊ |
365 | ␉mov␉(%rsp), %rsp␊ |
366 | ␉␊ |
367 | #define CCALL(fn)␉␉␉␉ \␊ |
368 | ␉mov␉%rsp, %r12␉␉␉;\␊ |
369 | ␉and␉$0xFFFFFFFFFFFFFFF0, %rsp␉;\␊ |
370 | ␉call␉EXT(fn)␉␉␉␉;\␊ |
371 | ␉mov␉%r12, %rsp␊ |
372 | ␊ |
373 | #define CCALL1(fn, arg1) ␉␉␉ \␊ |
374 | ␉mov␉arg1, %rdi ␉␉␉;\␊ |
375 | ␉CCALL(fn)␊ |
376 | ␊ |
377 | #define CCALL2(fn, arg1, arg2)␉␉ ␉ \␊ |
378 | ␉mov␉arg1, %rdi ␉␉␉;\␊ |
379 | ␉CCALL(fn)␊ |
380 | ␊ |
381 | #define CCALL3(fn, arg1, arg2, arg3) ␉␉ \␊ |
382 | ␉mov␉arg1, %rdi ␉␉␉;\␊ |
383 | ␉mov␉arg2, %rsi ␉␉␉;\␊ |
384 | ␉mov␉arg3, %rdx ␉␉␉;\␊ |
385 | ␉CCALL(fn)␊ |
386 | ␊ |
387 | #else␊ |
388 | #error unsupported architecture␊ |
389 | #endif␊ |
390 | ␊ |
391 | #endif /* _I386_ASM_H_ */␊ |
392 | |