.macro lea_ &r,&a lis $0,ha16($1) addi $0,$0,lo16($1) .endmacro MACOSX = 1 USE_TEMPORARY_MEMORY = 1 CHECK_STACK_OVERFLOWS = 0 MODULE_NAMES = 1 #define sp r1 #define d0 r24 #define d1 r25 #define d2 r26 #define d3 r27 #define d4 r28 #define d5 r29 #define d6 r30 #define d7 r31 #define a0 r23 #define a1 r22 #define a2 r21 #define a3 r20 #define a4 r19 #define a5 r18 #define a6 r17 #define o0 r3 #define o1 r4 #define o2 r5 #define o3 r6 #define o4 r7 #define o5 r8 #define g2 r9 #define g3 r10 #define g0 r11 #define g1 r12 #define int_reg r16 #define char_reg r15 #define real_reg r14 #define bool_reg r13 .globl init_profiler .globl profile_r .globl profile_l .globl profile_l2 .globl profile_n .globl profile_n2 .globl profile_s .globl profile_s2 .globl profile_t .globl profile_ti .globl write_profile_information .globl write_profile_stack .if USE_TEMPORARY_MEMORY .globl _TempNewHandle .globl _TempHLock .globl _TempHUnlock .globl _TempDisposeHandle .else .globl _NewPtr .endif .globl __STRING__ .globl writeFC .globl writeFI .globl print_error .globl _stack_size .globl _er_print_string .globl _er_print_char .if CHECK_STACK_OVERFLOWS .globl _Debugger .endif #define FunctionProfile_next 0 #define FunctionProfile_name 4 #define FunctionProfile 8 #define Globals_n_free_records_in_block 0 # comment 0 n free records in block #define Globals_last_allocated_block 4 # comment 4 latest allocated block #define Globals_profile_records 8 # comment 8 profile record list #define Globals_stack_pointer 12 # comment 12 stack pointer #define Globals_n_words_free 16 .if USE_TEMPORARY_MEMORY #define Globals_temp_handle_list 20 #define Globals_profile_stack_handle 24 .if CHECK_STACK_OVERFLOWS Globals_end_profile_stack = 28 Globals = 32 .else Globals = 28 .endif .else .if CHECK_STACK_OVERFLOWS Globals_end_profile_stack = 20 Globals = 24 .else Globals = 20 .endif .endif .text profile_ti: lea_ r5,profile_globals b profile_t_ profile_t: mflr r12 lea_ r5,profile_globals mtctr r12 mtlr r0 profile_t_: lwz r6,Globals_stack_pointer(r5) lwzu r4,-4(r6) stw r6,Globals_stack_pointer(r5) bctr profile_r: lea_ r5,profile_globals lwz r6,Globals_stack_pointer(r5) lwzu r4,-4(r6) stw r6,Globals_stack_pointer(r5) blr profile_l: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) addi r6,r6,4 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr profile_l2: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) stw r4,4(r6) addi r6,r6,8 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr profile_n: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) addi r6,r6,4 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr profile_n2: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) stw r4,4(r6) addi r6,r6,8 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr profile_s2: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) stw r4,4(r6) addi r6,r6,8 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr profile_s: mflr r12 lea_ r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r6,Globals_stack_pointer(r5) stw r4,0(r6) addi r6,r6,4 .if CHECK_STACK_OVERFLOWS lwz r12,Globals_end_profile_stack(r5) .endif stw r6,Globals_stack_pointer(r5) .if CHECK_STACK_OVERFLOWS cmpw r6,r12 bge profile_stack_overflow .endif mtlr r0 bctr allocate_function_profile_record: lwz r6,Globals_n_free_records_in_block(r5) lwz r4,Globals_last_allocated_block(r5) cmpwi 0,r6,0 bne+ no_alloc stw r0,-4(sp) stw r3,-8(sp) stw r9,-12(sp) stw r10,-16(sp) mfctr r11 stw r11,-20(sp) mflr r12 stw r12,-24(sp) .if USE_TEMPORARY_MEMORY li r3,(512*FunctionProfile)+4 .else li r3,512*FunctionProfile .endif .if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+32+28)(sp) .else stwu sp,-(64+32)(sp) .endif .if USE_TEMPORARY_MEMORY bl allocate_temp_memory_handle .else bl _NewPtr nop .endif .if MACOSX lwz sp,0(sp) .else addi sp,sp,64+32 .endif and. r4,r3,r3 lwz r12,-24(sp) lwz r11,-20(sp) mtlr r12 lwz r10,-16(sp) mtctr r11 lwz r9,-12(sp) lwz r3,-8(sp) lwz r0,-4(sp) lea_ r5,profile_globals beq profiler_memory_error .if USE_TEMPORARY_MEMORY lwz r6,Globals_temp_handle_list(r5) stw r4,Globals_temp_handle_list(r5) lwz r4,0(r4) stw r6,0(r4) addi r4,r4,4 .endif li r6,512 stw r4,Globals_last_allocated_block(r5) no_alloc: subi r6,r6,1 stw r6,Globals_n_free_records_in_block(r5) addi r7,r4,FunctionProfile stw r7,Globals_last_allocated_block(r5) lwz r6,Globals_profile_records(r5) li r8,0 stw r6,FunctionProfile_next(r4) stw r4,Globals_profile_records(r5) stw r3,FunctionProfile_name(r4) stw r4,0(r3) blr write_profile_information: .if USE_TEMPORARY_MEMORY mflr r0 .if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(96+28)(sp) .else stwu sp,-96(sp) .endif stw r0,96-4(sp) lea_ r5,profile_globals lwz r3,Globals_profile_stack_handle(r5) bl free_temp_memory_handle lea_ r5,profile_globals stw r31,96-8(sp) lwz r31,Globals_temp_handle_list(r5) b free_temp_handles free_temp_handles_lp: mr r3,r31 lwz r31,0(r31) lwz r31,0(r31) bl free_temp_memory_handle free_temp_handles: cmpwi 0,r31,0 bne free_temp_handles_lp lwz r31,96-8(sp) lwz r0,96-4(sp) .if MACOSX lwz sp,0(sp) .else addi sp,sp,96 .endif mtlr r0 .endif lwz r0,0(sp) addi sp,sp,4 blr write_profile_stack: mflr r0 lea_ d0,profile_globals stwu r0,-4(sp) lwz d0,Globals_stack_pointer(d0) cmpwi 0,d0,0 beq stack_not_initialised .if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) .else stwu sp,-64(sp) .endif lea_ o0,stack_trace_string bl _er_print_string .if MACOSX lwz sp,0(sp) .else addi sp,sp,64 .endif li d2,12 write_functions_on_stack: lwzu d1,-4(d0) cmpwi 0,d1,0 beq end_profile_stack lwz o0,FunctionProfile_name(d1) .if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) .else stwu sp,-64(sp) .endif addi o0,o0,4 bl _er_print_string li o0,13 bl _er_print_char .if MACOSX lwz sp,0(sp) .else addi sp,sp,64 .endif subic. d2,d2,1 .if 0 b write_functions_on_stack .else bne write_functions_on_stack .endif end_profile_stack: stack_not_initialised: lwz r0,0(sp) mtlr r0 lwz r0,4(sp) addi sp,sp,8 blr init_profiler: .if 0 mflr r0 stw r0,-4(sp) stwu sp,-64(sp) bl .Debugger nop lwz r0,64-4(sp) addi sp,sp,64 mtlr r0 .endif mflr r0 stwu r0,-4(sp) .if 1 lea_ r3,_stack_size lwz r3,0(r3) .else li r3, (512*1024) % 65536 addis r3,r3,(512*1024) / 65536 .endif .if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) .else stwu sp,-64(sp) .endif .if USE_TEMPORARY_MEMORY bl allocate_temp_memory_handle .else bl _NewPtr nop .endif .if MACOSX lwz sp,0(sp) .else addi sp,sp,64 .endif lea_ r5,profile_globals and. r9,r3,r3 beq init_profiler_error .if USE_TEMPORARY_MEMORY stw r9,Globals_profile_stack_handle(r5) lwz r9,0(r9) li r0,0 stw r0,Globals_temp_handle_list(r5) .endif .if CHECK_STACK_OVERFLOWS .if 1 lea_ r3,_stack_size lwz r3,0(r3) .else li r3, (512*1024) % 65536 addis r3,r3,(512*1024) / 65536 .endif add r3,r3,r9 stw r3,Globals_end_profile_stack(r5) .endif lea_ r3,start_string bl allocate_function_profile_record lwz r0,0(sp) addi sp,sp,4 mtlr r0 li r0,0 stw r4,4(r9) stw r0,0(r9) addi r9,r9,8 stw r9,Globals_stack_pointer(r5) stw d7,Globals_n_words_free(r5) lwz r0,0(sp) addi sp,sp,4 blr .if USE_TEMPORARY_MEMORY allocate_temp_memory_handle: mflr r0 stw r31,-4(sp) stw r0,8(sp) stwu sp,-96(sp) addi r4,sp,56 bl L_TempNewHandle$stub nop mr. r31,r3 beq return_r31 addi r4,sp,56 bl L_TempHLock$stub nop lha r0,56(sp) cmpwi r0,0 beq+ return_r31 mr r3,r31 addi r4,sp,56 bl L_TempDisposeHandle$stub nop li r31,0 return_r31: lwz r0,104(sp) mr r3,r31 mtlr r0 addi sp,sp,96 lwz r31,-4(sp) blr free_temp_memory_handle: mflr r0 stw r3,-4(sp) stw r0,8(sp) stwu sp,-96(sp) addi r4,sp,56 bl L_TempHUnlock$stub nop lwz r3,96-4(sp) addi r4,sp,56 bl L_TempDisposeHandle$stub nop lwz r0,104(sp) addi sp,sp,96 mtlr r0 blr .endif init_profiler_error: lea_ o0,not_enough_memory_for_profile_stack lea_ r5,profile_globals li r4,0 stw r4,Globals_stack_pointer(r5) b print_error profiler_memory_error: lea_ o0,not_enough_memory_for_profiler b print_error .if CHECK_STACK_OVERFLOWS profile_stack_overflow: mflr r0 stw r0,-4(sp) stwu sp,-64(sp) bl .Debugger nop lwz r0,64-4(sp) addi sp,sp,64 mtlr r0 b profile_stack_overflow .endif .data .align 2 .comm profile_globals,Globals .align 2 .if MODULE_NAMES m_system_: .long 6 .ascii "System" .byte 0,0 .long m_system_ .endif start_string: .long 0 .ascii "start" .byte 0 .align 2 not_enough_memory_for_profile_stack: .ascii "not enough memory for profile stack" .byte 13 .byte 0 not_enough_memory_for_profiler: .ascii "not enough memory for profiler" .byte 13 .byte 0 stack_trace_string: .ascii "Stack trace:" .byte 13 .byte 0 .align 2 .picsymbol_stub L_TempDisposeHandle$stub: .indirect_symbol _TempDisposeHandle mflr r0 bcl 20,31,L21$pb L21$pb: mflr r11 addis r11,r11,ha16(L21$lz-L21$pb) mtlr r0 lwz r12,lo16(L21$lz-L21$pb)(r11) mtctr r12 addi r11,r11,lo16(L21$lz-L21$pb ) bctr .lazy_symbol_pointer L21$lz: .indirect_symbol _TempDisposeHandle .long dyld_stub_binding_helper .picsymbol_stub L_TempHLock$stub: .indirect_symbol _TempHLock mflr r0 bcl 20,31,L22$pb L22$pb: mflr r11 addis r11,r11,ha16(L22$lz-L22$pb) mtlr r0 lwz r12,lo16(L22$lz-L22$pb)(r11) mtctr r12 addi r11,r11,lo16(L22$lz-L22$pb ) bctr .lazy_symbol_pointer L22$lz: .indirect_symbol _TempHLock .long dyld_stub_binding_helper .picsymbol_stub L_TempHUnlock$stub: .indirect_symbol _TempHUnlock mflr r0 bcl 20,31,L23$pb L23$pb: mflr r11 addis r11,r11,ha16(L23$lz-L23$pb) mtlr r0 lwz r12,lo16(L23$lz-L23$pb)(r11) mtctr r12 addi r11,r11,lo16(L23$lz-L23$pb ) bctr .lazy_symbol_pointer L23$lz: .indirect_symbol _TempHUnlock .long dyld_stub_binding_helper .picsymbol_stub L_TempNewHandle$stub: .indirect_symbol _TempNewHandle mflr r0 bcl 20,31,L24$pb L24$pb: mflr r11 addis r11,r11,ha16(L24$lz-L24$pb) mtlr r0 lwz r12,lo16(L24$lz-L24$pb)(r11) mtctr r12 addi r11,r11,lo16(L24$lz-L24$pb ) bctr .lazy_symbol_pointer L24$lz: .indirect_symbol _TempNewHandle .long dyld_stub_binding_helper