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