]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/architecture/ppc/asm_help.h
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1996 NeXT Software, Inc. All rights reserved.
30 * File: architecture/ppc/asm_help.h
31 * Author: Mike DeMoney, NeXT Software, Inc.
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.
38 * 20-May-97 Umesh Vaishampayan (umeshv@apple.com)
39 * Implemented Dynamic / PIC macros.
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.
48 * 05-Nov-92 Mike DeMoney (mike@next.com)
52 #ifndef _ARCH_PPC_ASM_HELP_H_
53 #define _ARCH_PPC_ASM_HELP_H_
55 #include <architecture/ppc/reg_help.h>
59 * ppc stack frames look like this after procedure prolog has
64 * +-------------------------------+
66 * +-------------------------------+
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
73 * | Caller's FPF's | FPF n
74 * +-------------------------------+
75 * | Save Area for | GRF 31
77 * | Caller's GRF's | GRF n
78 * +-------------------------------+
82 * +-------------------------------+
86 * +-------------------------------+
87 * SP + X -> | aN for FUTURE call |
88 * +-------------------------------+
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 * +===============================+
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.
112 * ALSO NOTE: Args to the called routine are found in the caller's frame.
116 * ARG(n) -- stack offset to n'th argument
118 * NOTE CAREFULLY! These macros start numbering arguments at 1 (NOT 0)
119 * The first argument is ARG(1).
121 * ALSO NOTE: This stack offset is only valid if using routine
125 #define ARG(n) ((((n) - 1) * 4) + 24)
128 * Macros for building stack frame according to C calling conventions.
129 * lr, cr, and sp are saved.
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
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.
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.
153 * Warning: ROUND_TO_STACK is only to be used in assembly language;
154 * for C usage, use ROUND_FRAME() in reg_help.h.
156 #define ROUND_TO_STACK(len) \
157 (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)
159 #define BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved) \
160 .set __argoutsize, ROUND_TO_STACK((maxargsout) * 4) @\
161 .if __argoutsize < 32 @\
162 .set __argoutsize,32 @\
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)) @\
173 stwu r1,-__framesize(r1)
176 * Macros for referencing data in stack frame.
178 * NOTE WELL: ARG's and VAR's start at 1, NOT 0. Why ??? (FIXME)
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)
190 * Macros for unwinding stack frame.
191 * NOTE: GRF's and FPF's are NOT RESTORED. User must do this before
196 lwz32 r0,r1,SAVED_LR @\
197 lwz32 r12,r1,SAVED_CR @\
198 addic sp,r1,__framesize @\
208 * Macros for declaring procedures
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.
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
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
227 * TEXT -- declare start of text segment
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.
246 * X_LEAF -- declare alternate global label for leaf
248 #define X_LEAF(name, value) \
253 * P_LEAF -- declare private leaf procedure
255 #define P_LEAF(name) \
261 * LABEL -- declare a global code label
262 * MUST be used (rather than LEAF, NESTED, etc) if control
263 * "flows into" the label.
265 #define LABEL(name) \
271 * NESTED -- declare procedure that invokes other procedures
273 #define NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
277 BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved)
280 * X_NESTED -- declare alternate global label for nested proc
282 #define X_NESTED(name, value) \
287 * P_NESTED -- declare private nested procedure
289 #define P_NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
292 BUILD_FRAME(locavarsize, maxargsout, grfsaved, fpfsaved)
295 * HANDLER -- declare procedure with exception frame rather than
298 #define HANDLER(name) \
304 * X_HANDLER -- declare alternate name for exception handler
305 * (Should appear immediately before a HANDLER declaration or
306 * another X_HANDLER declaration)
308 #define X_HANDLER(name) \
314 * P_HANDLER -- declare private handler
316 #define P_HANDLER(name) \
321 * END -- mark end of procedure
322 * FIXME: Unimplemented for now.
327 * BL -- call procedure (relative)
333 * Storage definition macros
334 * The main purpose of these is to allow an easy handle for ctags
338 * IMPORT -- import symbol
340 #define IMPORT(name) \
344 * ABS -- declare global absolute symbol
346 #define ABS(name, value) \
351 * P_ABS -- declare private absolute symbol
353 #define P_ABS(name, value) \
357 * EXPORT -- declare global label for data
359 #define EXPORT(name) \
365 * BSS -- declare global zero'ed storage
367 #define BSS(name,size) \
372 * P_BSS -- declare private zero'ed storage
374 #define P_BSS(name,size) \
378 * dynamic/PIC macros for routines which reference external symbols
380 #if defined(__DYNAMIC__)
381 #define PICIFY_REG r12
383 /* Assume that the lr is saved before calling any of these macros */
386 #define PICIFY(var) \
389 1: mflr PICIFY_REG @\
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)
394 #define CALL_EXTERN_AGAIN(var) \
405 #define NON_LAZY_STUB(var) \
406 .non_lazy_symbol_pointer @\
408 L ## var ## $non_lazy_ptr: @\
409 .indirect_symbol var @\
414 #define BRANCH_EXTERN(var) \
420 #define CALL_EXTERN(var) \
421 CALL_EXTERN_AGAIN(var) @\
424 #define REG_TO_EXTERN(reg, var) \
426 stw reg, 0(PICIFY_REG) @\
429 #define EXTERN_TO_REG(reg, var) \
431 lwz reg, 0(PICIFY_REG) @\
434 #else /* ! __DYNAMIC__ */
436 #define BRANCH_EXTERN(var) \
439 #define CALL_EXTERN(var) \
442 #define CALL_EXTERN_AGAIN(var) \
445 #define REG_TO_EXTERN(reg, var) \
446 lis TMP_REG, ha16(var) @\
447 stw reg, lo16(var)(TMP_REG)
449 #define EXTERN_TO_REG(reg, var) \
450 lis reg, ha16(var) @\
451 lwz reg, lo16(var)(reg)
453 #endif /* __DYNAMIC__ */
455 #endif /* __ASSEMBLER__ */
456 #endif /* _ARCH_PPC_ASM_HELP_H_ */