]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/architecture/ppc/asm_help.h
xnu-792.12.6.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / architecture / ppc / asm_help.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /* Copyright (c) 1996 NeXT Software, Inc. All rights reserved.
31 *
32 * File: architecture/ppc/asm_help.h
33 * Author: Mike DeMoney, NeXT Software, Inc.
34 *
35 * This header file defines macros useful when writing assembly code
36 * for the PowerPC processors.
37 * r12 is used as the tmp register / PICIFY base.
38 *
39 * HISTORY
40 * 20-May-97 Umesh Vaishampayan (umeshv@apple.com)
41 * Implemented Dynamic / PIC macros.
42 *
43 * 28-Dec-96 Umesh Vaishampayan (umeshv@NeXT.com)
44 * added ".align" directive to various macros to avoid alignment
45 * faults. Moved Register Usage #defines to reg_help.h as that's
46 * where they should have been in the first place.
47 * Added Dynamic / PIC macroes for routines which refernce external
48 * symbols. Not implemented fully as yet.
49 *
50 * 05-Nov-92 Mike DeMoney (mike@next.com)
51 * Created.
52 */
53
54 #ifndef _ARCH_PPC_ASM_HELP_H_
55 #define _ARCH_PPC_ASM_HELP_H_
56
57 #include <architecture/ppc/reg_help.h>
58
59 #ifdef __ASSEMBLER__
60 /*
61 * ppc stack frames look like this after procedure prolog has
62 * been executed:
63 *
64 * Higher address:
65 * .........
66 * +-------------------------------+
67 * | caller's LR |
68 * +-------------------------------+
69 * | caller's CR |
70 * +-------------------------------+
71 * Caller's SP->| caller's caller's sp | ^^ Caller's Frame ^^
72 * +===============================+ vv Called Rtn Frame vv
73 * | Save Area for | FPF 31
74 * ..........
75 * | Caller's FPF's | FPF n
76 * +-------------------------------+
77 * | Save Area for | GRF 31
78 * ..........
79 * | Caller's GRF's | GRF n
80 * +-------------------------------+
81 * | alignment pad |
82 * ............
83 * | (if necessary) |
84 * +-------------------------------+
85 * | Local |
86 * ........
87 * | Variables |
88 * +-------------------------------+
89 * SP + X -> | aN for FUTURE call |
90 * +-------------------------------+
91 * ..........
92 * +-------------------------------+
93 * SP + 28 -> | a1 for FUTURE call |
94 * +-------------------------------+
95 * SP + 24 -> | a0 for FUTURE call |
96 * +-------------------------------+
97 * SP + 20 -> | caller's TOC |
98 * +-------------------------------+
99 * SP + 16 -> | reserved |
100 * +-------------------------------+
101 * SP + 12 -> | reserved |
102 * +-------------------------------+
103 * SP + 8 -> | LR callee-save for FUTURE call|
104 * +-------------------------------+
105 * SP + 4 -> | CR callee-save for FUTURE call|
106 * +-------------------------------+
107 * SP -> | caller's sp |
108 * +===============================+
109 * Lower address:
110 *
111 * NOTE: All state with the exception of LR and CR are saved in the
112 * called routines frame. LR and CR are saved in the CALLER'S FRAME.
113 *
114 * ALSO NOTE: Args to the called routine are found in the caller's frame.
115 */
116
117 /*
118 * ARG(n) -- stack offset to n'th argument
119 *
120 * NOTE CAREFULLY! These macros start numbering arguments at 1 (NOT 0)
121 * The first argument is ARG(1).
122 *
123 * ALSO NOTE: This stack offset is only valid if using routine
124 * DOES NOT alter SP.
125 *
126 */
127 #define ARG(n) ((((n) - 1) * 4) + 24)
128
129 /*
130 * Macros for building stack frame according to C calling conventions.
131 * lr, cr, and sp are saved.
132 *
133 * NOTE WELL: localvarsize is in bytes, maxargsout is a count of words,
134 * grfsaved and fpfsaved is a count of registers. BE SURE TO COUNT
135 * BOTH FP (r31) AND sN REGISTERS IN THE COUNT OF GRF REGISTERS SAVED!
136 * This will be TWO more than the N of the highest sN register you
137 * save: s2 implies you are saving s2, s1, s0, and fp => grfsaved
138 * should be 4!
139 *
140 * FURTHER NOTE: These macros do NOT SAVE GRF or FPF registers. User
141 * must do that. GRF sN regs should be saved via
142 * stmw sN,SAVED_GRF_S(N)(sp)
143 * where N is the highest numbered s* register to be saved. E.g. if
144 * s0, s1, and s2 are to be saved use:
145 * stmw s2,SAVED_GRF_S(2)(sp)
146 * Note that this also saves fp.
147 * An individual saved grf can be loaded via:
148 * lwz s2,SAVED_GRF_S(2)(sp)
149 * Analogous stuff works for fpf's.
150 *
151 * NOTE: these simple routines will be replaced with more complicated
152 * ones once we know what the linker and gdb will require as for as
153 * register use masks and frame declarations.
154 *
155 * Warning: ROUND_TO_STACK is only to be used in assembly language;
156 * for C usage, use ROUND_FRAME() in reg_help.h.
157 */
158 #define ROUND_TO_STACK(len) \
159 (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)
160
161 #define BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved) \
162 .set __argoutsize, ROUND_TO_STACK((maxargsout) * 4) @\
163 .if __argoutsize < 32 @\
164 .set __argoutsize,32 @\
165 .endif @\
166 .set __framesize, ROUND_TO_STACK( \
167 24 + __argoutsize + (localvarsize) \
168 + 4*(grfsaved) + 8*(fpfsaved)) @\
169 .set __grfbase,(__framesize - 4*(grfsaved) - 8*(fpfsaved)) @\
170 .set __fpfbase,(__framesize - 8*(fpfsaved)) @\
171 mflr r0 @\
172 mfcr r12 @\
173 stw r0,8(sp) @\
174 stw r12,4(sp) @\
175 stwu r1,-__framesize(r1)
176
177 /*
178 * Macros for referencing data in stack frame.
179 *
180 * NOTE WELL: ARG's and VAR's start at 1, NOT 0. Why ??? (FIXME)
181 */
182 #define LOCAL_VAR(n) (((n)-1)*4 + __argoutsize + 24)
183 #define SAVED_GRF_S(n) (__grfbase + ((grfsaved) - (n) - 2) * 4)
184 #define SAVED_FRF_FS(n) (__fpfbase + ((fpfsaved) - (n) - 1) * 4)
185 #define ARG_IN(n) (ARG(n) + __framesize)
186 #define ARG_OUT(n) (ARG(n) + 0)
187 #define SAVED_FP (__grfbase + ((grfsaved) - 1) * 4)
188 #define SAVED_LR (__framesize + 8)
189 #define SAVED_CR (__framesize + 4)
190
191 /*
192 * Macros for unwinding stack frame.
193 * NOTE: GRF's and FPF's are NOT RESTORED. User must do this before
194 * using this macro.
195 */
196 #define RETURN \
197 .if __framesize @\
198 lwz32 r0,r1,SAVED_LR @\
199 lwz32 r12,r1,SAVED_CR @\
200 addic sp,r1,__framesize @\
201 mtlr r0 @\
202 mtcrf 0xff,r12 @\
203 blr @\
204 .else @\
205 blr @\
206 .endif
207
208
209 /*
210 * Macros for declaring procedures
211 *
212 * Use of these macros allows ctags to have a predictable way
213 * to find various types of declarations. They also simplify
214 * inserting appropriate symbol table information.
215 *
216 * NOTE: these simple stubs will be replaced with more
217 * complicated versions once we know what the linker and gdb
218 * will require as far as register use masks and frame declarations.
219 * These macros may also be ifdef'ed in the future to contain profiling
220 * code.
221 *
222 * FIXME: Document what makes a leaf a LEAF and a handler a HANDLER.
223 * (E.g. leaf's have return pc in lr, NESTED's have rpc in offset off
224 * sp, handlers have rpc in exception frame which is found via exception
225 * link, etc etc.)
226 */
227
228 /*
229 * TEXT -- declare start of text segment
230 */
231 #define TEXT \
232 .text @\
233 .align 2
234
235 /*
236 * LEAF -- declare global leaf procedure
237 * NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only
238 * be jumped to. (A leaf may do an align.) Use a LABEL() if you
239 * need control to flow into the label.
240 */
241 #define LEAF(name) \
242 .align 2 @\
243 .globl name @\
244 name: @\
245 .set __framesize,0
246
247 /*
248 * X_LEAF -- declare alternate global label for leaf
249 */
250 #define X_LEAF(name, value) \
251 .globl name @\
252 .set name,value
253
254 /*
255 * P_LEAF -- declare private leaf procedure
256 */
257 #define P_LEAF(name) \
258 .align 2 @\
259 name: @\
260 .set __framesize,0
261
262 /*
263 * LABEL -- declare a global code label
264 * MUST be used (rather than LEAF, NESTED, etc) if control
265 * "flows into" the label.
266 */
267 #define LABEL(name) \
268 .align 2 @\
269 .globl name @\
270 name:
271
272 /*
273 * NESTED -- declare procedure that invokes other procedures
274 */
275 #define NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
276 .align 2 @\
277 .globl name @\
278 name: @\
279 BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved)
280
281 /*
282 * X_NESTED -- declare alternate global label for nested proc
283 */
284 #define X_NESTED(name, value) \
285 .globl name @\
286 .set name,value
287
288 /*
289 * P_NESTED -- declare private nested procedure
290 */
291 #define P_NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
292 .align 2 @\
293 name: @\
294 BUILD_FRAME(locavarsize, maxargsout, grfsaved, fpfsaved)
295
296 /*
297 * HANDLER -- declare procedure with exception frame rather than
298 * standard C frame
299 */
300 #define HANDLER(name) \
301 .align 2 @\
302 .globl name @\
303 name:
304
305 /*
306 * X_HANDLER -- declare alternate name for exception handler
307 * (Should appear immediately before a HANDLER declaration or
308 * another X_HANDLER declaration)
309 */
310 #define X_HANDLER(name) \
311 .align 2 @\
312 .globl name @\
313 name:
314
315 /*
316 * P_HANDLER -- declare private handler
317 */
318 #define P_HANDLER(name) \
319 .align 2 @\
320 name:
321
322 /*
323 * END -- mark end of procedure
324 * FIXME: Unimplemented for now.
325 */
326 #define END(name)
327
328 /*
329 * BL -- call procedure (relative)
330 */
331 #define BL(name) \
332 bl name
333
334 /*
335 * Storage definition macros
336 * The main purpose of these is to allow an easy handle for ctags
337 */
338
339 /*
340 * IMPORT -- import symbol
341 */
342 #define IMPORT(name) \
343 .reference name
344
345 /*
346 * ABS -- declare global absolute symbol
347 */
348 #define ABS(name, value) \
349 .globl name @\
350 .set name,value
351
352 /*
353 * P_ABS -- declare private absolute symbol
354 */
355 #define P_ABS(name, value) \
356 .set name,value
357
358 /*
359 * EXPORT -- declare global label for data
360 */
361 #define EXPORT(name) \
362 .align 2 @\
363 .globl name @\
364 name:
365
366 /*
367 * BSS -- declare global zero'ed storage
368 */
369 #define BSS(name,size) \
370 .comm name,size
371
372
373 /*
374 * P_BSS -- declare private zero'ed storage
375 */
376 #define P_BSS(name,size) \
377 .lcomm name,size
378
379 /*
380 * dynamic/PIC macros for routines which reference external symbols
381 */
382 #if defined(__DYNAMIC__)
383 #define PICIFY_REG r12
384
385 /* Assume that the lr is saved before calling any of these macros */
386 /* using PICIFY() */
387
388 #define PICIFY(var) \
389 mflr r0 @\
390 bl 1f @\
391 1: mflr PICIFY_REG @\
392 mtlr r0 @\
393 addis PICIFY_REG, PICIFY_REG, ha16(L ## var ## $non_lazy_ptr - 1b) @\
394 lwz PICIFY_REG, lo16(L ## var ## $non_lazy_ptr - 1b)(PICIFY_REG)
395
396 #define CALL_EXTERN_AGAIN(var) \
397 PICIFY(var) @\
398 mtctr PICIFY_REG @\
399 mflr r0 @\
400 stw r0,8(r1) @\
401 stwu r1,-56(r1) @\
402 bctrl @\
403 addic r1,r1,56 @\
404 lwz r0,8(r1) @\
405 mtlr r0
406
407 #define NON_LAZY_STUB(var) \
408 .non_lazy_symbol_pointer @\
409 .align 2 @\
410 L ## var ## $non_lazy_ptr: @\
411 .indirect_symbol var @\
412 .long 0 @\
413 .text @\
414 .align 2
415
416 #define BRANCH_EXTERN(var) \
417 PICIFY(var) @\
418 mtctr PICIFY_REG @\
419 bctr @\
420 NON_LAZY_STUB(var)
421
422 #define CALL_EXTERN(var) \
423 CALL_EXTERN_AGAIN(var) @\
424 NON_LAZY_STUB(var)
425
426 #define REG_TO_EXTERN(reg, var) \
427 PICIFY(var) @\
428 stw reg, 0(PICIFY_REG) @\
429 NON_LAZY_STUB(var)
430
431 #define EXTERN_TO_REG(reg, var) \
432 PICIFY(var) @\
433 lwz reg, 0(PICIFY_REG) @\
434 NON_LAZY_STUB(var)
435
436 #else /* ! __DYNAMIC__ */
437 #define TMP_REG r12
438 #define BRANCH_EXTERN(var) \
439 b var
440
441 #define CALL_EXTERN(var) \
442 bl var
443
444 #define CALL_EXTERN_AGAIN(var) \
445 CALL_EXTERN(var)
446
447 #define REG_TO_EXTERN(reg, var) \
448 lis TMP_REG, ha16(var) @\
449 stw reg, lo16(var)(TMP_REG)
450
451 #define EXTERN_TO_REG(reg, var) \
452 lis reg, ha16(var) @\
453 lwz reg, lo16(var)(reg)
454
455 #endif /* __DYNAMIC__ */
456
457 #endif /* __ASSEMBLER__ */
458 #endif /* _ARCH_PPC_ASM_HELP_H_ */