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