|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This 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 OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
23: *
24: * File: architecture/i386/asm_help.h
25: * Author: Mike DeMoney, NeXT Computer, Inc.
26: * Modified for i386 by: Bruce Martin, NeXT Computer, Inc.
27: *
28: * This header file defines macros useful when writing assembly code
29: * for the Intel i386 family processors.
30: *
31: * HISTORY
32: * 10-Mar-92 Bruce Martin ([email protected])
33: * Adapted to i386
34: * 23-Jan-91 Mike DeMoney ([email protected])
35: * Created.
36: */
37:
38: #ifndef _ARCH_I386_ASM_HELP_H_
39: #define _ARCH_I386_ASM_HELP_H_
40:
41: #import <architecture/i386/reg_help.h>
42:
43:
44: #ifdef __ASSEMBLER__
45:
46: #define ALIGN \
47: .align 2, 0x90
48:
49: #define ROUND_TO_STACK(len) \
50: (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)
51:
52: #ifdef notdef
53: #define CALL_MCOUNT \
54: pushl %ebp ;\
55: movl %esp, %ebp ;\
56: .data ;\
57: 1: .long 0 ;\
58: .text ;\
59: lea 9b,%edx ;\
60: call mcount ;\
61: popl %ebp ;
62: #else
63: #define CALL_MCOUNT
64: #endif
65:
66: /*
67: * Prologue for functions that may call other functions. Saves
68: * registers and sets up a C frame.
69: */
70: #define NESTED_FUNCTION_PROLOGUE(localvarsize) \
71: .set __framesize,ROUND_TO_STACK(localvarsize) ;\
72: .set __nested_function, 1 ;\
73: CALL_MCOUNT \
74: .if __framesize ;\
75: pushl %ebp ;\
76: movl %esp, %ebp ;\
77: subl $__framesize, %esp ;\
78: .endif ;\
79: pushl %edi ;\
80: pushl %esi ;\
81: pushl %ebx
82:
83: /*
84: * Prologue for functions that do not call other functions. Does not
85: * save registers (this is the functions responsibility). Does set
86: * up a C frame.
87: */
88: #define LEAF_FUNCTION_PROLOGUE(localvarsize) \
89: .set __framesize,ROUND_TO_STACK(localvarsize) ;\
90: .set __nested_function, 0 ;\
91: CALL_MCOUNT \
92: .if __framesize ;\
93: pushl %ebp ;\
94: movl %esp, %ebp ;\
95: subl $__framesize, %esp ;\
96: .endif
97:
98: /*
99: * Prologue for any function.
100: *
101: * We assume that all Leaf functions will be responsible for saving any
102: * local registers they clobber.
103: */
104: #define FUNCTION_EPILOGUE \
105: .if __nested_function ;\
106: popl %ebx ;\
107: popl %esi ;\
108: popl %edi ;\
109: .endif ;\
110: .if __framesize ;\
111: movl %ebp, %esp ;\
112: popl %ebp ;\
113: .endif ;\
114: ret
115:
116:
117: /*
118: * Macros for declaring procedures
119: *
120: * Use of these macros allows ctags to have a predictable way
121: * to find various types of declarations. They also simplify
122: * inserting appropriate symbol table information.
123: *
124: * NOTE: these simple stubs will be replaced with more
125: * complicated versions once we know what the linker and gdb
126: * will require as far as register use masks and frame declarations.
127: * These macros may also be ifdef'ed in the future to contain profiling
128: * code.
129: *
130: */
131:
132: /*
133: * TEXT -- declare start of text segment
134: */
135: #define TEXT \
136: .text
137:
138: /*
139: * DATA -- declare start of data segment
140: */
141: #define DATA \
142: .data
143:
144: /*
145: * LEAF -- declare global leaf procedure
146: * NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only
147: * be jumped to. (A leaf may do an align.) Use a LABEL() if you
148: * need control to flow into the label.
149: */
150: #define LEAF(name, localvarsize) \
151: .globl name ;\
152: ALIGN ;\
153: name: ;\
154: LEAF_FUNCTION_PROLOGUE(localvarsize)
155:
156: /*
157: * X_LEAF -- declare alternate global label for leaf
158: */
159: #define X_LEAF(name, value) \
160: .globl name ;\
161: .set name,value
162:
163: /*
164: * P_LEAF -- declare private leaf procedure
165: */
166: #define P_LEAF(name, localvarsize) \
167: ALIGN ;\
168: name: ;\
169: LEAF_FUNCTION_PROLOGUE(localvarsize)
170:
171: /*
172: * LABEL -- declare a global code label
173: * MUST be used (rather than LEAF, NESTED, etc) if control
174: * "flows into" the label.
175: */
176: #define LABEL(name) \
177: .globl name ;\
178: name:
179:
180: /*
181: * NESTED -- declare procedure that invokes other procedures
182: */
183: #define NESTED(name, localvarsize) \
184: .globl name ;\
185: ALIGN ;\
186: name: ;\
187: NESTED_FUNCTION_PROLOGUE(localvarsize)
188:
189: /*
190: * X_NESTED -- declare alternate global label for nested proc
191: */
192: #define X_NESTED(name, value) \
193: .globl name ;\
194: .set name,value
195:
196: /*
197: * P_NESTED -- declare private nested procedure
198: */
199: #define P_NESTED(name, localvarsize) \
200: ALIGN ;\
201: name: ;\
202: NESTED_FUNCTION_PROLOGUE(localvarsize)
203:
204: /*
205: * END -- mark end of procedure
206: */
207: #define END(name) \
208: FUNCTION_EPILOGUE
209:
210:
211: /*
212: * Storage definition macros
213: * The main purpose of these is to allow an easy handle for ctags
214: */
215:
216: /*
217: * IMPORT -- import symbol
218: */
219: #define IMPORT(name) \
220: .reference name
221:
222: /*
223: * ABS -- declare global absolute symbol
224: */
225: #define ABS(name, value) \
226: .globl name ;\
227: .set name,value
228:
229: /*
230: * P_ABS -- declare private absolute symbol
231: */
232: #define P_ABS(name, value) \
233: .set name,value
234:
235: /*
236: * EXPORT -- declare global label for data
237: */
238: #define EXPORT(name) \
239: .globl name ;\
240: name:
241:
242: /*
243: * BSS -- declare global zero'ed storage
244: */
245: #define BSS(name,size) \
246: .comm name,size
247:
248:
249: /*
250: * P_BSS -- declare private zero'ed storage
251: */
252: #define P_BSS(name,size) \
253: .lcomm name,size
254:
255: /*
256: * dynamic/PIC macros for routines which reference external symbols
257: */
258:
259: #if defined(__DYNAMIC__)
260: #define PICIFY(var) \
261: call 1f ; \
262: 1: ; \
263: popl %edx ; \
264: movl L ## var ## $non_lazy_ptr-1b(%edx),%edx
265:
266: #define CALL_EXTERN_AGAIN(func) \
267: PICIFY(func) ; \
268: call %edx
269:
270: #define NON_LAZY_STUB(var) \
271: .non_lazy_symbol_pointer ; \
272: L ## var ## $non_lazy_ptr: ; \
273: .indirect_symbol var ; \
274: .long 0 ; \
275: .text
276:
277: #define CALL_EXTERN(func) \
278: CALL_EXTERN_AGAIN(func) ; \
279: NON_LAZY_STUB(func)
280:
281: #define BRANCH_EXTERN(func) \
282: PICIFY(func) ; \
283: jmp %edx ; \
284: NON_LAZY_STUB(func)
285:
286: #define PUSH_EXTERN(var) \
287: PICIFY(var) ; \
288: movl (%edx),%edx ; \
289: pushl %edx ; \
290: NON_LAZY_STUB(var)
291:
292: #define REG_TO_EXTERN(reg, var) \
293: PICIFY(var) ; \
294: movl reg, (%edx) ; \
295: NON_LAZY_STUB(var)
296:
297: #define EXTERN_TO_REG(var, reg) \
298: call 1f ; \
299: 1: ; \
300: popl %edx ; \
301: movl L ## var ##$non_lazy_ptr-1b(%edx),reg ; \
302: NON_LAZY_STUB(var)
303:
304:
305: #else
306: #define BRANCH_EXTERN(func) jmp func
307: #define PUSH_EXTERN(var) pushl var
308: #define CALL_EXTERN(func) call func
309: #define CALL_EXTERN_AGAIN(func) call func
310: #define REG_TO_EXTERN(reg, var) movl reg, var
311: #define EXTERN_TO_REG(var, reg) movl $ ## var, reg
312: #endif
313:
314: #endif /* __ASSEMBLER__ */
315:
316: #endif /* _ARCH_I386_ASM_HELP_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.