0.8.2.8:
[sbcl.git] / src / runtime / ppc-assem.S
index 1135c8a..de36538 100644 (file)
@@ -3,34 +3,79 @@
 #include "sbcl.h" 
 #include "lispregs.h"
 #include "globals.h"
+
 #include "genesis/simple-fun.h"
 #include "genesis/fdefn.h"
 #include "genesis/closure.h"
 #include "genesis/static-symbols.h"
 
+#ifdef DARWIN
+#define CSYMBOL(x) _ ## x
+#else
+#define CSYMBOL(x) x
+#endif
+
+#if defined DARWIN
+#define FUNCDEF(x)     .text @ \
+                       .align 3 @ \
+_##x:
+
+#define GFUNCDEF(x)    .globl _/**/x @ \
+       FUNCDEF(x)
+#else
 #define FUNCDEF(x)     .text ; \
                        .align 3 ; \
                        .type x,@function ; \
 x:
+
 #define GFUNCDEF(x)    .globl x ; \
        FUNCDEF(x)
+#endif
 
+#if defined DARWIN
+#define SET_SIZE(x)
+#else
 #define SET_SIZE(x) .size x,.-x
+#endif
 
 /* Load a register from a global, using the register as an intermediary */
 /* The register will be a fixnum for one instruction, so this is gc-safe */
 
+#if defined DARWIN
+#define load(reg,global) \
+       lis reg,ha16(global) @ \
+       lwz reg,lo16(global)(reg) ; Comment
+#define store(reg,temp,global) \
+       lis temp,ha16(global) @\
+       stw reg,lo16(global)(temp) ; Comment
+#else
 #define load(reg,global) \
        lis reg,global@ha; lwz reg,global@l(reg)
 #define store(reg,temp,global) \
        lis temp,global@ha; stw reg,global@l(temp)
+#endif
        
 #define        FIRST_SAVE_FPR  14      /* lowest-numbered non-volatile FPR */
+#ifdef DARWIN
+#define        FIRST_SAVE_GPR  13      /* lowest-numbered non-volatile GPR */
+#define NGPR_SAVE_BYTES(n) ((32-(n))*4)
+#define FRAME_ARG_BYTES(n)  (((((n)+6)*4)+15)&~15)
+#else
 #define        FIRST_SAVE_GPR  14      /* lowest-numbered non-volatile GPR */
-#define        NFPR_SAVE_BYTES(n) ((32-(n))*8)
 #define NGPR_SAVE_BYTES(n) ((32-(~1&((n)+1)))*4)
 #define FRAME_ARG_BYTES(n)  (((((n)+2)*4)+15)&~15)
+#endif
+#define        NFPR_SAVE_BYTES(n) ((32-(n))*8)
 
+#ifdef DARWIN
+#define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
+(NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words))
+#define SAVE_FPR(n) stfd f##n,-8*(32- n)(r11)
+#define SAVE_GPR(n) stw r##n,-4*(32- n)(r11)
+#define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1)
+#define RESTORE_FPR(n) lfd f##n,-8*(32- n)(r11)
+#define RESTORE_GPR(n) lwz r##n,-4*(32- n)(r11)
+#else
 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
@@ -39,6 +84,106 @@ x:
 
 #define RESTORE_FPR(n) lfd n,-8*(32-(n))(11)
 #define RESTORE_GPR(n) lwz n,-4*(32-(n))(11)
+#endif
+
+#ifdef DARWIN
+#define C_FULL_PROLOG \
+       nop @\
+       nop @ \
+       mfcr REG(0) @ \
+       stw REG(0),4(REG(1)) @ \
+       mflr REG(0) @ \
+       stw REG(0),8(REG(1)) @ \
+       mr REG(11),REG(1) @ \
+       stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
+       SAVE_FPR(14) @ \
+       SAVE_FPR(15) @ \
+       SAVE_FPR(16) @ \
+       SAVE_FPR(17) @ \
+       SAVE_FPR(18) @ \
+       SAVE_FPR(19) @ \
+       SAVE_FPR(20) @ \
+       SAVE_FPR(21) @ \
+       SAVE_FPR(22) @ \
+       SAVE_FPR(23) @ \
+       SAVE_FPR(24) @ \
+       SAVE_FPR(25) @ \
+       SAVE_FPR(26) @ \
+       SAVE_FPR(27) @ \
+       SAVE_FPR(28) @ \
+       SAVE_FPR(29) @ \
+       SAVE_FPR(30) @ \
+       SAVE_FPR(31) @ \
+       la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
+       SAVE_GPR(13) @ \
+       SAVE_GPR(14) @ \
+       SAVE_GPR(15) @ \
+       SAVE_GPR(16) @ \
+       SAVE_GPR(17) @ \
+       SAVE_GPR(18) @ \
+       SAVE_GPR(19) @ \
+       SAVE_GPR(20) @ \
+       SAVE_GPR(21) @ \
+       SAVE_GPR(22) @ \
+       SAVE_GPR(23) @ \
+       SAVE_GPR(24) @ \
+       SAVE_GPR(25) @ \
+       SAVE_GPR(26) @ \
+       SAVE_GPR(27) @ \
+       SAVE_GPR(28) @ \
+       SAVE_GPR(29) @ \
+       SAVE_GPR(30) @ \
+       SAVE_GPR(31)
+
+
+#define C_FULL_EPILOG \
+       la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
+       RESTORE_GPR(13) @ \
+       RESTORE_GPR(14) @ \
+       RESTORE_GPR(15) @ \
+       RESTORE_GPR(16) @ \
+       RESTORE_GPR(17) @ \
+       RESTORE_GPR(18) @ \
+       RESTORE_GPR(19) @ \
+       RESTORE_GPR(20) @ \
+       RESTORE_GPR(21) @ \
+       RESTORE_GPR(22) @ \
+       RESTORE_GPR(23) @ \
+       RESTORE_GPR(24) @ \
+       RESTORE_GPR(25) @ \
+       RESTORE_GPR(26) @ \
+       RESTORE_GPR(27) @ \
+       RESTORE_GPR(28) @ \
+       RESTORE_GPR(29) @ \
+       RESTORE_GPR(30) @ \
+       RESTORE_GPR(31) @ \
+       la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
+       RESTORE_FPR(14) @ \
+       RESTORE_FPR(15) @ \
+       RESTORE_FPR(16) @ \
+       RESTORE_FPR(17) @ \
+       RESTORE_FPR(18) @ \
+       RESTORE_FPR(19) @ \
+       RESTORE_FPR(20) @ \
+       RESTORE_FPR(21) @ \
+       RESTORE_FPR(22) @ \
+       RESTORE_FPR(23) @ \
+       RESTORE_FPR(24) @ \
+       RESTORE_FPR(25) @ \
+       RESTORE_FPR(26) @ \
+       RESTORE_FPR(27) @ \
+       RESTORE_FPR(28) @ \
+       RESTORE_FPR(29) @ \
+       RESTORE_FPR(30) @ \
+       RESTORE_FPR(31) @ \
+       lwz REG(1),0(REG(1)) @ \
+       lwz REG(0),4(REG(1)) @ \
+       mtcr REG(0) @ \
+       lwz REG(0),8(REG(1)) @ \
+       mtlr REG(0) @ \
+       
+#else  
+
 #define C_FULL_PROLOG \
        mflr 0 ; \
        stw 0,4(1) ; \
@@ -80,10 +225,13 @@ x:
        SAVE_GPR(28) ; \
        SAVE_GPR(29) ; \
        SAVE_GPR(30) ; \
-       SAVE_GPR(31)
-
+       SAVE_GPR(31) ; \
+       mfcr 0  ; \
+       stw 0,8(1)
 
 #define C_FULL_EPILOG \
+       lwz 5,8(1) ; \
+       mtcrf 255,5 ; \
        la 11,FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(1) ; \
        RESTORE_GPR(14) ; \
        RESTORE_GPR(15) ; \
@@ -126,8 +274,7 @@ x:
        lwz 0,4(1) ; \
        mtlr 0 ; \
        
-
-
+#endif
        
        .text
 
@@ -138,8 +285,6 @@ x:
 
        GFUNCDEF(call_into_lisp)
        C_FULL_PROLOG
-       mfcr 0
-       stw 0,8(1)
        /* store(reg_POLL,11,saver2) */
        /* Initialize tagged registers */
        li reg_ZERO,0
@@ -157,19 +302,23 @@ x:
        li reg_L1,0
        li reg_L2,0
        li reg_LIP,0
+#ifdef DARWIN  
+       lis reg_NULL,hi16(NIL)
+       ori reg_NULL,reg_NULL,lo16(NIL)
+#else
        lis reg_NULL,NIL@h
        ori reg_NULL,reg_NULL,NIL@l
-
+#endif
        /* Turn on pseudo-atomic */
 
        li reg_NL3,-4
        li reg_ALLOC,4
-       store(reg_ZERO,reg_NL4,foreign_function_call_active)
-       load(reg_NL4,dynamic_space_free_pointer)
+       store(reg_ZERO,reg_NL4,CSYMBOL(foreign_function_call_active))
+       load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
        add reg_ALLOC,reg_ALLOC,reg_NL4
-       load(reg_BSP,current_binding_stack_pointer)
-       load(reg_CSP,current_control_stack_pointer)
-       load(reg_OCFP,current_control_frame_pointer)
+       load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
+       load(reg_CSP,CSYMBOL(current_control_stack_pointer))
+       load(reg_OCFP,CSYMBOL(current_control_frame_pointer))
 
        /* No longer atomic, and check for interrupt */
        add reg_ALLOC,reg_ALLOC,reg_NL3
@@ -185,8 +334,13 @@ x:
        lwz reg_A3,12(reg_CFP)
 
        /* Calculate LRA */
-       lis reg_LRA,lra@ha
+#ifdef DARWIN
+       lis reg_LRA,ha16(lra)
+       addi reg_LRA,reg_LRA,lo16(lra)
+#else
+       lis reg_LRA,lra@h
        addi reg_LRA,reg_LRA,lra@l
+#endif
        addi reg_LRA,reg_LRA,OTHER_POINTER_LOWTAG
 
        /* Function is an indirect closure */
@@ -206,7 +360,7 @@ lra:
 
        /* Return the one value. */
 
-       mr 3,reg_A0
+       mr REG(3),reg_A0
 
        /* Turn on  pseudo-atomic */
        li reg_NL3,-4
@@ -214,24 +368,22 @@ lra:
 
        /* Store lisp state */
        clrrwi reg_NL1,reg_ALLOC,3
-       store(reg_NL1,reg_NL2,dynamic_space_free_pointer)
+       store(reg_NL1,reg_NL2,CSYMBOL(dynamic_space_free_pointer))
        /* store(reg_POLL,reg_NL2,poll_flag) */
        /* load(reg_NL2,current_thread) */
-       store(reg_BSP,reg_NL2,current_binding_stack_pointer)
-       store(reg_CSP,reg_NL2,current_control_stack_pointer)
-       store(reg_CFP,reg_NL2,current_control_frame_pointer)
+       store(reg_BSP,reg_NL2,CSYMBOL(current_binding_stack_pointer))
+       store(reg_CSP,reg_NL2,CSYMBOL(current_control_stack_pointer))
+       store(reg_CFP,reg_NL2,CSYMBOL(current_control_frame_pointer))
        /* load(reg_POLL,saver2) */
 
        /* No longer in Lisp. */
-       store(reg_NL1,reg_NL2,foreign_function_call_active)
+       store(reg_NL1,reg_NL2,CSYMBOL(foreign_function_call_active))
 
        /* Check for interrupt */
        add reg_ALLOC,reg_ALLOC,reg_NL3
        twlti reg_ALLOC,0
 
        /* Back to C */
-       lwz 5,8(1)
-       mtcrf 255,5
        C_FULL_EPILOG
        blr
        SET_SIZE(call_into_lisp)
@@ -269,27 +421,37 @@ lra:
 
        /* Store Lisp state */
        clrrwi reg_NFP,reg_ALLOC,3
-       store(reg_NFP,reg_CFUNC,dynamic_space_free_pointer)
+       store(reg_NFP,reg_CFUNC,CSYMBOL(dynamic_space_free_pointer))
        /* load(reg_CFUNC,current_thread) */
        
-       store(reg_BSP,reg_CFUNC,current_binding_stack_pointer)
-       store(reg_CSP,reg_CFUNC,current_control_stack_pointer)
-       store(reg_CFP,reg_CFUNC,current_control_frame_pointer)
+       store(reg_BSP,reg_CFUNC,CSYMBOL(current_binding_stack_pointer))
+       store(reg_CSP,reg_CFUNC,CSYMBOL(current_control_stack_pointer))
+       store(reg_CFP,reg_CFUNC,CSYMBOL(current_control_frame_pointer))
 
        /* No longer in Lisp */
-       store(reg_CSP,reg_CFUNC,foreign_function_call_active)
+       store(reg_CSP,reg_CFUNC,CSYMBOL(foreign_function_call_active))
        /* load(reg_POLL,saver2) */
        /* Disable pseudo-atomic; check pending interrupt */
        add reg_ALLOC,reg_ALLOC,reg_NL3
        twlti reg_ALLOC,0
        mr reg_NL3,reg_NARGS
 
+#ifdef DARWIN
+       /* PowerOpen (i.e. OS X) requires the callee address in r12
+           (a.k.a. CFUNC), so move it back there, too. */
+       mfctr reg_CFUNC
+#endif
         /* Into C we go. */
        bctrl
 
        /* Re-establish NIL */
+#ifdef DARWIN
+       lis reg_NULL,hi16(NIL)
+       ori reg_NULL,reg_NULL,lo16(NIL)
+#else
        lis reg_NULL,NIL@h
        ori reg_NULL,reg_NULL,NIL@l
+#endif
        /* And reg_ZERO */
        li reg_ZERO,0
 
@@ -316,14 +478,14 @@ lra:
        li reg_ALLOC,4
 
        /* No long in foreign function call. */
-       store(reg_ZERO,reg_NL2,foreign_function_call_active)
+       store(reg_ZERO,reg_NL2,CSYMBOL(foreign_function_call_active))
 
        /* The free pointer may have moved */
-       load(reg_NL4,dynamic_space_free_pointer)
+       load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
        add reg_ALLOC,reg_ALLOC,reg_NL4
 
        /* The BSP wasn't preserved by C, so load it */
-       load(reg_BSP,current_binding_stack_pointer)
+       load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
 
        /* Other lisp stack/frame pointers were preserved by C.
        I can't imagine why they'd have moved */
@@ -349,12 +511,12 @@ lra:
        SET_SIZE(call_into_c)
 
        GFUNCDEF(xundefined_tramp)
-       .globl undefined_tramp
+       .globl CSYMBOL(undefined_tramp)
        .byte 0,0,0,SIMPLE_FUN_HEADER_WIDETAG
        .byte 18<<2
-undefined_tramp:       
+CSYMBOL(undefined_tramp):      
        .byte 0,0,24
-       .long undefined_tramp
+       .long CSYMBOL(undefined_tramp)
        .long NIL
        .long NIL
        .long NIL
@@ -372,12 +534,12 @@ undefined_tramp:
        SET_SIZE(xundefined_tramp)
 
        GFUNCDEF(xclosure_tramp)
-       .globl closure_tramp
+       .globl CSYMBOL(closure_tramp)
        .byte 0,0,0,SIMPLE_FUN_HEADER_WIDETAG
        .byte 18<<2
-closure_tramp:
+CSYMBOL(closure_tramp):
        .byte 0,0,24
-       .long closure_tramp
+       .long CSYMBOL(closure_tramp)
        .long NIL 
        .long NIL
        .long NIL
@@ -408,9 +570,9 @@ closure_tramp:
 
 
        GFUNCDEF(ppc_flush_cache_line)
-       dcbf 0,3
+       dcbf 0,REG(3)
        sync
-       icbi 0,3
+       icbi 0,REG(3)
        sync
        isync
        blr