--- hatari/src/debug/profiledsp.c 2019/04/09 08:53:07 1.1 +++ hatari/src/debug/profiledsp.c 2019/04/09 08:59:21 1.1.1.5 @@ -1,7 +1,7 @@ /* * Hatari - profiledsp.c * - * Copyright (C) 2010-2013 by Eero Tamminen + * Copyright (C) 2010-2015 by Eero Tamminen * * This file is distributed under the GNU General Public License, version 2 * or at your option any later version. Read the file gpl.txt for details. @@ -12,14 +12,19 @@ const char Profiledsp_fileid[] = "Hatari #include #include +#include #include #include "main.h" #include "configuration.h" #include "clocks_timings.h" #include "dsp.h" +#include "symbols.h" #include "profile.h" #include "profile_priv.h" -#include "symbols.h" +#include "debug_priv.h" +/* for VBL info */ +#include "screen.h" +#include "video.h" static callinfo_t dsp_callinfo; @@ -38,6 +43,9 @@ static struct { profile_area_t ram; /* statistics for whole memory */ Uint16 *sort_arr; /* data indexes used for sorting */ Uint16 prev_pc; /* previous PC for which the cycles are for */ + Uint16 loop_start; /* address of last loop start */ + Uint16 loop_end; /* address of last loop end */ + Uint32 loop_count; /* how many times it was looped */ Uint32 disasm_addr; /* 'dspaddresses' command start address */ bool processed; /* true when data is already processed */ bool enabled; /* true when profiling enabled */ @@ -96,7 +104,7 @@ void Profile_DspShowStats(void) */ fprintf(stderr, "- sum of per instruction cycle changes\n" " (can indicate code change during profiling):\n %"PRIu64"\n", - area->counters.misses); + area->counters.cycles_diffs); fprintf(stderr, "- used cycles:\n %"PRIu64"\n", area->counters.cycles); @@ -110,9 +118,9 @@ void Profile_DspShowStats(void) * Show DSP instructions which execution was profiled, in the address order, * starting from the given address. Return next disassembly address. */ -Uint16 Profile_DspShowAddresses(Uint32 addr, Uint32 upper, FILE *out) +Uint16 Profile_DspShowAddresses(Uint32 addr, Uint32 upper, FILE *out, paging_t use_paging) { - int show, shown, active; + int show, shown, addrs, active; dsp_profile_item_t *data; Uint16 nextpc; Uint32 end; @@ -126,37 +134,46 @@ Uint16 Profile_DspShowAddresses(Uint32 a end = DSP_PROFILE_ARR_SIZE; active = dsp_profile.ram.active; - show = ConfigureParams.Debugger.nDisasmLines; if (upper) { if (upper < end) { end = upper; } - show = active; - } else { - show = ConfigureParams.Debugger.nDisasmLines; - if (!show || show > active) { - show = active; + } + show = INT_MAX; + if (use_paging == PAGING_ENABLED) { + show = DebugUI_GetPageLines(ConfigureParams.Debugger.nDisasmLines, 0); + if (!show) { + show = INT_MAX; } } fputs("# disassembly with profile data: % (, , )\n", out); + shown = 2; /* first and last printf */ - nextpc = 0; - for (shown = 0; shown < show && addr < end; addr++) { + addrs = nextpc = 0; + for (; shown < show && addrs < active && addr < end; addr++) { if (!data[addr].count) { continue; } if (addr != nextpc && nextpc) { fputs("[...]\n", out); + shown++; } - symbol = Symbols_GetByDspAddress(addr); + symbol = Symbols_GetByDspAddress(addr, SYMTYPE_TEXT); if (symbol) { fprintf(out, "%s:\n", symbol); + shown++; } nextpc = DSP_DisasmAddress(out, addr, addr); + addrs++; shown++; } - printf("Disassembled %d (of active %d) DSP addresses.\n", shown, active); + if (addr < end) { + printf("Disassembled %d (of active %d) DSP addresses.\n", addrs, active); + } else { + printf("Disassembled last %d (of active %d) DSP addresses, wrapping...\n", addrs, active); + nextpc = 0; + } return nextpc; } @@ -265,7 +282,7 @@ void Profile_DspShowCounts(int show, boo return; } - symbols = Symbols_DspCount(); + symbols = Symbols_DspCodeCount(); if (!symbols) { fprintf(stderr, "ERROR: no DSP symbols loaded!\n"); return; @@ -276,7 +293,7 @@ void Profile_DspShowCounts(int show, boo for (end = sort_arr + active; sort_arr < end; sort_arr++) { addr = *sort_arr; - name = Symbols_GetByDspAddress(addr); + name = Symbols_GetByDspAddress(addr, SYMTYPE_TEXT); if (!name) { continue; } @@ -298,7 +315,7 @@ void Profile_DspShowCounts(int show, boo static const char * addr2name(Uint32 addr, Uint64 *total) { *total = dsp_profile.data[addr].count; - return Symbols_GetByDspAddress(addr); + return Symbols_GetByDspAddress(addr, SYMTYPE_TEXT); } /** @@ -323,7 +340,7 @@ void Profile_DspSave(FILE *out) * p:0202 0aa980 000200 (07 cyc) jclr #0,x:$ffe9,p:$0200 0.00% (6, 42) */ fputs("Field regexp:\t^p:([0-9a-f]+) .*% \\((.*)\\)$\n", out); - Profile_DspShowAddresses(0, DSP_PROFILE_ARR_SIZE, out); + Profile_DspShowAddresses(0, DSP_PROFILE_ARR_SIZE, out, PAGING_DISABLED); Profile_DspShowCallers(out); } @@ -360,7 +377,7 @@ bool Profile_DspStart(void) printf("Allocated DSP profile buffer (%d KB).\n", (int)sizeof(*dsp_profile.data)*DSP_PROFILE_ARR_SIZE/1024); - Profile_AllocCallinfo(&(dsp_callinfo), Symbols_DspCount(), "DSP"); + Profile_AllocCallinfo(&(dsp_callinfo), Symbols_DspCodeCount(), "DSP"); item = dsp_profile.data; for (i = 0; i < DSP_PROFILE_ARR_SIZE; i++, item++) { @@ -368,6 +385,11 @@ bool Profile_DspStart(void) } dsp_profile.prev_pc = DSP_GetPC(); + dsp_profile.loop_start = 0xFFFF; + dsp_profile.loop_end = 0xFFFF; + dsp_profile.loop_count = 0; + Profile_LoopReset(); + dsp_profile.disasm_addr = 0; dsp_profile.processed = false; dsp_profile.enabled = true; @@ -505,7 +527,7 @@ static void collect_calls(Uint16 pc, cou } /* address is one which we're tracking? */ - idx = Symbols_GetDspAddressIndex(pc); + idx = Symbols_GetDspCodeIndex(pc); if (unlikely(idx >= 0)) { flag = dsp_opcode_type(prev_pc, pc); @@ -526,6 +548,19 @@ static void collect_calls(Uint16 pc, cou } /** + * log last loop info, if there's suitable data for one + */ +static void log_last_loop(void) +{ + unsigned len = dsp_profile.loop_end - dsp_profile.loop_start; + if (dsp_profile.loop_count > 1 && (len < profile_loop.dsp_limit || !profile_loop.dsp_limit)) { + fprintf(profile_loop.fp, "DSP %d 0x%04x %d %d\n", nVBLs, + dsp_profile.loop_start, len, dsp_profile.loop_count); + fflush(profile_loop.fp); + } +} + +/** * Update DSP cycle and count statistics for PC address. * * This is called after instruction is executed and PC points @@ -539,6 +574,25 @@ void Profile_DspUpdate(void) prev_pc = dsp_profile.prev_pc; dsp_profile.prev_pc = pc = DSP_GetPC(); + + if (unlikely(profile_loop.fp)) { + if (pc < prev_pc) { + if (pc == dsp_profile.loop_start && prev_pc == dsp_profile.loop_end) { + dsp_profile.loop_count++; + } else { + dsp_profile.loop_start = pc; + dsp_profile.loop_end = prev_pc; + dsp_profile.loop_count = 1; + } + } else { + if (pc > dsp_profile.loop_end) { + log_last_loop(); + dsp_profile.loop_end = 0xFFFF; + dsp_profile.loop_count = 0; + } + } + } + prev = dsp_profile.data + prev_pc; if (likely(prev->count < MAX_DSP_PROFILE_VALUE)) { @@ -594,7 +648,7 @@ static void update_area_item(profile_are area->counters.count += count; area->counters.cycles += cycles; - area->counters.misses += diff; + area->counters.cycles_diffs += diff; if (addr < area->lowest) { area->lowest = addr; @@ -619,6 +673,11 @@ void Profile_DspStop(void) return; } + log_last_loop(); + if (profile_loop.fp) { + fflush(profile_loop.fp); + } + Profile_FinalizeCalls(&(dsp_callinfo), &(dsp_profile.ram.counters), Symbols_GetByDspAddress); /* find lowest and highest addresses executed */ @@ -671,7 +730,7 @@ void Profile_DspGetPointers(bool **enabl /** * Get callinfo & symbol search pointers for stack walking. */ -void Profile_DspGetCallinfo(callinfo_t **callinfo, const char* (**get_symbol)(Uint32)) +void Profile_DspGetCallinfo(callinfo_t **callinfo, const char* (**get_symbol)(Uint32, symtype_t)) { *callinfo = &(dsp_callinfo); *get_symbol = Symbols_GetByDspAddress;