/** * Check whether given address matches any CPU symbol and whether * there's profiling information available for it. If yes, show it. */ static void DebugCpu_ShowAddressInfo(Uint32 addr) { Uint32 count, cycles; const char *symbol; bool shown = false; symbol = Symbols_GetByCpuAddress(addr); if (symbol) { fprintf(debugOutput, "%s", symbol); shown = true; } if (Profile_CpuAddressData(addr, &count, &cycles)) { fprintf(debugOutput, "%s%d/%d times/cycles", (shown ? ", " : ""), count, cycles); shown = true; } if (shown) fprintf(debugOutput, ":\n"); }
static const char * addr2name(Uint32 addr, Uint64 *total) { Uint32 idx = address2index(addr); *total = cpu_profile.data[idx].count; return Symbols_GetByCpuAddress(addr); }
/** * Sort CPU profile data addresses by call counts and show the results. * If symbols are requested and symbols are loaded, show (only) addresses * matching a symbol. */ void Profile_CpuShowCounts(int show, bool only_symbols) { cpu_profile_item_t *data = cpu_profile.data; int symbols, matched, active; int oldcols[DISASM_COLUMNS]; Uint32 *sort_arr, *end, addr, nextpc; const char *name; float percentage; Uint32 count; if (!data) { fprintf(stderr, "ERROR: no CPU profiling data available!\n"); return; } active = cpu_profile.active; show = (show < active ? show : active); sort_arr = cpu_profile.sort_arr; qsort(sort_arr, active, sizeof(*sort_arr), cmp_cpu_count); if (!only_symbols) { leave_instruction_column(oldcols); printf("addr:\t\tcount:\n"); for (end = sort_arr + show; sort_arr < end; sort_arr++) { addr = index2address(*sort_arr); count = data[*sort_arr].count; percentage = 100.0*count/cpu_profile.all.count; printf("0x%06x\t%5.2f%%\t%d%s\t", addr, percentage, count, count == MAX_CPU_PROFILE_VALUE ? " (OVERFLOW)" : ""); Disasm(stdout, addr, &nextpc, 1); } printf("%d CPU addresses listed.\n", show); Disasm_SetColumns(oldcols); return; } symbols = Symbols_CpuCount(); if (!symbols) { fprintf(stderr, "ERROR: no CPU symbols loaded!\n"); return; } matched = 0; leave_instruction_column(oldcols); printf("addr:\t\tcount:\t\tsymbol:\n"); for (end = sort_arr + active; sort_arr < end; sort_arr++) { addr = index2address(*sort_arr); name = Symbols_GetByCpuAddress(addr); if (!name) { continue; } count = data[*sort_arr].count; percentage = 100.0*count/cpu_profile.all.count; printf("0x%06x\t%5.2f%%\t%d\t%s%s\t", addr, percentage, count, name, count == MAX_CPU_PROFILE_VALUE ? " (OVERFLOW)" : ""); Disasm(stdout, addr, &nextpc, 1); matched++; if (matched >= show || matched >= symbols) { break; } } printf("%d CPU symbols listed.\n", matched); Disasm_SetColumns(oldcols); }
/** * Show CPU instructions which execution was profiled, in the address order, * starting from the given address. Return next disassembly address. */ Uint32 Profile_CpuShowAddresses(Uint32 lower, Uint32 upper, FILE *out) { int oldcols[DISASM_COLUMNS], newcols[DISASM_COLUMNS]; int show, shown, active; const char *symbol; cpu_profile_item_t *data; Uint32 idx, end, size; uaecptr nextpc, addr; data = cpu_profile.data; if (!data) { fprintf(stderr, "ERROR: no CPU profiling data available!\n"); return 0; } size = cpu_profile.size; active = cpu_profile.active; if (upper) { end = address2index(upper); show = active; if (end > size) { end = size; } } else { end = size; show = ConfigureParams.Debugger.nDisasmLines; if (!show || show > active) { show = active; } } /* get/change columns */ Disasm_GetColumns(oldcols); Disasm_DisableColumn(DISASM_COLUMN_HEXDUMP, oldcols, newcols); Disasm_SetColumns(newcols); fputs("# disassembly with profile data: <instructions percentage>% (<sum of instructions>, <sum of cycles>, <sum of i-cache misses>)\n", out); nextpc = 0; idx = address2index(lower); for (shown = 0; shown < show && idx < end; idx++) { if (!data[idx].count) { continue; } addr = index2address(idx); if (addr != nextpc && nextpc) { fprintf(out, "[...]\n"); } symbol = Symbols_GetByCpuAddress(addr); if (symbol) { fprintf(out, "%s:\n", symbol); } /* NOTE: column setup works only with 68kDisass disasm engine! */ Disasm(out, addr, &nextpc, 1); shown++; } printf("Disassembled %d (of active %d) CPU addresses.\n", shown, active); /* restore disassembly columns */ Disasm_SetColumns(oldcols); return nextpc; }
/** * Check whether given address matches any CPU symbol and whether * there's profiling information available for it. If yes, show it. */ static void DebugCpu_ShowAddressInfo(Uint32 addr) { const char *symbol = Symbols_GetByCpuAddress(addr); if (symbol) fprintf(debugOutput, "%s:\n", symbol); }
/** * Check whether given address matches any CPU symbol and whether * there's profiling information available for it. If yes, show it. */ static void DebugCpu_ShowAddressInfo(Uint32 addr, FILE *fp) { const char *symbol = Symbols_GetByCpuAddress(addr); if (symbol) fprintf(fp, "%s:\n", symbol); }