]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/asm.h
xnu-1699.22.73.tar.gz
[apple/xnu.git] / osfmk / i386 / asm.h
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 #ifdef MACH_KERNEL
65 #include <mach_kdb.h>
66 #else /* !MACH_KERNEL */
67 #define MACH_KDB 0
68 #endif /* !MACH_KERNEL */
69
70
71 #if defined(MACH_KERNEL) || defined(_KERNEL)
72 #include <gprof.h>
73 #endif /* MACH_KERNEL || _KERNEL */
74
75 #if defined(__i386__)
76
77 #define S_PC (%esp)
78 #define S_ARG0 4(%esp)
79 #define S_ARG1 8(%esp)
80 #define S_ARG2 12(%esp)
81 #define S_ARG3 16(%esp)
82 #define S_ARG4 20(%esp)
83
84 #define FRAME pushl %ebp; movl %esp, %ebp
85 #define EMARF leave
86
87 #define B_LINK (%ebp)
88 #define B_PC 4(%ebp)
89 #define B_ARG0 8(%ebp)
90 #define B_ARG1 12(%ebp)
91 #define B_ARG2 16(%ebp)
92 #define B_ARG3 20(%ebp)
93
94 #elif defined(__x86_64__)
95
96 #define S_PC (%rsp)
97
98 #define FRAME pushq %rbp; movq %rsp, %rbp
99 #define EMARF leave
100
101 #define B_LINK (%rbp)
102 #define B_PC 8(%rbp)
103
104 #else
105 #error unsupported architecture
106 #endif
107
108 /* There is another definition of ALIGN for .c sources */
109 #ifdef ASSEMBLER
110 #define ALIGN 4,0x90
111 #endif /* ASSEMBLER */
112
113 #ifndef FALIGN
114 #define FALIGN ALIGN
115 #endif
116
117 #define LB(x,n) n
118 #if __STDC__
119 #ifndef __NO_UNDERSCORES__
120 #define LCL(x) L ## x
121 #define EXT(x) _ ## x
122 #define LEXT(x) _ ## x ## :
123 #else
124 #define LCL(x) .L ## x
125 #define EXT(x) x
126 #define LEXT(x) x ## :
127 #endif
128 #define LBc(x,n) n ## :
129 #define LBb(x,n) n ## b
130 #define LBf(x,n) n ## f
131 #else /* __STDC__ */
132 #ifndef __NO_UNDERSCORES__
133 #define LCL(x) L/**/x
134 #define EXT(x) _/**/x
135 #define LEXT(x) _/**/x/**/:
136 #else /* __NO_UNDERSCORES__ */
137 #define LCL(x) .L/**/x
138 #define EXT(x) x
139 #define LEXT(x) x/**/:
140 #endif /* __NO_UNDERSCORES__ */
141 #define LBc(x,n) n/**/:
142 #define LBb(x,n) n/**/b
143 #define LBf(x,n) n/**/f
144 #endif /* __STDC__ */
145
146 #define SVC .byte 0x9a; .long 0; .word 0x7
147
148 #define RPC_SVC .byte 0x9a; .long 0; .word 0xf
149
150 #define String .asciz
151 #define Value .word
152 #define Times(a,b) (a*b)
153 #define Divide(a,b) (a/b)
154
155 #define INB inb %dx, %al
156 #define OUTB outb %al, %dx
157 #define INL inl %dx, %eax
158 #define OUTL outl %eax, %dx
159
160 #define data16 .byte 0x66
161 #define addr16 .byte 0x67
162
163 #if !GPROF
164 #define MCOUNT
165
166 #elif defined(__SHARED__)
167 #define MCOUNT ; .data;\
168 .align ALIGN;\
169 LBc(x, 8) .long 0;\
170 .text;\
171 Gpush;\
172 Gload;\
173 leal Gotoff(LBb(x,8)),%edx;\
174 Egaddr(%eax,_mcount_ptr);\
175 Gpop;\
176 call *(%eax);
177
178 #else /* !GPROF, !__SHARED__ */
179 #define MCOUNT ; call mcount;
180 #endif /* GPROF */
181
182 #ifdef __ELF__
183 #define ELF_FUNC(x) .type x,@function
184 #define ELF_DATA(x) .type x,@object
185 #define ELF_SIZE(x,s) .size x,s
186 #else
187 #define ELF_FUNC(x)
188 #define ELF_DATA(x)
189 #define ELF_SIZE(x,s)
190 #endif
191
192 #define Entry(x) .globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x)
193 #define ENTRY(x) Entry(x) MCOUNT
194 #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
195 ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \
196 .align FALIGN; LEXT(x); LEXT(y) \
197 MCOUNT
198 #if __STDC__
199 #define ASENTRY(x) .globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT
200 #else
201 #define ASENTRY(x) .globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT
202 #endif /* __STDC__ */
203
204 #define DATA(x) .globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x)
205
206 #define End(x) ELF_SIZE(x,.-x)
207 #define END(x) End(EXT(x))
208 #define ENDDATA(x) END(x)
209 #define Enddata(x) End(x)
210
211 /*
212 * ELF shared library accessor macros.
213 * Gpush saves the %ebx register used for the GOT address
214 * Gpop pops %ebx if we need a GOT
215 * Gload loads %ebx with the GOT address if shared libraries are used
216 * Gcall calls an external function.
217 * Gotoff allows you to reference local labels.
218 * Gotoff2 allows you to reference local labels with an index reg.
219 * Gotoff3 allows you to reference local labels with an index reg & size.
220 * Gaddr loads up a register with an address of an external item.
221 * Gstack is the number of bytes that Gpush pushes on the stack.
222 *
223 * Varients of the above with E or L prefixes do EXT(name) or LCL(name)
224 * respectively.
225 */
226
227 #ifndef __SHARED__
228 #define Gpush
229 #define Gpop
230 #define Gload
231 #define Gcall(func) call func
232 #define Gotoff(lab) lab
233 #define Gotoff2(l,r) l(r)
234 #define Gotoff3(l,r,s) l(,r,s)
235 #define Gaddr(to,lab) movl $lab,to
236 #define Gcmp(lab,reg) cmpl $lab,reg
237 #define Gmemload(lab,reg) movl lab,reg
238 #define Gmemstore(reg,lab,tmp) movl reg,lab
239 #define Gstack 0
240
241 #else
242 #ifdef __ELF__ /* ELF shared libraries */
243 #define Gpush pushl %ebx
244 #define Gpop popl %ebx
245 #define Gload call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx
246 #define Gcall(func) call EXT(func)@PLT
247 #define Gotoff(lab) lab@GOTOFF(%ebx)
248 #define Gotoff2(l,r) l@GOTOFF(%ebx,r)
249 #define Gotoff3(l,r,s) l@GOTOFF(%ebx,r,s)
250 #define Gaddr(to,lab) movl lab@GOT(%ebx),to
251 #define Gcmp(lab,reg) cmpl reg,lab@GOT(%ebx)
252 #define Gmemload(lab,reg) movl lab@GOT(%ebx),reg; movl (reg),reg
253 #define Gmemstore(reg,lab,tmp) movl lab@GOT(%ebx),tmp; movl reg,(tmp)
254 #define Gstack 4
255
256 #else /* ROSE shared libraries */
257 #define Gpush
258 #define Gpop
259 #define Gload
260 #define Gcall(func) call *9f; .data; .align ALIGN; 9: .long func; .text
261 #define Gotoff(lab) lab
262 #define Gotoff2(l,r) l(r)
263 #define Gotoff3(l,r,s) l(,r,s)
264 #define Gaddr(to,lab) movl 9f,to; .data; .align ALIGN; 9: .long lab; .text
265 #define Gcmp(lab,reg) cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text
266 #define Gmemload(lab,reg) movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text
267 #define Gmemstore(reg,lab,tmp) movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text
268 #define Gstack 0
269 #endif /* __ELF__ */
270 #endif /* __SHARED__ */
271
272 /* Egotoff is not provided, since external symbols should not use @GOTOFF
273 relocations. */
274 #define Egcall(func) Gcall(EXT(func))
275 #define Egaddr(to,lab) Gaddr(to,EXT(lab))
276 #define Egcmp(lab,reg) Gcmp(EXT(lab),reg)
277 #define Egmemload(lab,reg) Gmemload(EXT(lab),reg)
278 #define Egmemstore(reg,lab,tmp) Gmemstore(reg,EXT(lab),tmp)
279
280 #define Lgotoff(lab) Gotoff(LCL(lab))
281 #define Lgotoff2(l,r) Gotoff2(LCL(l),r)
282 #define Lgotoff3(l,r,s) Gotoff3(LCL(l),r,s)
283 #define Lgcmp(lab,reg) Gcmp(LCL(lab),reg)
284 #define Lgmemload(lab,reg) movl Lgotoff(lab),reg
285 #define Lgmemstore(reg,lab,tmp) movl reg,Lgotoff(lab)
286
287 #ifdef ASSEMBLER
288 #if MACH_KDB
289 #include <ddb/stab.h>
290 /*
291 * This pseudo-assembler line is added so that there will be at least
292 * one N_SO entry in the symbol stable to define the current file name.
293 */
294 #endif /* MACH_KDB */
295
296 #else /* NOT ASSEMBLER */
297
298 /* These defines are here for .c files that wish to reference global symbols
299 * within __asm__ statements.
300 */
301 #ifndef __NO_UNDERSCORES__
302 #define CC_SYM_PREFIX "_"
303 #else
304 #define CC_SYM_PREFIX ""
305 #endif /* __NO_UNDERSCORES__ */
306 #endif /* ASSEMBLER */
307
308 /*
309 * The following macros make calls into C code.
310 * They dynamically align the stack to 16 bytes.
311 */
312 #if defined(__i386__)
313 /*
314 * Arguments are moved (not pushed) onto the correctly aligned stack.
315 * NOTE: ESI is destroyed in the process, and hence cannot
316 * be directly used as a parameter. Users of this macro must
317 * independently preserve ESI (a non-volatile) if the routine is
318 * intended to be called from C, for instance.
319 */
320
321 #define CCALL(fn) \
322 movl %esp, %esi ;\
323 andl $0xFFFFFFF0, %esp ;\
324 call EXT(fn) ;\
325 movl %esi, %esp
326
327 #define CCALL1(fn, arg1) \
328 movl %esp, %esi ;\
329 subl $4, %esp ;\
330 andl $0xFFFFFFF0, %esp ;\
331 movl arg1, (%esp) ;\
332 call EXT(fn) ;\
333 movl %esi, %esp
334
335 #define CCALL2(fn, arg1, arg2) \
336 movl %esp, %esi ;\
337 subl $8, %esp ;\
338 andl $0xFFFFFFF0, %esp ;\
339 movl arg2, 4(%esp) ;\
340 movl arg1, (%esp) ;\
341 call EXT(fn) ;\
342 movl %esi, %esp
343
344 /* This variant exists to permit adjustment of the stack by "dtrace" */
345 #define CCALL1WITHSP(fn, arg1) \
346 movl %esp, %esi ;\
347 subl $12, %esp ;\
348 andl $0xFFFFFFF0, %esp ;\
349 movl %esi, 8(%esp) ;\
350 leal 8(%esp), %esi ;\
351 movl %esi, 4(%esp) ;\
352 movl arg1, (%esp) ;\
353 call EXT(fn) ;\
354 movl 8(%esp), %esp
355
356 /*
357 * CCALL5 is used for callee functions with 3 arguments but
358 * where arg2 (a3:a2) and arg3 (a5:a4) are 64-bit values.
359 */
360 #define CCALL5(fn, a1, a2, a3, a4, a5) \
361 movl %esp, %esi ;\
362 subl $20, %esp ;\
363 andl $0xFFFFFFF0, %esp ;\
364 movl a5, 16(%esp) ;\
365 movl a4, 12(%esp) ;\
366 movl a3, 8(%esp) ;\
367 movl a2, 4(%esp) ;\
368 movl a1, (%esp) ;\
369 call EXT(fn) ;\
370 movl %esi, %esp
371
372 #elif defined(__x86_64__)
373
374 /* This variant exists to permit adjustment of the stack by "dtrace" */
375 #define CCALLWITHSP(fn) \
376 mov %rsp, %r12 ;\
377 sub $8, %rsp ;\
378 and $0xFFFFFFFFFFFFFFF0, %rsp ;\
379 mov %r12, (%rsp) ;\
380 leaq (%rsp), %rsi ;\
381 call EXT(fn) ;\
382 mov (%rsp), %rsp
383
384 #define CCALL(fn) \
385 mov %rsp, %r12 ;\
386 and $0xFFFFFFFFFFFFFFF0, %rsp ;\
387 call EXT(fn) ;\
388 mov %r12, %rsp
389
390 #define CCALL1(fn, arg1) \
391 mov arg1, %rdi ;\
392 CCALL(fn)
393
394 #define CCALL2(fn, arg1, arg2) \
395 mov arg1, %rdi ;\
396 CCALL(fn)
397
398 #define CCALL3(fn, arg1, arg2, arg3) \
399 mov arg1, %rdi ;\
400 mov arg2, %rsi ;\
401 mov arg3, %rdx ;\
402 CCALL(fn)
403
404 #else
405 #error unsupported architecture
406 #endif
407
408 #endif /* _I386_ASM_H_ */