string asis macro lea &r,&a lwz &r,&a{TC}(RTOC) endm ; MACOSX set 1 ; POWER601 set 1 ALLOCATION_PROFILE set 1 USE_TEMPORARY_MEMORY set 1 CHECK_STACK_OVERFLOWS set 0 MODULE_NAMES set 1 if POWER601 macro time_hi &r dialect Power mfrtcu &r dialect PowerPC endm macro time_lo &r dialect Power mfrtcl &r dialect PowerPC endm else macro time_hi &r mftbu &r endm macro time_lo &r mftb &r endm endif d0: set r24 d1: set r25 d2: set r26 d3: set r27 d4: set r28 d5: set r29 d6: set r30 d7: set r31 a0: set r23 a1: set r22 a2: set r21 a3: set r20 a4: set r19 a5: set r18 a6: set r17 o0: set r3 o1: set r4 o2: set r5 o3: set r6 o4: set r7 o5: set r8 g2: set r9 g3: set r10 g0: set r11 g1: set r12 int_reg set r16 char_reg set r15 real_reg set r14 bool_reg set r13 if POWER601 lo1e9 set 1000000000 % 65536 hi1e9 set (1000000000 / 65536)+1 endif export init_profiler export profile_r export profile_l export profile_l2 export profile_n export profile_n2 export profile_s export profile_s2 export profile_t export profile_ti export write_profile_information export write_profile_stack if USE_TEMPORARY_MEMORY import .TempNewHandle import .TempHLock import .TempHUnlock import .TempDisposeHandle else import .NewPtr endif import .Gestalt import __STRING__ import openF import closeF import writeFC import writeFI import print_error import new_file_creator import stack_size import .er_print_string import .er_print_char import .create_profile_file_name if CHECK_STACK_OVERFLOWS import .Debugger endif FunctionProfile: record next: ds.l 1 time_hi: ds.l 1 time_lo: ds.l 1 n_profiler_calls: ds.l 1 n_strict_calls: ds.l 1 n_lazy_calls: ds.l 1 n_curried_calls: ds.l 1 n_words_allocated: ds.l 1 name: ds.l 1 endr csect .profile_t profile_ti: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock lea r5,profile_globals b profile_t_ profile_t: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals mtctr r12 mtlr r0 profile_t_: lwz r6,Globals.stack_pointer(r5) lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) lwzu r4,-4(r6) stw r6,Globals.stack_pointer(r5) stw r4,Globals.last_tail_call(r5) if POWER601 sub. r10,r10,r8 sub r9,r9,r7 bge+ @no_borrow addis r10,r10,hi1e9 addi r10,r10,lo1e9 subi r9,r9,1 @no_borrow: else subc r10,r10,r8 subfe r9,r7,r9 endif lwz r8,FunctionProfile.time_lo(r4) lwz r7,FunctionProfile.time_hi(r4) if POWER601 add r8,r8,r10 add r7,r7,r9 subis r9,r8,hi1e9 cmpwi 0,r9,lo1e9 lwz r6,FunctionProfile.n_profiler_calls(r4) blt+ @no_carry subi r8,r9,lo1e9 addi r7,r7,1 @no_carry: else addc r8,r8,r10 lwz r6,FunctionProfile.n_profiler_calls(r4) adde r7,r7,r9 endif addi r6,r6,1 stw r7,FunctionProfile.time_hi(r4) stw r8,FunctionProfile.time_lo(r4) stw r6,FunctionProfile.n_profiler_calls(r4) if ALLOCATION_PROFILE lwz r11,Globals.n_words_free(r5) stw d7,Globals.n_words_free(r5) lwz r12,FunctionProfile.n_words_allocated(r4) sub r11,r11,d7 add r12,r12,r11 stw r12,FunctionProfile.n_words_allocated(r4) endif @store_clock: time_hi r9 stw r9,Globals.time_hi(r5) time_lo r10 time_hi r4 stw r10,Globals.time_lo(r5) cmpw 0,r4,r9 beqctr+ b @store_clock csect .profile_r profile_r: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock lea r5,profile_globals lwz r6,Globals.stack_pointer(r5) lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) lwzu r4,-4(r6) li r3,0 stw r6,Globals.stack_pointer(r5) stw r3,Globals.last_tail_call(r5) if POWER601 sub. r10,r10,r8 sub r9,r9,r7 bge+ @no_borrow addis r10,r10,hi1e9 addi r10,r10,lo1e9 subi r9,r9,1 @no_borrow: else subc r10,r10,r8 subfe r9,r7,r9 endif lwz r8,FunctionProfile.time_lo(r4) lwz r7,FunctionProfile.time_hi(r4) if POWER601 add r8,r8,r10 add r7,r7,r9 subis r9,r8,hi1e9 cmpwi 0,r9,lo1e9 lwz r6,FunctionProfile.n_profiler_calls(r4) blt+ @no_carry subi r8,r9,lo1e9 addi r7,r7,1 @no_carry: else addc r8,r8,r10 lwz r6,FunctionProfile.n_profiler_calls(r4) adde r7,r7,r9 endif addi r6,r6,1 stw r7,FunctionProfile.time_hi(r4) stw r8,FunctionProfile.time_lo(r4) stw r6,FunctionProfile.n_profiler_calls(r4) if ALLOCATION_PROFILE lwz r11,Globals.n_words_free(r5) stw d7,Globals.n_words_free(r5) lwz r12,FunctionProfile.n_words_allocated(r4) sub r11,r11,d7 add r12,r12,r11 stw r12,FunctionProfile.n_words_allocated(r4) endif @store_clock: time_hi r9 stw r9,Globals.time_hi(r5) time_lo r10 time_hi r4 stw r10,Globals.time_lo(r5) cmpw 0,r4,r9 beqlr+ b @store_clock csect .profile_l profile_l: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne @use_tail_calling_function lwz r3,-4(r6) @c_use_tail_calling_function: 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 lwz r6,FunctionProfile.n_curried_calls(r4) mtlr r0 addi r6,r6,1 stw r6,FunctionProfile.n_curried_calls(r4) b profile_n_ @use_tail_calling_function: li r12,0 stw r12,Globals.last_tail_call(r5) b @c_use_tail_calling_function csect .profile_l2 profile_l2: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne @use_tail_calling_function lwz r3,-4(r6) @c_use_tail_calling_function: 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 lwz r6,FunctionProfile.n_curried_calls(r4) mtlr r0 addi r6,r6,1 stw r6,FunctionProfile.n_curried_calls(r4) b profile_n_ @use_tail_calling_function: li r12,0 stw r12,Globals.last_tail_call(r5) b @c_use_tail_calling_function csect .profile_n profile_n: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne @use_tail_calling_function lwz r3,-4(r6) @c_use_tail_calling_function: 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 lwz r6,FunctionProfile.n_lazy_calls(r4) mtlr r0 addi r6,r6,1 stw r6,FunctionProfile.n_lazy_calls(r4) b profile_n_ @use_tail_calling_function: li r12,0 stw r12,Globals.last_tail_call(r5) b @c_use_tail_calling_function csect .profile_n2 profile_n2: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne @use_tail_calling_function lwz r3,-4(r6) @c_use_tail_calling_function: 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 lwz r6,FunctionProfile.n_lazy_calls(r4) mtlr r0 addi r6,r6,1 stw r6,FunctionProfile.n_lazy_calls(r4) b profile_n_ @use_tail_calling_function: li r12,0 stw r12,Globals.last_tail_call(r5) b @c_use_tail_calling_function csect .profile_s2 profile_s2: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne @use_tail_calling_function lwz r3,-4(r6) @c_use_tail_calling_function: 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 b profile_s_ @use_tail_calling_function: li r12,0 stw r12,Globals.last_tail_call(r5) b @c_use_tail_calling_function csect .profile_s profile_s: @read_clock: time_hi r9 time_lo r10 time_hi r4 cmpw 0,r4,r9 bne- @read_clock mflr r12 lea r5,profile_globals lwz r4,0(r3) mtctr r12 cmpwi 0,r4,0 beql allocate_function_profile_record lwz r3,Globals.last_tail_call(r5) lwz r6,Globals.stack_pointer(r5) cmpwi 0,r3,0 lwz r7,Globals.time_hi(r5) lwz r8,Globals.time_lo(r5) bne use_tail_calling_function0 lwz r3,-4(r6) c_use_tail_calling_function0: 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 profile_s_: lwz r6,FunctionProfile.n_strict_calls(r4) mtlr r0 addi r6,r6,1 stw r6,FunctionProfile.n_strict_calls(r4) profile_n_: if POWER601 sub. r10,r10,r8 sub r9,r9,r7 bge+ @no_borrow addis r10,r10,hi1e9 addi r10,r10,lo1e9 subi r9,r9,1 @no_borrow: else subc r10,r10,r8 subfe r9,r7,r9 endif lwz r8,FunctionProfile.time_lo(r3) lwz r7,FunctionProfile.time_hi(r3) if POWER601 add r8,r8,r10 add r7,r7,r9 subis r9,r8,hi1e9 cmpwi 0,r9,lo1e9 lwz r6,FunctionProfile.n_profiler_calls(r3) blt+ @no_carry subi r8,r9,lo1e9 addi r7,r7,1 @no_carry: else addc r8,r8,r10 lwz r6,FunctionProfile.n_profiler_calls(r3) adde r7,r7,r9 endif addi r6,r6,1 stw r7,FunctionProfile.time_hi(r3) stw r8,FunctionProfile.time_lo(r3) stw r6,FunctionProfile.n_profiler_calls(r3) if ALLOCATION_PROFILE lwz r11,Globals.n_words_free(r5) stw d7,Globals.n_words_free(r5) lwz r12,FunctionProfile.n_words_allocated(r3) sub r11,r11,d7 add r12,r12,r11 stw r12,FunctionProfile.n_words_allocated(r3) endif @store_clock: time_hi r9 stw r9,Globals.time_hi(r5) time_lo r10 time_hi r4 stw r10,Globals.time_lo(r5) cmpw 0,r4,r9 beqctr+ b @store_clock use_tail_calling_function0: li r12,0 stw r12,Globals.last_tail_call(r5) b c_use_tail_calling_function0 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,(128*FunctionProfile)+4 else li r3,128*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,128 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 r8,FunctionProfile.time_hi(r4) stw r8,FunctionProfile.time_lo(r4) stw r8,FunctionProfile.n_profiler_calls(r4) stw r8,FunctionProfile.n_strict_calls(r4) stw r8,FunctionProfile.n_lazy_calls(r4) stw r8,FunctionProfile.n_curried_calls(r4) stw r8,FunctionProfile.n_words_allocated(r4) stw r6,FunctionProfile.next(r4) stw r4,Globals.profile_records(r5) stw r3,FunctionProfile.name(r4) stw r4,0(r3) blr csect .write_profile_information write_profile_information: lea o0,profile_file_name mflr r0 stwu r0,-4(sp) if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) else stwu sp,-64(sp) endif bl .create_profile_file_name nop if MACOSX lwz sp,0(sp) lwz r0,0(sp) addi sp,sp,4 else lwz r0,64(sp) addi sp,sp,68 endif mtlr r0 lea d3,new_file_creator li d5,'T'*256+'I' lwz d4,0(d3) addis d5,d5,'P'*256+'R' stw d5,0(d3) li d0,1 lea a0,profile_file_name mflr r0 stwu r0,-4(sp) bl openF mtlr r0 stw d4,0(d3) cmpwi 0,d2,0 beq cannot_open mflr r0 li d3,0 stw r0,-4(sp) stwu d3,-8(sp) if MACOSX mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) else stwu sp,-64(sp) endif stw d3,64(sp) li r3,'u'*256+'t' addi r4,sp,64 addis r3,r3,'c'*256+'p' bl .Gestalt nop lwz d2,64(sp) stwu r0,-4(sp) bl writeFI_space mtlr r0 stw d3,64(sp) li r3,'l'*256+'k' addi r4,sp,64 addis r3,r3,'p'*256+'c' bl .Gestalt nop lwz d2,64(sp) stwu r0,-4(sp) bl writeFI_space mtlr r0 stw d3,64(sp) li r3,'l'*256+'k' addi r4,sp,64 addis r3,r3,'b'*256+'c' bl .Gestalt nop lwz d2,64(sp) stwu r0,-4(sp) bl writeFI mtlr r0 li d2,13 stwu r0,-4(sp) bl writeFC mtlr r0 if MACOSX lwz sp,0(sp) lwz r0,4(sp) addi sp,sp,8 else lwz r0,68(sp) addi sp,sp,72 endif mtlr r0 lea d2,profile_globals lwz d2,Globals.profile_records(d2) write_profile_lp: cmpwi 0,d2,0 beq end_list lwz d3,FunctionProfile.name(d2) stwu d2,-4(sp) #if MODULE_NAMES stwu d3,-4(sp) lwz d3,-4(d3) lwz d2,0(d3) addi d3,d3,3 write_module_name_lp: subic. d2,d2,1 blt end_module_name stw d2,-4(sp) lbzu d2,1(d3) mflr r0 stw d3,-8(sp) stwu r0,-12(sp) bl writeFC mtlr r0 lwz d2,4(sp) lwz d3,0(sp) addi sp,sp,8 b write_module_name_lp end_module_name: li d2,' ' mflr r0 stwu r0,-4(sp) bl writeFC mtlr r0 lwz d3,0(sp) addi sp,sp,4 #endif addi d3,d3,3 write_function_name_lp: lbzu d2,1(d3) cmpwi 0,d2,0 beq end_function_name stw d3,-4(sp) mflr r0 stwu r0,-8(sp) bl writeFC mtlr r0 lwz d3,0(sp) addi sp,sp,4 b write_function_name_lp end_function_name: li d2,' ' mflr r0 stwu r0,-4(sp) bl writeFC lwz d2,0(sp) lwz d2,FunctionProfile.n_strict_calls(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.n_lazy_calls(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.n_curried_calls(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.n_profiler_calls(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.n_words_allocated(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.time_hi(d2) stwu r0,-4(sp) bl writeFI_space lwz d2,0(sp) lwz d2,FunctionProfile.time_lo(d2) stwu r0,-4(sp) bl writeFI li d2,13 stwu r0,-4(sp) bl writeFC mtlr r0 lwz d2,0(sp) addi sp,sp,4 lwz d2,FunctionProfile.next(d2) b write_profile_lp writeFI_space: mflr r0 stwu r0,-4(sp) bl writeFI mtlr r0 li d2,' ' b writeFC end_list: mflr r0 stwu r0,-4(sp) bl closeF mtlr r0 cannot_open: 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 csect .write_profile_stack 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 nop if MACOSX lwz sp,0(sp) else addi sp,sp,64 endif if 1 li d2,12 else li d2,24 endif @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 nop li o0,13 bl .er_print_char nop 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 csect .init_profiler 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 MACOSX subi sp,sp,8 mr g0,sp ori sp,sp,28 stwu g0,-(64+28)(sp) else stwu sp,-72(sp) endif li r3,0 addi r4,sp,64 stw r3,64(sp) li r3,'u'*256+'t' addis r3,r3,'c'*256+'p' bl .Gestalt nop lwz r3,64(sp) if MACOSX lwz sp,0(sp) addi sp,sp,8 else addi sp,sp,72 endif cmpwi 0,r3,257 if POWER601 bne init_profiler_error1 else beq init_profiler_error1 endif if 1 lea r3,stack_size lwz r3,0(r3) addi r3,r3,4095 rlwinm r3,r3,0,0,31-12 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 r0,Globals.last_tail_call(r5) stw d7,Globals.n_words_free(r5) lwz r0,0(sp) addi sp,sp,4 @store_clock: time_hi r9 stw r9,Globals.time_hi(r5) time_lo r10 time_hi r4 stw r10,Globals.time_lo(r5) cmpw 0,r4,r9 beqlr+ b @store_clock 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 .TempNewHandle nop mr. r31,r3 beq return_r31 addi r4,sp,56 bl .TempHLock nop lha r0,56(sp) cmpwi r0,0 beq+ return_r31 mr r3,r31 addi r4,sp,56 bl .TempDisposeHandle 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 .TempHUnlock nop lwz r3,96-4(sp) addi r4,sp,56 bl .TempDisposeHandle nop lwz r0,104(sp) addi sp,sp,96 mtlr r0 blr endif init_profiler_error1: lea o0,wrong_processor lea r5,profile_globals li r4,0 stw r4,Globals.stack_pointer(r5) b print_error 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 csect data{RW} Globals: record n_free_records_in_block:ds.l 1 ; 0 n free records in block last_allocated_block: ds.l 1 ; 4 latest allocated block profile_records: ds.l 1 ; 8 profile record list time_hi: ds.l 1 ; 12 clock time_lo: ds.l 1 stack_pointer: ds.l 1 ; 20 stack pointer last_tail_call ds.l 1 ; 24 last tail calling function n_words_free: ds.l 1 if USE_TEMPORARY_MEMORY temp_handle_list ds.l 1 profile_stack_handle ds.l 1 endif if CHECK_STACK_OVERFLOWS end_profile_stack ds.l 1 endif endr align 2 profile_globals: ds Globals profile_file_name: dc.l __STRING__+2 dc.l 0 ds.b 32 align 2 if MODULE_NAMES m_system: dc.l 6 dc.b 'System' dc.b 0,0 dc.l m_system endif start_string: dc.l 0 dc.b 'start' dc.b 0 align 2 not_enough_memory_for_profile_stack: dc.b 'not enough memory for profile stack' dc.b 13 dc.b 0 not_enough_memory_for_profiler: dc.b 'not enough memory for profiler' dc.b 13 dc.b 0 wrong_processor: if POWER601 dc.b 'Not a PowerPC601 processor (don''t use profiling option for 601)' else dc.b 'This is a PowerPC601 processor (use profiling option for 601)' endif dc.b 13 dc.b 0 stack_trace_string: dc.b 'Stack trace:' dc.b 13 dc.b 0 align 2 macro te &address tc &address{TC},&address endm toc te profile_globals te profile_file_name te not_enough_memory_for_profile_stack te not_enough_memory_for_profiler te wrong_processor te start_string te stack_trace_string te new_file_creator te stack_size