/[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.7 - (show annotations)
Thu Feb 24 04:07:59 2005 UTC (9 years, 2 months ago) by rtoy
Branch: MAIN
CVS Tags: snapshot-2005-03
Changes since 1.6: +11 -1 lines
o Fix typo.
o When PPC_FUN_HACK is not defined, the raw_addr slot of an fdefn
  object should be on a word boundary, so change undefined_tramp and
  closure_tramp to be on such a boundary.  Previously, these had a
  lowtag of 1.  With this change, can we get rid of the other parts of
  a function definition that we don't use?
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 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1)
62 #else
63 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
64 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
65 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
66 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
67 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
68 #endif
69
70 #if defined DARWIN
71 #define RESTORE_FPR(n) lfd f##n,-8*(32- n)(r11)
72 #define RESTORE_GPR(n) lwz r##n,-4*(32- n)(r11)
73 #else
74 #define RESTORE_FPR(n) lfd f##n,-8*(32-(r##n))(r11)
75 #define RESTORE_GPR(n) lwz r##n,-4*(32-(r##n))(r11)
76 #endif
77 #define C_FULL_PROLOG \
78 nop @\
79 nop @ \
80 mfcr REG(0) @ \
81 stw REG(0),4(REG(1)) @ \
82 mflr REG(0) @ \
83 stw REG(0),8(REG(1)) @ \
84 mr REG(11),REG(1) @ \
85 stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
86 SAVE_FPR(14) @ \
87 SAVE_FPR(15) @ \
88 SAVE_FPR(16) @ \
89 SAVE_FPR(17) @ \
90 SAVE_FPR(18) @ \
91 SAVE_FPR(19) @ \
92 SAVE_FPR(20) @ \
93 SAVE_FPR(21) @ \
94 SAVE_FPR(22) @ \
95 SAVE_FPR(23) @ \
96 SAVE_FPR(24) @ \
97 SAVE_FPR(25) @ \
98 SAVE_FPR(26) @ \
99 SAVE_FPR(27) @ \
100 SAVE_FPR(28) @ \
101 SAVE_FPR(29) @ \
102 SAVE_FPR(30) @ \
103 SAVE_FPR(31) @ \
104 la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
105 SAVE_GPR(13) @ \
106 SAVE_GPR(14) @ \
107 SAVE_GPR(15) @ \
108 SAVE_GPR(16) @ \
109 SAVE_GPR(17) @ \
110 SAVE_GPR(18) @ \
111 SAVE_GPR(19) @ \
112 SAVE_GPR(20) @ \
113 SAVE_GPR(21) @ \
114 SAVE_GPR(22) @ \
115 SAVE_GPR(23) @ \
116 SAVE_GPR(24) @ \
117 SAVE_GPR(25) @ \
118 SAVE_GPR(26) @ \
119 SAVE_GPR(27) @ \
120 SAVE_GPR(28) @ \
121 SAVE_GPR(29) @ \
122 SAVE_GPR(30) @ \
123 SAVE_GPR(31)
124
125
126 #define C_FULL_EPILOG \
127 la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
128 RESTORE_GPR(13) @ \
129 RESTORE_GPR(14) @ \
130 RESTORE_GPR(15) @ \
131 RESTORE_GPR(16) @ \
132 RESTORE_GPR(17) @ \
133 RESTORE_GPR(18) @ \
134 RESTORE_GPR(19) @ \
135 RESTORE_GPR(20) @ \
136 RESTORE_GPR(21) @ \
137 RESTORE_GPR(22) @ \
138 RESTORE_GPR(23) @ \
139 RESTORE_GPR(24) @ \
140 RESTORE_GPR(25) @ \
141 RESTORE_GPR(26) @ \
142 RESTORE_GPR(27) @ \
143 RESTORE_GPR(28) @ \
144 RESTORE_GPR(29) @ \
145 RESTORE_GPR(30) @ \
146 RESTORE_GPR(31) @ \
147 la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
148 RESTORE_FPR(14) @ \
149 RESTORE_FPR(15) @ \
150 RESTORE_FPR(16) @ \
151 RESTORE_FPR(17) @ \
152 RESTORE_FPR(18) @ \
153 RESTORE_FPR(19) @ \
154 RESTORE_FPR(20) @ \
155 RESTORE_FPR(21) @ \
156 RESTORE_FPR(22) @ \
157 RESTORE_FPR(23) @ \
158 RESTORE_FPR(24) @ \
159 RESTORE_FPR(25) @ \
160 RESTORE_FPR(26) @ \
161 RESTORE_FPR(27) @ \
162 RESTORE_FPR(28) @ \
163 RESTORE_FPR(29) @ \
164 RESTORE_FPR(30) @ \
165 RESTORE_FPR(31) @ \
166 lwz REG(1),0(REG(1)) @ \
167 lwz REG(0),4(REG(1)) @ \
168 mtcr REG(0) @ \
169 lwz REG(0),8(REG(1)) @ \
170 mtlr REG(0) @ \
171
172
173
174
175 .text
176
177 /*
178 * Function to transfer control into lisp. The lisp object to invoke is
179 * passed as the first argument, which puts it in NL0
180 */
181
182 GFUNCDEF(call_into_lisp)
183 C_FULL_PROLOG
184 /* store(reg_POLL,11,saver2) */
185 /* Initialize tagged registers */
186 li reg_ZERO,0
187 li reg_CODE,0
188 li reg_CNAME,0
189 li reg_LEXENV,0
190 li reg_FDEFN,0
191 li reg_OCFP,0
192 li reg_LRA,0
193 li reg_A0,0
194 li reg_A1,0
195 li reg_A2,0
196 li reg_A3,0
197 li reg_L0,0
198 li reg_L1,0
199 li reg_L2,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_NL3,-4
207 li reg_ALLOC,4
208 store(reg_ZERO,reg_NL4,_foreign_function_call_active)
209 load(reg_NL4,_current_dynamic_space_free_pointer)
210 add reg_ALLOC,reg_ALLOC,reg_NL4
211 load(reg_BSP,_current_binding_stack_pointer)
212 load(reg_CSP,_current_control_stack_pointer)
213 load(reg_OCFP,_current_control_frame_pointer)
214
215 /* No longer atomic, and check for interrupt */
216 add reg_ALLOC,reg_ALLOC,reg_NL3
217 twlti reg_ALLOC,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 #ifdef PPC_FUN_HACK
236 mtctr reg_CODE
237 #else
238 addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
239 mtctr reg_LIP
240 #endif
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 add reg_ALLOC,reg_ALLOC,reg_NL3
274 twlti reg_ALLOC,0
275
276 /* Back to C */
277 C_FULL_EPILOG
278 blr
279 SET_SIZE(call_into_lisp)
280
281
282 GFUNCDEF(call_into_c)
283 /* We're kind of low on unboxed, non-dedicated registers here:
284 most of the unboxed registers may have outgoing C args in them.
285 CFUNC is going to have to go in the CTR in a moment, anyway
286 so we'll free it up soon. reg_NFP is preserved by lisp if it
287 has a meaningful value in it, so we can use it. reg_NARGS is
288 free when it's not holding a copy of the "real" reg_NL3, which
289 gets tied up by the pseudo-atomic mechanism */
290 mtctr reg_CFUNC
291 mflr reg_LIP
292 /* Build a lisp stack frame */
293 mr reg_OCFP,reg_CFP
294 mr reg_CFP,reg_CSP
295 la reg_CSP,32(reg_CSP)
296 stw reg_OCFP,0(reg_CFP)
297 stw reg_CODE,8(reg_CFP)
298 /* The pseudo-atomic mechanism wants to use reg_NL3, but that
299 may be an outgoing C argument. Copy reg_NL3 to something that's
300 unboxed and -not- one of the C argument registers */
301 mr reg_NARGS,reg_NL3
302
303 /* Turn on pseudo-atomic */
304 li reg_NL3,-4
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 add reg_ALLOC,reg_ALLOC,reg_NL3
326 twlti reg_ALLOC,0
327 mr reg_NL3,reg_NARGS
328
329 /* PowerOpen (i.e. OS X) requires the callee address in r12
330 (a.k.a. CFUNC), so move it back there, too. */
331 mfctr reg_CFUNC
332 /* Into C we go. */
333 bctrl
334
335 /* Re-establish NIL */
336 lis reg_NULL,hi16(NIL)
337 ori reg_NULL,reg_NULL,lo16(NIL)
338 /* And reg_ZERO */
339 li reg_ZERO,0
340
341 /* If we GC'ed during the FF code (as the result of a callback ?)
342 the tagged lisp registers may now contain garbage (since the
343 registers were saved by C and not seen by the GC.) Put something
344 harmless in all such registers before allowing an interrupt */
345 li reg_CODE,0
346 li reg_CNAME,0
347 li reg_LEXENV,0
348 /* reg_OCFP was pointing to a control stack frame & was preserved by C */
349 li reg_LRA,0
350 li reg_A0,0
351 li reg_A1,0
352 li reg_A2,0
353 li reg_A3,0
354 li reg_L0,0
355 li reg_L1,0
356 li reg_L2,0
357 li reg_LIP,0
358
359 /* Atomic ... */
360 li reg_NL3,-4
361 li reg_ALLOC,4
362
363 /* No long in foreign function call. */
364 store(reg_ZERO,reg_NL2,_foreign_function_call_active)
365
366 /* The free pointer may have moved */
367 load(reg_NL4,_current_dynamic_space_free_pointer)
368 add reg_ALLOC,reg_ALLOC,reg_NL4
369
370 /* The BSP wasn't preserved by C, so load it */
371 load(reg_BSP,_current_binding_stack_pointer)
372
373 /* Other lisp stack/frame pointers were preserved by C.
374 I can't imagine why they'd have moved */
375
376 /* Get the return address back. */
377 lwz reg_LIP,4(reg_CFP)
378 lwz reg_CODE,8(reg_CFP)
379 add reg_LIP,reg_CODE,reg_LIP
380 la reg_LIP,-type_OtherPointer(reg_LIP)
381
382 /* No longer atomic */
383 add reg_ALLOC,reg_ALLOC,reg_NL3
384 twlti reg_ALLOC,0
385 mtlr reg_LIP
386
387 /* Reset the lisp stack. */
388 mr reg_CSP,reg_CFP
389 mr reg_CFP,reg_OCFP
390
391 /* And back into Lisp. */
392 blr
393
394 SET_SIZE(call_into_c)
395
396 GFUNCDEF(xundefined_tramp)
397 .globl _undefined_tramp
398 .byte 0,0,0,type_FunctionHeader
399
400 #ifdef PPC_FUN_HACK
401 /*
402 * The next 4 bytes are the encoding for a PPC jump instruction.
403 * The jump should go to the twllei instruction below.
404 */
405 .byte 18<<2
406 _undefined_tramp:
407 .byte 0,0,24
408 #endif
409 .long _undefined_tramp
410 .long NIL
411 .long NIL
412 .long NIL
413 .long NIL
414 #ifndef PPC_FUN_HACK
415 _undefined_tramp:
416 #endif
417 twllei reg_ZERO,trap_Cerror
418 /* Number of argument bytes */
419 .byte 4
420 .byte UNDEFINED_SYMBOL_ERROR
421 /* Escape to create 16bit number from following two bytes,
422 in little-endian order */
423 .byte 254
424 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
425 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
426 /*
427 .byte sc_DescriptorReg+0x40
428 .byte 1
429 */
430 .align 2
431 #ifdef PPC_FUN_HACK_MAYBE
432 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_CNAME)
433 #else
434 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
435 #endif
436 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
437 mtctr reg_LIP
438 bctr
439
440 mr reg_CSP, reg_CFP
441 b 1b
442
443 SET_SIZE(xundefined_tramp)
444
445 GFUNCDEF(xclosure_tramp)
446 .globl _closure_tramp
447 .byte 0,0,0,type_FunctionHeader
448 #ifdef PPC_FUN_HACK
449 .byte 18<<2
450 _closure_tramp:
451 .byte 0,0,24
452 #endif
453 .long _closure_tramp
454 .long NIL
455 .long NIL
456 .long NIL
457 .long NIL
458 #ifndef PPC_FUN_HACK
459 _closure_tramp:
460 #endif
461 #ifdef PPC_FUN_HACK_MAYBE
462 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_CNAME)
463 #else
464 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
465 #endif
466 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
467 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
468 mtctr reg_LIP
469 bctr
470
471 SET_SIZE(xclosure_tramp)
472
473 GFUNCDEF(function_end_breakpoint_trap)
474 .long 0
475 SET_SIZE(function_end_breakpoint_trap)
476
477 GFUNCDEF(function_end_breakpoint)
478 .long 0
479 SET_SIZE(function_end_breakpoint)
480
481 GFUNCDEF(function_end_breakpoint_guts)
482 .long 0
483 SET_SIZE(function_end_breakpoint_guts)
484
485 GFUNCDEF(function_end_breakpoint_end)
486 .long 0
487 SET_SIZE(function_end_breakpoint_end)
488
489
490 GFUNCDEF(ppc_flush_cache_line)
491 dcbf 0,REG(3)
492 sync
493 icbi 0,REG(3)
494 sync
495 isync
496 blr
497 SET_SIZE(ppc_flush_cache_line)
498
499 #ifdef LINKAGE_TABLE
500 /*
501 * Call into C code to resolve a linkage entry.
502 *
503 * We get here by Lisp calling call_into_c with an address of the
504 * desired function which is contained in the register reg_CFUNC (aka
505 * %i4, aka %r28). This is the address of the entry in the linkage
506 * table, which is what we need to figure out what function we really
507 * wanted.
508 *
509 * Note that because we get here from call_into_c, all necessary live
510 * registers have been saved, including FP registers. Hence, no need
511 * to save them.
512 */
513 .globl _lazy_resolve_linkage
514 GFUNCDEF(resolve_linkage_tramp)
515 /*
516 * We need to call lazy_resolve_linkage. reg_A0 (= r24)
517 * (see ppc-arch.c) contains the address of the linkage entry.
518 */
519 /*
520 * Need to save all parameter regs to the stack because we
521 * need them for later. We save the FP registers too. (Do
522 * we really need to? lazy_resolve_linkage shouldn't call
523 * anything that uses FP registers. It's safe to do so.)
524 */
525 subi r1, r1, 8*4+8+8*13
526 stfd f1, 0(r1)
527 stfd f2, 8(r1)
528 stfd f3, 16(r1)
529 stfd f4, 24(r1)
530 stfd f5, 32(r1)
531 stfd f6, 40(r1)
532 stfd f7, 48(r1)
533 stfd f8, 56(r1)
534 stfd f9, 64(r1)
535 stfd f10, 72(r1)
536 stfd f11, 80(r1)
537 stfd f12, 88(r1)
538 stfd f13, 96(r1)
539
540 stw r3, 104+0(r1)
541 stw r4, 104+4(r1)
542 stw r5, 104+8(r1)
543 stw r6, 104+12(r1)
544 stw r7, 104+16(r1)
545 stw r8, 104+20(r1)
546 stw r9, 104+24(r1)
547 stw r10, 104+28(r1)
548
549
550 mr reg_NL0, reg_A0
551
552 stwu r1, (-(24+4))(r1)
553 /*
554 * At this point reg_NIL should be available to us.
555 * Call lazy_resolve_linkage to figure out the real function address.
556 */
557 lis reg_NULL, hi16(_lazy_resolve_linkage)
558 ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
559 mtctr reg_NULL
560 mflr reg_CODE
561 bctrl
562
563 addi r1,r1,24+4
564
565 /*
566 * The desired function is in r3 (NL0), so save it
567 * and restore the real arg parameters
568 */
569
570 mtctr reg_NL0
571 lfd f1, 0(r1)
572 lfd f2, 8(r1)
573 lfd f3, 16(r1)
574 lfd f4, 24(r1)
575 lfd f5, 32(r1)
576 lfd f6, 40(r1)
577 lfd f7, 48(r1)
578 lfd f8, 56(r1)
579 lfd f9, 64(r1)
580 lfd f10, 72(r1)
581 lfd f11, 80(r1)
582 lfd f12, 88(r1)
583 lfd f13, 96(r1)
584
585 lwz r3, 104+0(r1)
586 lwz r4, 104+4(r1)
587 lwz r5, 104+8(r1)
588 lwz r6, 104+12(r1)
589 lwz r7, 104+16(r1)
590 lwz r8, 104+20(r1)
591 lwz r9, 104+24(r1)
592 lwz r10, 104+28(r1)
593
594 addi r1,r1,8*4+8+8*13
595
596 /*
597 * Got it, so we can now jump directly to the desired function.
598 * reg_NL0 contains the result. Restore the stack and go!
599 */
600
601 mtlr reg_CODE
602
603 /* Back to C */
604 /* mtlr reg_CODE*/
605 bctr
606
607 SET_SIZE(resolve_linkage_tramp)
608
609
610 /*
611 * When we get called, r3 (reg_NL0) contains the address of the
612 * data_vector object which is a string naming the bad symbol.
613 */
614 GFUNCDEF(undefined_foreign_symbol_trap)
615
616 /*
617 Need to restore all the global registers with the Lisp values that
618 were saved away in call_into_c. (This routine is only called from
619 os_link_one_symbol, which is called from resolve_linkage_tramp, which
620 is called from call_into_c.)
621
622 The global registers are volatile across function calls, so who
623 knows what values have been they contain now!
624
625 */
626
627 load(reg_ALLOC, _current_dynamic_space_free_pointer)
628 load(reg_BSP, _current_binding_stack_pointer)
629 load(reg_CSP, _current_control_stack_pointer)
630 load(reg_CFP, _current_control_frame_pointer)
631
632 lis reg_NULL,hi16(NIL)
633 ori reg_NULL,reg_NULL,lo16(NIL)
634 /* And reg_ZERO */
635 li reg_ZERO,0
636
637 mr reg_NL0, reg_A0
638 twllei reg_ZERO, trap_Error
639 .byte 4 /* Number of argument bytes */
640 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
641 /* Escape to create 16bit number from following two bytes, in
642 little-endian order */
643 .byte 254
644 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
645 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
646 .align 4
647
648 #endif

  ViewVC Help
Powered by ViewVC 1.1.5