1 | /*␊ |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * ␊ |
5 | * This file contains Original Code and/or Modifications of Original Code␊ |
6 | * as defined in and that are subject to the Apple Public Source License␊ |
7 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
8 | * compliance with the License. Please obtain a copy of the License at␊ |
9 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
10 | * file.␊ |
11 | * ␊ |
12 | * The Original Code and all software distributed under the License are␊ |
13 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
17 | * Please see the License for the specific language governing rights and␊ |
18 | * limitations under the License.␊ |
19 | * ␊ |
20 | * Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.␊ |
21 | *␊ |
22 | *␉File:␉architecture/i386/asm_help.h␊ |
23 | *␉Author:␉Mike DeMoney, NeXT Computer, Inc.␊ |
24 | *␉Modified for i386 by: Bruce Martin, NeXT Computer, Inc.␊ |
25 | *␊ |
26 | *␉This header file defines macros useful when writing assembly code␊ |
27 | *␉for the Intel i386 family processors.␊ |
28 | *␊ |
29 | * HISTORY␊ |
30 | * 10-Mar-92 Bruce Martin (bmartin@next.com)␊ |
31 | *␉Adapted to i386␊ |
32 | * 23-Jan-91 Mike DeMoney (mike@next.com)␊ |
33 | *␉Created.␊ |
34 | */␊ |
35 | ␊ |
36 | #ifndef␉_ARCH_I386_ASM_HELP_H_␊ |
37 | #define␉_ARCH_I386_ASM_HELP_H_␊ |
38 | ␊ |
39 | #include␉<architecture/i386/reg_help.h>␊ |
40 | ␊ |
41 | ␊ |
42 | #ifdef␉__ASSEMBLER__␊ |
43 | ␊ |
44 | #define ALIGN␉␉␉␉␉␉\␊ |
45 | ␉.align␉2, 0x90␊ |
46 | ␊ |
47 | #define␉ROUND_TO_STACK(len)␉␉␉␉\␊ |
48 | ␉(((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)␊ |
49 | ␊ |
50 | #ifdef notdef␊ |
51 | #if defined(__i386__)␊ |
52 | #define CALL_MCOUNT␉␉␉␉␉␉\␊ |
53 | ␉pushl␉%ebp␉␉␉␉␉␉;\␊ |
54 | ␉movl␉%esp, %ebp␉␉␉␉␉;\␊ |
55 | ␉.data␉␉␉␉␉␉␉;\␊ |
56 | ␉1: .long 0␉␉␉␉␉␉;\␊ |
57 | ␉.text␉␉␉␉␉␉␉;\␊ |
58 | ␉lea 9b,%edx␉␉␉␉␉␉;\␊ |
59 | ␉call mcount␉␉␉␉␉␉;\␊ |
60 | ␉popl␉%ebp␉␉␉␉␉␉;␊ |
61 | #elif defined(__x86_64__)␊ |
62 | #define CALL_MCOUNT␉␉␉␉␉␉\␊ |
63 | ␉pushq␉%rbp␉␉␉␉␉␉;\␊ |
64 | ␉movq␉%rsp, %rbp␉␉␉␉␉;\␊ |
65 | ␉.data␉␉␉␉␉␉␉;\␊ |
66 | ␉1: .quad 0␉␉␉␉␉␉;\␊ |
67 | ␉.text␉␉␉␉␉␉␉;\␊ |
68 | ␉lea 9b,%r13␉␉␉␉␉␉;\␊ |
69 | ␉call mcount␉␉␉␉␉␉;\␊ |
70 | ␉popq␉%rbp␉␉␉␉␉;␊ |
71 | #endif␊ |
72 | #else␊ |
73 | #define CALL_MCOUNT␊ |
74 | #endif␊ |
75 | ␊ |
76 | /*␊ |
77 | * Prologue for functions that may call other functions. Saves␊ |
78 | * registers and sets up a C frame.␊ |
79 | */␊ |
80 | #if defined(__i386__)␊ |
81 | #define NESTED_FUNCTION_PROLOGUE(localvarsize)␉␉␉\␊ |
82 | ␉.set␉__framesize,ROUND_TO_STACK(localvarsize)␉;\␊ |
83 | ␉.set␉__nested_function, 1␉␉␉␉;\␊ |
84 | ␉CALL_MCOUNT␉␉␉␉␉␉\␊ |
85 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
86 | ␉ pushl␉%ebp␉␉␉␉␉␉;\␊ |
87 | ␉ movl␉%esp, %ebp␉␉␉␉␉;\␊ |
88 | ␉ subl␉$__framesize, %esp␉␉␉␉;\␊ |
89 | ␉.endif␉␉␉␉␉␉␉;\␊ |
90 | ␉pushl␉%edi␉␉␉␉␉␉;\␊ |
91 | ␉pushl␉%esi␉␉␉␉␉␉;\␊ |
92 | ␉pushl␉%ebx␊ |
93 | #elif defined(__x86_64__)␊ |
94 | #define NESTED_FUNCTION_PROLOGUE(localvarsize)␉␉␉\␊ |
95 | ␉.set␉__framesize,ROUND_TO_STACK(localvarsize)␉;\␊ |
96 | ␉.set␉__nested_function, 1␉␉␉␉;\␊ |
97 | ␉CALL_MCOUNT␉␉␉␉␉␉\␊ |
98 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
99 | ␉ pushq␉%rbp␉␉␉␉␉␉;\␊ |
100 | ␉ movq␉%rsp, %rbp␉␉␉␉␉;\␊ |
101 | ␉ subq␉$__framesize, %rsp␉␉␉␉;\␊ |
102 | ␉.endif␉␉␉␉␉␉␉;␊ |
103 | #endif␊ |
104 | ␊ |
105 | /*␊ |
106 | * Prologue for functions that do not call other functions. Does not␊ |
107 | * save registers (this is the functions responsibility). Does set␊ |
108 | * up a C frame.␊ |
109 | */␊ |
110 | #if defined(__i386__)␊ |
111 | #define LEAF_FUNCTION_PROLOGUE(localvarsize)␉␉␉\␊ |
112 | ␉.set␉__framesize,ROUND_TO_STACK(localvarsize)␉;\␊ |
113 | ␉.set␉__nested_function, 0␉␉␉␉;\␊ |
114 | ␉CALL_MCOUNT␉␉␉␉␉␉\␊ |
115 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
116 | ␉ pushl␉%ebp␉␉␉␉␉␉;\␊ |
117 | ␉ movl␉%esp, %ebp␉␉␉␉␉;\␊ |
118 | ␉ subl␉$__framesize, %esp␉␉␉␉;\␊ |
119 | ␉.endif␊ |
120 | #elif defined(__x86_64__)␊ |
121 | #define LEAF_FUNCTION_PROLOGUE(localvarsize)␉␉␉\␊ |
122 | ␉.set␉__framesize,ROUND_TO_STACK(localvarsize)␉;\␊ |
123 | ␉.set␉__nested_function, 0␉␉␉␉;\␊ |
124 | ␉CALL_MCOUNT␉␉␉␉␉␉\␊ |
125 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
126 | ␉ pushq␉%rbp␉␉␉␉␉␉;\␊ |
127 | ␉ movq␉%rsp, %rbp␉␉␉␉␉;\␊ |
128 | ␉ subq␉$__framesize, %rsp␉␉␉␉;\␊ |
129 | ␉.endif␊ |
130 | #endif␊ |
131 | ␊ |
132 | /*␊ |
133 | * Epilogue for any function.␊ |
134 | *␊ |
135 | * We assume that all Leaf functions will be responsible for saving any␊ |
136 | * local registers they clobber.␊ |
137 | */␊ |
138 | #if defined(__i386__)␊ |
139 | #define FUNCTION_EPILOGUE␉␉␉␉␉\␊ |
140 | ␉.if __nested_function␉␉␉␉␉;\␊ |
141 | ␉ popl␉%ebx␉␉␉␉␉␉;\␊ |
142 | ␉ popl␉%esi␉␉␉␉␉␉;\␊ |
143 | ␉ popl␉%edi␉␉␉␉␉␉;\␊ |
144 | ␉.endif␉␉␉␉␉␉␉;\␊ |
145 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
146 | ␉ movl␉%ebp, %esp␉␉␉␉␉;\␊ |
147 | ␉ popl␉%ebp␉␉␉␉␉␉;\␊ |
148 | ␉.endif␉␉␉␉␉␉␉;\␊ |
149 | ␉ret␊ |
150 | #elif defined(__x86_64__)␊ |
151 | #define FUNCTION_EPILOGUE␉␉␉␉␉\␊ |
152 | ␉.if __framesize␉␉␉␉␉␉;\␊ |
153 | ␉ movq␉%rbp, %rsp␉␉␉␉␉;\␊ |
154 | ␉ popq␉%rbp␉␉␉␉␉␉;\␊ |
155 | ␉.endif␉␉␉␉␉␉␉;\␊ |
156 | ␉ret␊ |
157 | #endif␊ |
158 | ␊ |
159 | /*␊ |
160 | * Macros for declaring procedures␊ |
161 | *␊ |
162 | * Use of these macros allows ctags to have a predictable way␊ |
163 | * to find various types of declarations. They also simplify␊ |
164 | * inserting appropriate symbol table information.␊ |
165 | *␊ |
166 | * NOTE: these simple stubs will be replaced with more␊ |
167 | * complicated versions once we know what the linker and gdb␊ |
168 | * will require as far as register use masks and frame declarations.␊ |
169 | * These macros may also be ifdef'ed in the future to contain profiling␊ |
170 | * code.␊ |
171 | *␊ |
172 | */␊ |
173 | ␊ |
174 | /*␊ |
175 | * TEXT -- declare start of text segment␊ |
176 | */␊ |
177 | #define␉TEXT␉␉␉␉␉␉\␊ |
178 | ␉.text␊ |
179 | ␊ |
180 | /*␊ |
181 | * DATA -- declare start of data segment␊ |
182 | */␊ |
183 | #define DATA␉␉␉␉␉␉\␊ |
184 | ␉.data␊ |
185 | ␊ |
186 | /*␊ |
187 | * LEAF -- declare global leaf procedure␊ |
188 | * NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only␊ |
189 | * be jumped to. (A leaf may do an align.) Use a LABEL() if you␊ |
190 | * need control to flow into the label.␊ |
191 | */␊ |
192 | #define␉LEAF(name, localvarsize)␉␉␉\␊ |
193 | ␉.globl␉name␉␉␉␉␉;\␊ |
194 | ␉ALIGN␉␉␉␉␉␉;\␊ |
195 | name:␉␉␉␉␉␉␉;\␊ |
196 | ␉LEAF_FUNCTION_PROLOGUE(localvarsize)␊ |
197 | ␊ |
198 | /*␊ |
199 | * X_LEAF -- declare alternate global label for leaf␊ |
200 | */␊ |
201 | #define␉X_LEAF(name, value)␉␉␉␉\␊ |
202 | ␉.globl␉name␉␉␉␉␉;\␊ |
203 | ␉.set␉name,value␊ |
204 | ␊ |
205 | /*␊ |
206 | * P_LEAF -- declare private leaf procedure␊ |
207 | */␊ |
208 | #define␉P_LEAF(name, localvarsize)␉␉␉\␊ |
209 | ␉ALIGN␉␉␉␉␉␉;\␊ |
210 | name:␉␉␉␉␉␉␉;\␊ |
211 | ␉LEAF_FUNCTION_PROLOGUE(localvarsize)␊ |
212 | ␊ |
213 | /*␊ |
214 | * LABEL -- declare a global code label␊ |
215 | * MUST be used (rather than LEAF, NESTED, etc) if control␊ |
216 | * "flows into" the label.␊ |
217 | */␊ |
218 | #define␉LABEL(name)␉␉␉␉␉\␊ |
219 | ␉.globl␉name␉␉␉␉␉;\␊ |
220 | name:␊ |
221 | ␊ |
222 | /*␊ |
223 | * NESTED -- declare procedure that invokes other procedures␊ |
224 | */␊ |
225 | #define␉NESTED(name, localvarsize)␉␉␉\␊ |
226 | ␉.globl␉name␉␉␉␉␉;\␊ |
227 | ␉ALIGN␉␉␉␉␉␉;\␊ |
228 | name:␉␉␉␉␉␉␉;\␊ |
229 | ␉NESTED_FUNCTION_PROLOGUE(localvarsize)␊ |
230 | ␊ |
231 | /*␊ |
232 | * X_NESTED -- declare alternate global label for nested proc␊ |
233 | */␊ |
234 | #define␉X_NESTED(name, value)␉␉␉␉\␊ |
235 | ␉.globl␉name␉␉␉␉␉;\␊ |
236 | ␉.set␉name,value␊ |
237 | ␊ |
238 | /*␊ |
239 | * P_NESTED -- declare private nested procedure␊ |
240 | */␊ |
241 | #define␉P_NESTED(name, localvarsize)␉␉␉\␊ |
242 | ␉ALIGN␉␉␉␉␉␉;\␊ |
243 | name:␉␉␉␉␉␉␉;\␊ |
244 | ␉NESTED_FUNCTION_PROLOGUE(localvarsize)␊ |
245 | ␊ |
246 | /*␊ |
247 | * END -- mark end of procedure␊ |
248 | */␊ |
249 | #define␉END(name)␉␉␉␉␉\␊ |
250 | ␉FUNCTION_EPILOGUE␊ |
251 | ␊ |
252 | ␊ |
253 | /*␊ |
254 | * Storage definition macros␊ |
255 | * The main purpose of these is to allow an easy handle for ctags␊ |
256 | */␊ |
257 | ␊ |
258 | /*␊ |
259 | * IMPORT -- import symbol␊ |
260 | */␊ |
261 | #define␉IMPORT(name)␉␉␉␉␉\␊ |
262 | ␉.reference␉name␊ |
263 | ␊ |
264 | /*␊ |
265 | * ABS -- declare global absolute symbol␊ |
266 | */␊ |
267 | #define␉ABS(name, value)␉␉␉␉\␊ |
268 | ␉.globl␉name␉␉␉␉␉;\␊ |
269 | ␉.set␉name,value␊ |
270 | ␊ |
271 | /*␊ |
272 | * P_ABS -- declare private absolute symbol␊ |
273 | */␊ |
274 | #define␉P_ABS(name, value)␉␉␉␉\␊ |
275 | ␉.set␉name,value␊ |
276 | ␊ |
277 | /*␊ |
278 | * EXPORT -- declare global label for data␊ |
279 | */␊ |
280 | #define␉EXPORT(name)␉␉␉␉␉\␊ |
281 | ␉.globl␉name␉␉␉␉␉;\␊ |
282 | name:␊ |
283 | ␊ |
284 | /*␊ |
285 | * BSS -- declare global zero'ed storage␊ |
286 | */␊ |
287 | #define␉BSS(name,size)␉␉␉␉␉\␊ |
288 | ␉.comm␉name,size␊ |
289 | ␊ |
290 | ␊ |
291 | /*␊ |
292 | * P_BSS -- declare private zero'ed storage␊ |
293 | */␊ |
294 | #define␉P_BSS(name,size)␉␉␉␉\␊ |
295 | ␉.lcomm␉name,size␊ |
296 | ␊ |
297 | /*␊ |
298 | * dynamic/PIC macros for routines which reference external symbols␊ |
299 | */␊ |
300 | ␊ |
301 | #if defined(__DYNAMIC__)␊ |
302 | #if defined(__i386__)␊ |
303 | #define PICIFY(var)␉␉␉␉␉\␊ |
304 | ␉call␉1f␉␉␉␉␉; \␊ |
305 | 1:␉␉␉␉␉␉␉; \␊ |
306 | ␉popl␉%edx␉␉␉␉␉; \␊ |
307 | ␉movl␉L ## var ## __non_lazy_ptr-1b(%edx),%edx␊ |
308 | #elif defined(__x86_64__)␊ |
309 | #define PICIFY(var)␉␉␉␉␉\␊ |
310 | ␉movq␉var@GOTPCREL(%rip),%r11␊ |
311 | #endif␊ |
312 | ␊ |
313 | #if defined(__i386__)␊ |
314 | #define CALL_EXTERN_AGAIN(func)␉\␊ |
315 | ␉PICIFY(func)␉␉; \␊ |
316 | ␉call␉*%edx␊ |
317 | #elif defined(__x86_64__)␊ |
318 | #define CALL_EXTERN_AGAIN(func)␉\␊ |
319 | ␉call␉func␊ |
320 | #endif␊ |
321 | ␊ |
322 | #if defined(__i386__)␊ |
323 | #define NON_LAZY_STUB(var)␉\␊ |
324 | .section __IMPORT,__pointers,non_lazy_symbol_pointers␉; \␊ |
325 | L ## var ## __non_lazy_ptr:␉; \␊ |
326 | .indirect_symbol var␉␉; \␊ |
327 | .long 0␉␉␉␉; \␊ |
328 | .text␊ |
329 | #elif defined(__x86_64__)␊ |
330 | #define NON_LAZY_STUB(var)␉␊ |
331 | #endif␊ |
332 | ␊ |
333 | #define CALL_EXTERN(func)␉\␊ |
334 | ␉CALL_EXTERN_AGAIN(func)␉; \␊ |
335 | ␉NON_LAZY_STUB(func)␊ |
336 | ␊ |
337 | #if defined(__i386__)␊ |
338 | #define BRANCH_EXTERN(func)␉\␊ |
339 | ␉PICIFY(func)␉␉; \␊ |
340 | ␉jmp␉*%edx␉␉; \␊ |
341 | ␉NON_LAZY_STUB(func)␊ |
342 | #elif defined(__x86_64__)␊ |
343 | #define BRANCH_EXTERN(func)␉\␊ |
344 | ␉jmp␉func␊ |
345 | #endif␊ |
346 | ␊ |
347 | #if defined(__i386__)␊ |
348 | #define PUSH_EXTERN(var)␉\␊ |
349 | ␉PICIFY(var)␉␉; \␊ |
350 | ␉movl␉(%edx),%edx␉; \␊ |
351 | ␉pushl␉%edx␉␉; \␊ |
352 | ␉NON_LAZY_STUB(var)␊ |
353 | #endif␊ |
354 | ␊ |
355 | #if defined(__i386__)␊ |
356 | #define REG_TO_EXTERN(reg, var)␉\␊ |
357 | ␉PICIFY(var)␉␉; \␊ |
358 | ␉movl␉reg, (%edx)␉; \␊ |
359 | ␉NON_LAZY_STUB(var)␊ |
360 | #elif defined(__x86_64__)␊ |
361 | #define REG_TO_EXTERN(reg, var)␉\␊ |
362 | ␉PICIFY(var)␉␉; \␊ |
363 | ␉mov␉␉reg, (%r11)␊ |
364 | #endif␊ |
365 | ␊ |
366 | #if defined(__i386__)␊ |
367 | #define EXTERN_TO_REG(var, reg)␉␉␉␉\␊ |
368 | ␉call␉1f␉␉␉␉␉; \␊ |
369 | 1:␉␉␉␉␉␉␉; \␊ |
370 | ␉popl␉%edx␉␉␉␉␉; \␊ |
371 | ␉movl␉L ## var ##__non_lazy_ptr-1b(%edx),reg␉; \␊ |
372 | ␉NON_LAZY_STUB(var)␊ |
373 | #elif defined(__x86_64__)␊ |
374 | #define EXTERN_TO_REG(var, reg)␉␉␉␉\␊ |
375 | ␉PICIFY(var)␉␉; \␊ |
376 | ␉mov (%r11), reg␊ |
377 | #endif␊ |
378 | ␊ |
379 | #else␊ |
380 | #define BRANCH_EXTERN(func)␉jmp␉func␊ |
381 | #define PUSH_EXTERN(var)␉push␉var␊ |
382 | #define CALL_EXTERN(func)␉call␉func␊ |
383 | #define CALL_EXTERN_AGAIN(func)␉call␉func␊ |
384 | #if defined(__i386__)␊ |
385 | #define REG_TO_EXTERN(reg, var)␉mov␉reg, var␊ |
386 | #define EXTERN_TO_REG(var, reg)␉mov␉$ ## var, reg␊ |
387 | #elif defined(__x86_64__)␊ |
388 | #define REG_TO_EXTERN(reg, var)␉mov␉reg, var ## (%rip)␊ |
389 | #define EXTERN_TO_REG(var, reg)␉mov␉var ## (%rip), reg␊ |
390 | #endif␊ |
391 | #endif␊ |
392 | ␊ |
393 | #endif␉/* __ASSEMBLER__ */␊ |
394 | ␊ |
395 | #endif␉/* _ARCH_I386_ASM_HELP_H_ */␊ |
396 | |