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