#if defined(__ppc64__) #define MODE_CHOICE(x, y) y #else #define MODE_CHOICE(x, y) x #endif #define machine_choice MODE_CHOICE(ppc7400,ppc64) ; Define some pseudo-opcodes for size-independent load & store of GPRs ... #define lgu MODE_CHOICE(lwzu, ldu) #define lg MODE_CHOICE(lwz,ld) #define sg MODE_CHOICE(stw,std) #define sgu MODE_CHOICE(stwu,stdu) ; ... and the size of GPRs and their storage indicator. #define GPR_BYTES MODE_CHOICE(4,8) #define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ #define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ ; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04. #define LINKAGE_SIZE MODE_CHOICE(24,48) #define PARAM_AREA MODE_CHOICE(32,64) #define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */ ; The whole stack frame **MUST** be 16byte-aligned. #define SAVE_SIZE (LINKAGE_SIZE+PARAM_AREA) #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 ; We no longer need the pic symbol stub for Darwin >= 9. #define BLGCP1 _GC_push_one #undef WANT_STUB #else #define BLGCP1 L_GC_push_one$stub #define WANT_STUB #endif .machine machine_choice ; GC_push_regs function. Under some optimization levels GCC will clobber ; some of the non-volatile registers before we get a chance to save them ; therefore, this cannot be inline asm. .text .align LOG2_GPR_BYTES .globl _GC_push_regs _GC_push_regs: ; Prolog mflr r0 sg r0,SAVED_LR_OFFSET(r1) sgu r1,-SAVE_SIZE(r1) L_body: ; 'Push' r13-r31 mr r3,r13 bl BLGCP1 mr r3,r14 bl BLGCP1 mr r3,r15 bl BLGCP1 mr r3,r16 bl BLGCP1 mr r3,r17 bl BLGCP1 mr r3,r18 bl BLGCP1 mr r3,r19 bl BLGCP1 mr r3,r20 bl BLGCP1 mr r3,r21 bl BLGCP1 mr r3,r22 bl BLGCP1 mr r3,r23 bl BLGCP1 mr r3,r24 bl BLGCP1 mr r3,r25 bl BLGCP1 mr r3,r26 bl BLGCP1 mr r3,r27 bl BLGCP1 mr r3,r28 bl BLGCP1 mr r3,r29 bl BLGCP1 mr r3,r30 bl BLGCP1 mr r3,r31 bl BLGCP1 L_epilog: ; Epilog lg r0,SAVE_SIZE+SAVED_LR_OFFSET(r1) addi r1,r1,SAVE_SIZE mtlr r0 ; Return blr LFE0: ; eh frames, for those that want 'em. #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) #define EH_FRAME_OFFSET MODE_CHOICE(0x40,0x70) .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 .long L$set$0 ; Length of Common Information Entry LSCIE1: .long 0 ; CIE Identifier Tag .byte 0x1 ; CIE Version .ascii "zR\0" ; CIE Augmentation .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor .byte EH_DATA_ALIGN_FACT ; sleb128 -4/-8; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0 ; uleb128 0 .align LOG2_GPR_BYTES LECIE1: .globl _GC_push_regs.eh _GC_push_regs.eh: LSFDE1: .set L$set$1,LEFDE1-LASFDE1 .long L$set$1 ; FDE Length LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset .g_long _GC_push_regs-. ; FDE initial location .set L$set$2,LFE0-_GC_push_regs .g_long L$set$2 ; FDE address range .byte 0 ; uleb128 0; Augmentation size .byte 0x4 ; DW_CFA_advance_loc4 .set L$set$3,L_body-_GC_push_regs .long L$set$3 .byte 0xe ; DW_CFA_def_cfa_offset .byte EH_FRAME_OFFSET ; uleb128 0x40/0x70 .byte 0x11 ; DW_CFA_offset_extended_sf .byte 0x41 ; uleb128 0x41 .byte 0x7e ; sleb128 -2 .byte 0x4 ; DW_CFA_advance_loc4 .set L$set$4,L_epilog-L_body .long L$set$4 .byte 0xe ; DW_CFA_def_cfa_offset .byte 0 ; uleb128 0 .align LOG2_GPR_BYTES LEFDE1: .data #ifdef WANT_STUB ; PIC stub stuff, generated by GCC .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .align LOG2_GPR_BYTES L_GC_push_one$stub: .indirect_symbol _GC_push_one mflr r0 bcl 20,31,L0$_GC_push_one L0$_GC_push_one: mflr r11 addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one) mtlr r0 lgu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11) mtctr r12 bctr .data .lazy_symbol_pointer L_GC_push_one$lazy_ptr: .indirect_symbol _GC_push_one .g_long dyld_stub_binding_helper #endif