2 // Mark the object as not requiring an executable stack.
3 .section .note.GNU-stack,"",%progbits
6 #define LANGUAGE_ASSEMBLY
12 #include "genesis/simple-fun.h"
13 #include "genesis/fdefn.h"
14 #include "genesis/closure.h"
15 #include "genesis/funcallable-instance.h"
16 #include "genesis/static-symbols.h"
17 #ifdef LISP_FEATURE_SB_THREAD
18 #include "genesis/thread.h"
21 #ifdef LISP_FEATURE_DARWIN
22 #define CSYMBOL(x) _ ## x
27 #if defined LISP_FEATURE_DARWIN
28 #define FUNCDEF(x) .text @ \
32 #define GFUNCDEF(x) .globl _ ## x @ \
35 #define FUNCDEF(x) .text ; \
40 #define GFUNCDEF(x) .globl x ; \
44 #if defined LISP_FEATURE_DARWIN
47 #define SET_SIZE(x) .size x,.-x
50 /* Load a register from a global, using the register as an intermediary */
51 /* The register will be a fixnum for one instruction, so this is gc-safe */
53 #if defined LISP_FEATURE_DARWIN
54 #define load(reg,global) \
55 lis reg,ha16(global) @ \
56 lwz reg,lo16(global)(reg) ; Comment
57 #define store(reg,temp,global) \
58 lis temp,ha16(global) @\
59 stw reg,lo16(global)(temp) ; Comment
61 #define load(reg,global) \
62 lis reg,global@ha; lwz reg,global@l(reg)
63 #define store(reg,temp,global) \
64 lis temp,global@ha; stw reg,global@l(temp)
67 #define FIRST_SAVE_FPR 14 /* lowest-numbered non-volatile FPR */
68 #ifdef LISP_FEATURE_DARWIN
69 #define FIRST_SAVE_GPR 13 /* lowest-numbered non-volatile GPR */
70 #define NGPR_SAVE_BYTES(n) ((32-(n))*4)
71 #define FRAME_ARG_BYTES(n) (((((n)+6)*4)+15)&~15)
73 #define FIRST_SAVE_GPR 14 /* lowest-numbered non-volatile GPR */
74 #define NGPR_SAVE_BYTES(n) ((32-(~1&((n)+1)))*4)
75 #define FRAME_ARG_BYTES(n) (((((n)+2)*4)+15)&~15)
77 #define NFPR_SAVE_BYTES(n) ((32-(n))*8)
79 #ifdef LISP_FEATURE_DARWIN
80 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
81 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words))
82 #define SAVE_FPR(n) stfd f##n,-8*(32- n)(r11)
83 #define SAVE_GPR(n) stw r##n,-4*(32- n)(r11)
84 #define FULL_FRAME_SIZE (FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1)+15&~15)
85 #define RESTORE_FPR(n) lfd f##n,-8*(32- n)(r11)
86 #define RESTORE_GPR(n) lwz r##n,-4*(32- n)(r11)
88 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
89 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
90 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
91 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
92 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
94 #define RESTORE_FPR(n) lfd n,-8*(32-(n))(11)
95 #define RESTORE_GPR(n) lwz n,-4*(32-(n))(11)
98 #ifdef LISP_FEATURE_DARWIN
99 #define C_FULL_PROLOG \
103 stw REG(0),4(REG(1)) @ \
105 stw REG(0),8(REG(1)) @ \
106 mr REG(11),REG(1) @ \
107 stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
126 la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
148 #define C_FULL_EPILOG \
149 la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
169 la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
188 lwz REG(1),0(REG(1)) @ \
189 lwz REG(0),4(REG(1)) @ \
191 lwz REG(0),8(REG(1)) @ \
196 #define C_FULL_PROLOG \
200 stwu 1,-FULL_FRAME_SIZE(1) ; \
219 la 11,-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(11) ; \
241 #define C_FULL_EPILOG \
244 la 11,FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(1) ; \
263 la 11,NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(11) ; \
288 /* gas can't parse nnnnLU; redefine */
289 #if BACKEND_PAGE_BYTES == 65536
290 # undef BACKEND_PAGE_BYTES
291 # define BACKEND_PAGE_BYTES 65536
292 #elif BACKEND_PAGE_BYTES == 4096
293 # undef BACKEND_PAGE_BYTES
294 # define BACKEND_PAGE_BYTES 4096
296 # error BACKEND_PAGE_BYTES mismatch
299 #ifdef LISP_FEATURE_SB_SAFEPOINT
300 /* OAOOM because we don't have the C headers here. */
301 # define THREAD_CSP_PAGE_SIZE 4096
303 /* the CSP page sits right before the thread */
304 # define THREAD_SAVED_CSP_OFFSET (-THREAD_CSP_PAGE_SIZE)
310 * Function to transfer control into lisp. The lisp object to invoke is
311 * passed as the first argument, which puts it in NL0
314 GFUNCDEF(call_into_lisp)
316 /* NL0 - function, NL1 - frame pointer, NL2 - nargs. */
317 #if defined(LISP_FEATURE_SB_THREAD)
318 /* We need to obtain a pointer to our TLS block before we do
319 * anything else. For this, we call pthread_getspecific().
320 * We've preserved all of the callee-saves registers, so we
321 * can use them to stash our arguments temporarily while we
327 /* Call out to obtain our TLS block. */
328 load(reg_NL0,CSYMBOL(specials))
329 /* This won't work on darwin: wrong fixup style. And is it
330 * supposed to be lis/ori or lis/addi? Or does it differ
331 * between darwin and everything else again? */
332 lis reg_CFUNC,CSYMBOL(pthread_getspecific)@h
333 ori reg_CFUNC,reg_CFUNC,CSYMBOL(pthread_getspecific)@l
336 mr reg_THREAD, reg_NL0
338 /* Restore our original parameters. */
343 /* store(reg_POLL,11,saver2) */
344 /* Initialize tagged registers */
358 #if !defined(LISP_FEATURE_SB_THREAD)
362 #ifdef LISP_FEATURE_DARWIN
363 lis reg_NULL,hi16(NIL)
364 ori reg_NULL,reg_NULL,lo16(NIL)
367 ori reg_NULL,reg_NULL,NIL@l
369 /* Turn on pseudo-atomic */
371 li reg_ALLOC,flag_PseudoAtomic
372 #if defined(LISP_FEATURE_SB_THREAD)
373 stw reg_ZERO,THREAD_FOREIGN_FUNCTION_CALL_ACTIVE_OFFSET(reg_THREAD)
374 lwz reg_BSP,THREAD_BINDING_STACK_POINTER_OFFSET(reg_THREAD)
375 lwz reg_CSP,THREAD_CONTROL_STACK_POINTER_OFFSET(reg_THREAD)
376 lwz reg_OCFP,THREAD_CONTROL_FRAME_POINTER_OFFSET(reg_THREAD)
378 store(reg_ZERO,reg_NL4,CSYMBOL(foreign_function_call_active))
379 load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
380 load(reg_CSP,CSYMBOL(current_control_stack_pointer))
381 load(reg_OCFP,CSYMBOL(current_control_frame_pointer))
383 /* This is important for CHENEYGC: It's the allocation
384 * pointer. It's also important for ROOM on GENCGC:
385 * It's a pointer to the end of dynamic space, used to
386 * determine where to stop in MAP-ALLOCATED-OBJECTS. */
387 load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
388 add reg_ALLOC,reg_ALLOC,reg_NL4
390 /* No longer atomic, and check for interrupt */
391 subi reg_ALLOC,reg_ALLOC,flag_PseudoAtomic
392 andi. reg_NL3, reg_ALLOC, flag_PseudoAtomicInterrupted
395 /* Pass in the arguments */
398 mr reg_LEXENV,reg_NL0
399 lwz reg_A0,0(reg_CFP)
400 lwz reg_A1,4(reg_CFP)
401 lwz reg_A2,8(reg_CFP)
402 lwz reg_A3,12(reg_CFP)
405 #ifdef LISP_FEATURE_DARWIN
406 lis reg_LRA,ha16(lra)
407 addi reg_LRA,reg_LRA,lo16(lra)
410 ori reg_LRA,reg_LRA,lra@l
412 addi reg_LRA,reg_LRA,OTHER_POINTER_LOWTAG
414 /* Function is an indirect closure */
415 lwz reg_CODE,SIMPLE_FUN_SELF_OFFSET(reg_LEXENV)
416 addi reg_LIP,reg_CODE,SIMPLE_FUN_CODE_OFFSET
418 slwi reg_NARGS,reg_NL2,2
423 .long RETURN_PC_WIDETAG
425 /* Blow off any extra values. */
429 /* Return the one value. */
433 /* Turn on pseudo-atomic */
434 la reg_ALLOC,flag_PseudoAtomic(reg_ALLOC)
436 #if defined(LISP_FEATURE_SB_THREAD)
437 /* Store lisp state */
438 stw reg_BSP,THREAD_BINDING_STACK_POINTER_OFFSET(reg_THREAD)
439 stw reg_CSP,THREAD_CONTROL_STACK_POINTER_OFFSET(reg_THREAD)
440 stw reg_CFP,THREAD_CONTROL_FRAME_POINTER_OFFSET(reg_THREAD)
442 /* No longer in Lisp. */
443 stw reg_ALLOC,THREAD_FOREIGN_FUNCTION_CALL_ACTIVE_OFFSET(reg_THREAD)
445 /* Store lisp state */
446 clrrwi reg_NL1,reg_ALLOC,3
447 store(reg_NL1,reg_NL2,CSYMBOL(dynamic_space_free_pointer))
448 /* store(reg_POLL,reg_NL2,poll_flag) */
449 /* load(reg_NL2,current_thread) */
450 store(reg_BSP,reg_NL2,CSYMBOL(current_binding_stack_pointer))
451 store(reg_CSP,reg_NL2,CSYMBOL(current_control_stack_pointer))
452 store(reg_CFP,reg_NL2,CSYMBOL(current_control_frame_pointer))
453 /* load(reg_POLL,saver2) */
455 /* No longer in Lisp. */
456 store(reg_NL1,reg_NL2,CSYMBOL(foreign_function_call_active))
459 /* Check for interrupt */
460 subi reg_ALLOC, reg_ALLOC, flag_PseudoAtomic
461 andi. reg_NL3, reg_ALLOC, flag_PseudoAtomicInterrupted
467 SET_SIZE(call_into_lisp)
470 GFUNCDEF(call_into_c)
471 /* We're kind of low on unboxed, non-dedicated registers here:
472 most of the unboxed registers may have outgoing C args in them.
473 CFUNC is going to have to go in the CTR in a moment, anyway
474 so we'll free it up soon. reg_NFP is preserved by lisp if it
475 has a meaningful value in it, so we can use it. reg_NARGS is
476 free when it's not holding a copy of the "real" reg_NL3, which
477 gets tied up by the pseudo-atomic mechanism */
480 /* Build a lisp stack frame */
483 la reg_CSP,32(reg_CSP)
484 stw reg_OCFP,0(reg_CFP)
485 stw reg_CODE,8(reg_CFP)
486 /* The pseudo-atomic mechanism wants to use reg_NL3, but that
487 may be an outgoing C argument. Copy reg_NL3 to something that's
488 unboxed and -not- one of the C argument registers */
491 /* Turn on pseudo-atomic */
492 la reg_ALLOC,flag_PseudoAtomic(reg_ALLOC)
494 /* Convert the return address to an offset and save it on the stack. */
495 sub reg_NFP,reg_LIP,reg_CODE
496 la reg_NFP,OTHER_POINTER_LOWTAG(reg_NFP)
497 stw reg_NFP,4(reg_CFP)
499 #ifdef LISP_FEATURE_SB_THREAD
500 /* Store Lisp state */
501 stw reg_BSP,THREAD_BINDING_STACK_POINTER_OFFSET(reg_THREAD)
502 stw reg_CSP,THREAD_CONTROL_STACK_POINTER_OFFSET(reg_THREAD)
503 stw reg_CFP,THREAD_CONTROL_FRAME_POINTER_OFFSET(reg_THREAD)
505 /* No longer in Lisp. */
506 stw reg_CSP,THREAD_FOREIGN_FUNCTION_CALL_ACTIVE_OFFSET(reg_THREAD)
508 /* Store Lisp state */
509 clrrwi reg_NFP,reg_ALLOC,3
510 store(reg_NFP,reg_CFUNC,CSYMBOL(dynamic_space_free_pointer))
511 /* load(reg_CFUNC,current_thread) */
513 store(reg_BSP,reg_CFUNC,CSYMBOL(current_binding_stack_pointer))
514 store(reg_CSP,reg_CFUNC,CSYMBOL(current_control_stack_pointer))
515 store(reg_CFP,reg_CFUNC,CSYMBOL(current_control_frame_pointer))
517 /* No longer in Lisp */
518 store(reg_CSP,reg_CFUNC,CSYMBOL(foreign_function_call_active))
520 /* load(reg_POLL,saver2) */
521 /* Disable pseudo-atomic; check pending interrupt */
522 subi reg_ALLOC, reg_ALLOC, flag_PseudoAtomic
523 andi. reg_NL3, reg_ALLOC, flag_PseudoAtomicInterrupted
526 #ifdef LISP_FEATURE_SB_SAFEPOINT
527 /* OK to run GC without stopping this thread from this point on. */
528 stw reg_CSP,THREAD_SAVED_CSP_OFFSET(reg_THREAD)
533 #ifdef LISP_FEATURE_DARWIN
534 /* PowerOpen (i.e. OS X) requires the callee address in r12
535 (a.k.a. CFUNC), so move it back there, too. */
541 /* Re-establish NIL */
542 #ifdef LISP_FEATURE_DARWIN
543 lis reg_NULL,hi16(NIL)
544 ori reg_NULL,reg_NULL,lo16(NIL)
547 ori reg_NULL,reg_NULL,NIL@l
552 /* If we GC'ed during the FF code (as the result of a callback ?)
553 the tagged lisp registers may now contain garbage (since the
554 registers were saved by C and not seen by the GC.) Put something
555 harmless in all such registers before allowing an interrupt */
560 /* reg_OCFP was pointing to a control stack frame & was preserved by C */
568 #if !defined(LISP_FEATURE_SB_THREAD)
569 /* reg_L2 is our TLS block pointer. */
574 # ifdef LISP_FEATURE_SB_SAFEPOINT
575 /* No longer OK to run GC except at safepoints. */
576 stw reg_ZERO,THREAD_SAVED_CSP_OFFSET(reg_THREAD)
580 li reg_ALLOC,flag_PseudoAtomic
582 #if defined(LISP_FEATURE_SB_THREAD)
583 /* No longer in foreign function call. */
584 stw reg_ZERO,THREAD_FOREIGN_FUNCTION_CALL_ACTIVE_OFFSET(reg_THREAD)
586 /* The binding stack pointer isn't preserved by C. */
587 lwz reg_BSP,THREAD_BINDING_STACK_POINTER_OFFSET(reg_THREAD)
589 /* No long in foreign function call. */
590 store(reg_ZERO,reg_NL2,CSYMBOL(foreign_function_call_active))
592 /* The free pointer may have moved */
595 /* The BSP wasn't preserved by C, so load it */
596 load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
598 /* This is important for CHENEYGC: It's the allocation
599 * pointer. It's also important for ROOM on GENCGC:
600 * It's a pointer to the end of dynamic space, used to
601 * determine where to stop in MAP-ALLOCATED-OBJECTS. */
602 load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
603 add reg_ALLOC,reg_ALLOC,reg_NL4
605 /* Other lisp stack/frame pointers were preserved by C.
606 I can't imagine why they'd have moved */
608 /* Get the return address back. */
609 lwz reg_LIP,4(reg_CFP)
610 lwz reg_CODE,8(reg_CFP)
611 add reg_LIP,reg_CODE,reg_LIP
612 la reg_LIP,-OTHER_POINTER_LOWTAG(reg_LIP)
614 /* No longer atomic */
615 subi reg_ALLOC, reg_ALLOC, flag_PseudoAtomic
616 andi. reg_NL3, reg_ALLOC, flag_PseudoAtomicInterrupted
621 /* Reset the lisp stack. */
625 /* And back into Lisp. */
628 SET_SIZE(call_into_c)
630 /* The fun_end_breakpoint support here is considered by the
631 authors of the other $ARCH-assem.S files to be magic, and it
632 is. It is a small fragment of code that is copied into a heap
633 code-object when needed, and contains an LRA object, code to
634 convert a single-value return to unknown-values format, and a
635 trap_FunEndBreakpoint. */
636 GFUNCDEF(fun_end_breakpoint_guts)
637 .globl CSYMBOL(fun_end_breakpoint_trap)
638 .globl CSYMBOL(fun_end_breakpoint_end)
640 /* Due to pointer verification in MAKE-LISP-OBJ, this must
641 include its header data (the offset from the start of the
642 code-object to the LRA). The code-object header is 4
643 words, there are 1 word of constants, and the instruction
644 space is doubleword-aligned, making an offset of six.
645 This is header data for a widetag, so shift left eight bits
647 /* FIXME: the above is full of magic numbers. */
648 .long RETURN_PC_WIDETAG + 0x600
650 /* We are receiving unknown multiple values, thus must deal
651 with the single-value and multiple-value cases separately. */
652 b fun_end_breakpoint_multiple_values
655 /* Compute the correct value for reg_CODE based on the LRA.
656 This is a "simple" matter of subtracting a constant from
657 reg_LRA (where the LRA is stored by the return sequence) to
658 obtain a tagged pointer to the enclosing code component. Both
659 values are tagged OTHER_POINTER_LOWTAG, so we just have to
660 account for the six words (see calculation for
661 RETURN_PC_WIDETAG, above) between the two addresses.
662 Restoring reg_CODE doesn't appear to be strictly necessary
663 here, but let's observe the niceties.*/
664 addi reg_CODE, reg_LRA, -24
666 /* Multiple values are stored relative to reg_OCFP, which we
667 set to be the current top-of-stack. */
670 /* Reserve a save location for the one value we have. */
671 addi reg_CSP, reg_CSP, 4
673 /* Record the number of values we have as a FIXNUM. */
676 /* Blank the remaining arg-passing registers. */
681 /* And branch to our trap. */
682 b CSYMBOL(fun_end_breakpoint_trap)
684 fun_end_breakpoint_multiple_values:
685 /* Compute the correct value for reg_CODE. See the
686 explanation for the single-value case, above. */
687 addi reg_CODE, reg_LRA, -24
689 /* The actual magic trap. */
690 CSYMBOL(fun_end_breakpoint_trap):
691 twllei reg_ZERO, trap_FunEndBreakpoint
693 /* Finally, the debugger needs to know where the end of the
694 fun_end_breakpoint_guts are, so that it may calculate its size
695 in order to populate out a suitably-sized code object. */
696 CSYMBOL(fun_end_breakpoint_end):
697 SET_SIZE(fun_end_breakpoint_guts)
700 GFUNCDEF(ppc_flush_cache_line)
707 SET_SIZE(ppc_flush_cache_line)
709 GFUNCDEF(do_pending_interrupt)
712 /* King Nato's branch has a nop here. Do we need this? */
713 SET_SIZE(do_pending_interrupt)