]>
Commit | Line | Data |
---|---|---|
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 @\ | |
239 | name: @\ | |
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 @\ | |
254 | name: @\ | |
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 @\ | |
265 | name: | |
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 @\ | |
273 | name: @\ | |
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 @\ | |
288 | name: @\ | |
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 @\ | |
298 | name: | |
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 @\ | |
308 | name: | |
309 | ||
310 | /* | |
311 | * P_HANDLER -- declare private handler | |
312 | */ | |
313 | #define P_HANDLER(name) \ | |
314 | .align 2 @\ | |
315 | name: | |
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 @\ | |
359 | name: | |
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 @\ | |
386 | 1: 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 @\ | |
405 | L ## 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_ */ |