/[cmucl]/src/lisp/ppc-assem.S
ViewVC logotype

Contents of /src/lisp/ppc-assem.S

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.16 - (show annotations)
Sat Dec 17 16:30:02 2005 UTC (8 years, 3 months ago) by rtoy
Branch: MAIN
CVS Tags: snapshot-2006-01
Changes since 1.15: +2 -0 lines
Missing a nop in breakpoint guts.
1 #define LANGUAGE_ASSEMBLY
2
3 #include "internals.h"
4 #include "lispregs.h"
5 #include "globals.h"
6
7 #if defined DARWIN
8 #define FUNCDEF(x) .text @ \
9 .align 3 @ \
10 _/**/x:
11 #define GFUNCDEF(x) .globl _/**/x @ \
12 FUNCDEF(x)
13 #else
14 #define FUNCDEF(x) .text ; \
15 .align 3 ; \
16 .type x,@function ; \
17 x:
18 #define GFUNCDEF(x) .globl _/**/x @ \
19 FUNCDEF(x)
20 #endif
21
22 #if defined DARWIN
23 #define SET_SIZE(x)
24 #else
25 #define SET_SIZE(x) .size x,.-x
26 #endif
27
28 /* Load a register from a global, using the register as an intermediary */
29 /* The register will be a fixnum for one instruction, so this is gc-safe */
30
31 #if defined DARWIN
32 #define load(reg,global) \
33 lis reg,ha16(global) @ \
34 lwz reg,lo16(global)(reg) ; Comment
35 #define store(reg,temp,global) \
36 lis temp,ha16(global) @\
37 stw reg,lo16(global)(temp) ; Comment
38 #else
39 #define load(reg,global) \
40 lis reg,global@ha; lwz reg,global@l(reg)
41 #define store(reg,temp,global) \
42 lis temp,global@ha; stw reg,global@l(temp)
43 #endif
44
45 #define FIRST_SAVE_FPR 14 /* lowest-numbered non-volatile FPR */
46 #define FIRST_SAVE_GPR 13 /* lowest-numbered non-volatile GPR */
47 #define NFPR_SAVE_BYTES(n) ((32-(n))*8)
48 #if defined DARWIN
49 #define NGPR_SAVE_BYTES(n) ((32-(n))*4)
50 #define FRAME_ARG_BYTES(n) (((((n)+6)*4)+15)&~15)
51 #else
52 #define NGPR_SAVE_BYTES(n) ((32-(~1&((n)+1)))*4)
53 #define FRAME_ARG_BYTES(n) (((((n)+2)*4)+15)&~15)
54 #endif
55
56 #if defined DARWIN
57 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
58 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words))
59 #define SAVE_FPR(n) stfd f/**/n,-8*(32- n)(r11)
60 #define SAVE_GPR(n) stw r/**/n,-4*(32- n)(r11)
61 /* Make sure FULL_FRAME_SIZE is on a 16-byte boundary */
62 #define FULL_FRAME_SIZE ((FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1) + 15) & ~15)
63 #else
64 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
65 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
66 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
67 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
68 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
69 #endif
70
71 #if defined DARWIN
72 #define RESTORE_FPR(n) lfd f/**/n,-8*(32- n)(r11)
73 #define RESTORE_GPR(n) lwz r/**/n,-4*(32- n)(r11)
74 #else
75 #define RESTORE_FPR(n) lfd f##n,-8*(32-(r##n))(r11)
76 #define RESTORE_GPR(n) lwz r##n,-4*(32-(r##n))(r11)
77 #endif
78 #define C_FULL_PROLOG \
79 nop @\
80 nop @ \
81 mfcr REG(0) @ \
82 stw REG(0),4(REG(1)) @ \
83 mflr REG(0) @ \
84 stw REG(0),8(REG(1)) @ \
85 mr REG(11),REG(1) @ \
86 stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
87 SAVE_FPR(14) @ \
88 SAVE_FPR(15) @ \
89 SAVE_FPR(16) @ \
90 SAVE_FPR(17) @ \
91 SAVE_FPR(18) @ \
92 SAVE_FPR(19) @ \
93 SAVE_FPR(20) @ \
94 SAVE_FPR(21) @ \
95 SAVE_FPR(22) @ \
96 SAVE_FPR(23) @ \
97 SAVE_FPR(24) @ \
98 SAVE_FPR(25) @ \
99 SAVE_FPR(26) @ \
100 SAVE_FPR(27) @ \
101 SAVE_FPR(28) @ \
102 SAVE_FPR(29) @ \
103 SAVE_FPR(30) @ \
104 SAVE_FPR(31) @ \
105 la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
106 SAVE_GPR(13) @ \
107 SAVE_GPR(14) @ \
108 SAVE_GPR(15) @ \
109 SAVE_GPR(16) @ \
110 SAVE_GPR(17) @ \
111 SAVE_GPR(18) @ \
112 SAVE_GPR(19) @ \
113 SAVE_GPR(20) @ \
114 SAVE_GPR(21) @ \
115 SAVE_GPR(22) @ \
116 SAVE_GPR(23) @ \
117 SAVE_GPR(24) @ \
118 SAVE_GPR(25) @ \
119 SAVE_GPR(26) @ \
120 SAVE_GPR(27) @ \
121 SAVE_GPR(28) @ \
122 SAVE_GPR(29) @ \
123 SAVE_GPR(30) @ \
124 SAVE_GPR(31)
125
126
127 #define C_FULL_EPILOG \
128 la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
129 RESTORE_GPR(13) @ \
130 RESTORE_GPR(14) @ \
131 RESTORE_GPR(15) @ \
132 RESTORE_GPR(16) @ \
133 RESTORE_GPR(17) @ \
134 RESTORE_GPR(18) @ \
135 RESTORE_GPR(19) @ \
136 RESTORE_GPR(20) @ \
137 RESTORE_GPR(21) @ \
138 RESTORE_GPR(22) @ \
139 RESTORE_GPR(23) @ \
140 RESTORE_GPR(24) @ \
141 RESTORE_GPR(25) @ \
142 RESTORE_GPR(26) @ \
143 RESTORE_GPR(27) @ \
144 RESTORE_GPR(28) @ \
145 RESTORE_GPR(29) @ \
146 RESTORE_GPR(30) @ \
147 RESTORE_GPR(31) @ \
148 la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
149 RESTORE_FPR(14) @ \
150 RESTORE_FPR(15) @ \
151 RESTORE_FPR(16) @ \
152 RESTORE_FPR(17) @ \
153 RESTORE_FPR(18) @ \
154 RESTORE_FPR(19) @ \
155 RESTORE_FPR(20) @ \
156 RESTORE_FPR(21) @ \
157 RESTORE_FPR(22) @ \
158 RESTORE_FPR(23) @ \
159 RESTORE_FPR(24) @ \
160 RESTORE_FPR(25) @ \
161 RESTORE_FPR(26) @ \
162 RESTORE_FPR(27) @ \
163 RESTORE_FPR(28) @ \
164 RESTORE_FPR(29) @ \
165 RESTORE_FPR(30) @ \
166 RESTORE_FPR(31) @ \
167 lwz REG(1),0(REG(1)) @ \
168 lwz REG(0),4(REG(1)) @ \
169 mtcr REG(0) @ \
170 lwz REG(0),8(REG(1)) @ \
171 mtlr REG(0) @ \
172
173
174
175
176 .text
177
178 /*
179 * Function to transfer control into lisp. The lisp object to invoke is
180 * passed as the first argument, which puts it in NL0
181 */
182
183 GFUNCDEF(call_into_lisp)
184 C_FULL_PROLOG
185 /* store(reg_POLL,11,saver2) */
186 /* Initialize tagged registers */
187 li reg_ZERO,0
188 li reg_CODE,0
189 li reg_CNAME,0
190 li reg_LEXENV,0
191 li reg_FDEFN,0
192 li reg_OCFP,0
193 li reg_LRA,0
194 li reg_A0,0
195 li reg_A1,0
196 li reg_A2,0
197 li reg_A3,0
198 li reg_L0,0
199 li reg_L1,0
200 li reg_LIP,0
201 lis reg_NULL,hi16(NIL)
202 ori reg_NULL,reg_NULL,lo16(NIL)
203
204 /* Turn on pseudo-atomic */
205
206 li reg_ALLOC,4
207 store(reg_ZERO,reg_NL4,_foreign_function_call_active)
208 load(reg_NL4,_current_dynamic_space_free_pointer)
209 add reg_ALLOC,reg_ALLOC,reg_NL4
210 load(reg_BSP,_current_binding_stack_pointer)
211 load(reg_CSP,_current_control_stack_pointer)
212 load(reg_OCFP,_current_control_frame_pointer)
213
214 /* No longer atomic, and check for interrupt */
215 andi. reg_NL3, reg_ALLOC, 1
216 subi reg_ALLOC,reg_ALLOC,4
217 twnei reg_NL3, 0
218
219 /* Pass in the arguments */
220
221 mr reg_CFP,reg_NL1
222 mr reg_LEXENV,reg_NL0
223 lwz reg_A0,0(reg_CFP)
224 lwz reg_A1,4(reg_CFP)
225 lwz reg_A2,8(reg_CFP)
226 lwz reg_A3,12(reg_CFP)
227
228 /* Calculate LRA */
229 lis reg_LRA,ha16(lra)
230 addi reg_LRA,reg_LRA,lo16(lra)
231 addi reg_LRA,reg_LRA,type_OtherPointer
232
233 /* Function is an indirect closure */
234 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
235 /*
236 * The 6 is vm:function-code-offset, the 4 is
237 * the number of bytes in a lispobj.
238 */
239 addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
240 mtctr reg_LIP
241 slwi reg_NARGS,reg_NL2,2
242 bctr
243 .align 3
244 lra:
245 .long type_ReturnPcHeader
246
247 /* Blow off any extra values. */
248 mr reg_CSP,reg_OCFP
249 nop
250
251 /* Return the one value. */
252
253 mr REG(3),reg_A0
254
255 /* Turn on pseudo-atomic */
256 li reg_NL3,-4
257 la reg_ALLOC,4(reg_ALLOC)
258
259 /* Store lisp state */
260 clrrwi reg_NL1,reg_ALLOC,3
261 store(reg_NL1,reg_NL2,_current_dynamic_space_free_pointer)
262 /* store(reg_POLL,reg_NL2,poll_flag) */
263 /* load(reg_NL2,current_thread) */
264 store(reg_BSP,reg_NL2,_current_binding_stack_pointer)
265 store(reg_CSP,reg_NL2,_current_control_stack_pointer)
266 store(reg_CFP,reg_NL2,_current_control_frame_pointer)
267 /* load(reg_POLL,saver2) */
268
269 /* No longer in Lisp. */
270 store(reg_NL1,reg_NL2,_foreign_function_call_active)
271
272 /* Check for interrupt */
273 andi. reg_NL3, reg_ALLOC, 1
274 subi reg_ALLOC, reg_ALLOC, 4
275 twnei reg_NL3,0
276
277 /* Back to C */
278 C_FULL_EPILOG
279 blr
280 SET_SIZE(call_into_lisp)
281
282
283 GFUNCDEF(call_into_c)
284 /* We're kind of low on unboxed, non-dedicated registers here:
285 most of the unboxed registers may have outgoing C args in them.
286 CFUNC is going to have to go in the CTR in a moment, anyway
287 so we'll free it up soon. reg_NFP is preserved by lisp if it
288 has a meaningful value in it, so we can use it. reg_NARGS is
289 free when it's not holding a copy of the "real" reg_NL3, which
290 gets tied up by the pseudo-atomic mechanism */
291 mtctr reg_CFUNC
292 mflr reg_LIP
293 /* Build a lisp stack frame */
294 mr reg_OCFP,reg_CFP
295 mr reg_CFP,reg_CSP
296 la reg_CSP,32(reg_CSP)
297 stw reg_OCFP,0(reg_CFP)
298 stw reg_CODE,8(reg_CFP)
299 /* The pseudo-atomic mechanism wants to use reg_NL3, but that
300 may be an outgoing C argument. Copy reg_NL3 to something that's
301 unboxed and -not- one of the C argument registers */
302 mr reg_NARGS,reg_NL3
303
304 /* Turn on pseudo-atomic */
305 la reg_ALLOC,4(reg_ALLOC)
306
307 /* Convert the return address to an offset and save it on the stack. */
308 sub reg_NFP,reg_LIP,reg_CODE
309 la reg_NFP,type_OtherPointer(reg_NFP)
310 stw reg_NFP,4(reg_CFP)
311
312 /* Store Lisp state */
313 clrrwi reg_NFP,reg_ALLOC,3
314 store(reg_NFP,reg_CFUNC,_current_dynamic_space_free_pointer)
315 /* load(reg_CFUNC,current_thread) */
316
317 store(reg_BSP,reg_CFUNC,_current_binding_stack_pointer)
318 store(reg_CSP,reg_CFUNC,_current_control_stack_pointer)
319 store(reg_CFP,reg_CFUNC,_current_control_frame_pointer)
320
321 /* No longer in Lisp */
322 store(reg_CSP,reg_CFUNC,_foreign_function_call_active)
323 /* load(reg_POLL,saver2) */
324 /* Disable pseudo-atomic; check pending interrupt */
325 andi. reg_NL3, reg_ALLOC, 1
326 subi reg_ALLOC, reg_ALLOC, 4
327 twnei reg_NL3, 0
328
329 mr reg_NL3,reg_NARGS
330
331 /* PowerOpen (i.e. OS X) requires the callee address in r12
332 (a.k.a. CFUNC), so move it back there, too. */
333 mfctr reg_CFUNC
334 /* Into C we go. */
335 bctrl
336
337 /* Re-establish NIL */
338 lis reg_NULL,hi16(NIL)
339 ori reg_NULL,reg_NULL,lo16(NIL)
340 /* And reg_ZERO */
341 li reg_ZERO,0
342
343 /* If we GC'ed during the FF code (as the result of a callback ?)
344 the tagged lisp registers may now contain garbage (since the
345 registers were saved by C and not seen by the GC.) Put something
346 harmless in all such registers before allowing an interrupt */
347 li reg_CODE,0
348 li reg_CNAME,0
349 li reg_LEXENV,0
350 /* reg_OCFP was pointing to a control stack frame & was preserved by C */
351 li reg_LRA,0
352 li reg_A0,0
353 li reg_A1,0
354 li reg_A2,0
355 li reg_A3,0
356 li reg_L0,0
357 li reg_L1,0
358 li reg_LIP,0
359
360 /* Atomic ... */
361 #if 0
362 li reg_NL3,-4
363 #endif
364 li reg_ALLOC,4
365
366 /* No long in foreign function call. */
367 store(reg_ZERO,reg_NL2,_foreign_function_call_active)
368
369 /* The free pointer may have moved */
370 load(reg_NL4,_current_dynamic_space_free_pointer)
371 add reg_ALLOC,reg_ALLOC,reg_NL4
372
373 /* The BSP wasn't preserved by C, so load it */
374 load(reg_BSP,_current_binding_stack_pointer)
375
376 /* Other lisp stack/frame pointers were preserved by C.
377 I can't imagine why they'd have moved */
378
379 /* Get the return address back. */
380 lwz reg_LIP,4(reg_CFP)
381 lwz reg_CODE,8(reg_CFP)
382 add reg_LIP,reg_CODE,reg_LIP
383 la reg_LIP,-type_OtherPointer(reg_LIP)
384
385 /* No longer atomic */
386 andi. reg_NL3, reg_ALLOC, 1
387 subi reg_ALLOC, reg_ALLOC, 4
388 twnei reg_NL3, 0
389
390 mtlr reg_LIP
391
392 /* Reset the lisp stack. */
393 mr reg_CSP,reg_CFP
394 mr reg_CFP,reg_OCFP
395
396 /* And back into Lisp. */
397 blr
398
399 SET_SIZE(call_into_c)
400
401 GFUNCDEF(xundefined_tramp)
402 .globl _undefined_tramp
403 .byte 0
404 _undefined_tramp:
405 .byte 0, 0, type_FunctionHeader
406 .long _undefined_tramp /* self slot */
407 .long NIL /* next slot */
408 .long NIL /* name slot */
409 .long NIL /* arglist slot */
410 .long NIL /* type slot */
411
412 twllei reg_ZERO,trap_Cerror
413 /* Number of argument bytes */
414 .byte 4
415 .byte UNDEFINED_SYMBOL_ERROR
416 /* Escape to create 16bit number from following two bytes,
417 in little-endian order */
418 .byte 254
419 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
420 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
421 /*
422 .byte sc_DescriptorReg+0x40
423 .byte 1
424 */
425 .align 2
426 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
427 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
428 mtctr reg_LIP
429 bctr
430
431 mr reg_CSP, reg_CFP
432 b 1b
433
434 SET_SIZE(xundefined_tramp)
435
436 GFUNCDEF(xclosure_tramp)
437 .globl _closure_tramp
438 .byte 0
439 _closure_tramp:
440 .byte 0,0,type_FunctionHeader /* Header */
441 .long _closure_tramp
442 .long NIL
443 .long NIL
444 .long NIL
445 .long NIL
446
447 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
448 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
449 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
450 mtctr reg_LIP
451 bctr
452
453 SET_SIZE(xclosure_tramp)
454
455 /*
456 * Function-end breakpoint magic. See MAKE-BOGUS-LRA in
457 * code/debug-int.lisp.
458 */
459 .text
460 .align 3
461 .globl _function_end_breakpoint_guts
462 _function_end_breakpoint_guts:
463 .long type_ReturnPcHeader
464 b 1f
465 /* This NOP is necessary for the return convention, I think */
466 nop
467 /*
468 * Are these really necessary? I'm cargo-culting from the sparc port
469 */
470 mr reg_OCFP, reg_CSP
471 addi reg_CSP, reg_CSP, 4
472 li reg_NARGS, 4
473 mr reg_A1, reg_NULL
474 mr reg_A2, reg_NULL
475 mr reg_A3, reg_NULL
476 1:
477 .globl _function_end_breakpoint_trap
478 _function_end_breakpoint_trap:
479 twllei reg_ZERO, trap_FunctionEndBreakpoint
480 b 1b
481 .globl _function_end_breakpoint_end
482 _function_end_breakpoint_end:
483
484
485 GFUNCDEF(ppc_flush_cache_line)
486 dcbf 0,REG(3)
487 sync
488 icbi 0,REG(3)
489 sync
490 isync
491 blr
492 SET_SIZE(ppc_flush_cache_line)
493
494 #ifdef LINKAGE_TABLE
495 /*
496 * Call into C code to resolve a linkage entry.
497 *
498 * We get here by Lisp calling call_into_c with an address of the
499 * desired function which is contained in the register reg_CFUNC (aka
500 * %i4, aka %r28). This is the address of the entry in the linkage
501 * table, which is what we need to figure out what function we really
502 * wanted.
503 *
504 * Note that because we get here from call_into_c, all necessary live
505 * registers have been saved, including FP registers. Hence, no need
506 * to save them.
507 */
508 .globl _lazy_resolve_linkage
509 GFUNCDEF(resolve_linkage_tramp)
510 /*
511 * We need to call lazy_resolve_linkage. reg_A0 (= r24)
512 * (see ppc-arch.c) contains the address of the linkage entry.
513 */
514 /*
515 * Need to save all parameter regs to the stack because we
516 * need them for later. We save the FP registers too. (Do
517 * we really need to? lazy_resolve_linkage shouldn't call
518 * anything that uses FP registers. It's safe to do so.)
519 */
520 subi r1, r1, 8*4+8+8*13
521 stfd f1, 0(r1)
522 stfd f2, 8(r1)
523 stfd f3, 16(r1)
524 stfd f4, 24(r1)
525 stfd f5, 32(r1)
526 stfd f6, 40(r1)
527 stfd f7, 48(r1)
528 stfd f8, 56(r1)
529 stfd f9, 64(r1)
530 stfd f10, 72(r1)
531 stfd f11, 80(r1)
532 stfd f12, 88(r1)
533 stfd f13, 96(r1)
534
535 stw r3, 104+0(r1)
536 stw r4, 104+4(r1)
537 stw r5, 104+8(r1)
538 stw r6, 104+12(r1)
539 stw r7, 104+16(r1)
540 stw r8, 104+20(r1)
541 stw r9, 104+24(r1)
542 stw r10, 104+28(r1)
543
544
545 mr reg_NL0, reg_A0
546
547 stwu r1, (-(24+4))(r1)
548 /*
549 * At this point reg_NIL should be available to us.
550 * Call lazy_resolve_linkage to figure out the real function address.
551 */
552 lis reg_NULL, hi16(_lazy_resolve_linkage)
553 ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
554 mtctr reg_NULL
555 mflr reg_CODE
556 bctrl
557
558 addi r1,r1,24+4
559
560 /*
561 * The desired function is in r3 (NL0), so save it
562 * and restore the real arg parameters
563 */
564
565 mtctr reg_NL0
566 lfd f1, 0(r1)
567 lfd f2, 8(r1)
568 lfd f3, 16(r1)
569 lfd f4, 24(r1)
570 lfd f5, 32(r1)
571 lfd f6, 40(r1)
572 lfd f7, 48(r1)
573 lfd f8, 56(r1)
574 lfd f9, 64(r1)
575 lfd f10, 72(r1)
576 lfd f11, 80(r1)
577 lfd f12, 88(r1)
578 lfd f13, 96(r1)
579
580 lwz r3, 104+0(r1)
581 lwz r4, 104+4(r1)
582 lwz r5, 104+8(r1)
583 lwz r6, 104+12(r1)
584 lwz r7, 104+16(r1)
585 lwz r8, 104+20(r1)
586 lwz r9, 104+24(r1)
587 lwz r10, 104+28(r1)
588
589 addi r1,r1,8*4+8+8*13
590
591 /*
592 * Got it, so we can now jump directly to the desired function.
593 * reg_NL0 contains the result. Restore the stack and go!
594 */
595
596 mtlr reg_CODE
597
598 /* Back to C */
599 /* mtlr reg_CODE*/
600 bctr
601
602 SET_SIZE(resolve_linkage_tramp)
603
604
605 /*
606 * When we get called, r3 (reg_NL0) contains the address of the
607 * data_vector object which is a string naming the bad symbol.
608 */
609 GFUNCDEF(undefined_foreign_symbol_trap)
610
611 /*
612 Need to restore all the global registers with the Lisp values that
613 were saved away in call_into_c. (This routine is only called from
614 os_link_one_symbol, which is called from resolve_linkage_tramp, which
615 is called from call_into_c.)
616
617 The global registers are volatile across function calls, so who
618 knows what values have been they contain now!
619
620 */
621
622 load(reg_ALLOC, _current_dynamic_space_free_pointer)
623 load(reg_BSP, _current_binding_stack_pointer)
624 load(reg_CSP, _current_control_stack_pointer)
625 load(reg_CFP, _current_control_frame_pointer)
626
627 lis reg_NULL,hi16(NIL)
628 ori reg_NULL,reg_NULL,lo16(NIL)
629 /* And reg_ZERO */
630 li reg_ZERO,0
631
632 mr reg_NL0, reg_A0
633 twllei reg_ZERO, trap_Error
634 .byte 4 /* Number of argument bytes */
635 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
636 /* Escape to create 16bit number from following two bytes, in
637 little-endian order */
638 .byte 254
639 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
640 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
641 .align 4
642
643 #endif

  ViewVC Help
Powered by ViewVC 1.1.5