17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <mach.h>
57dd7cddfSDavid du Colombier #include "arm.h"
67dd7cddfSDavid du Colombier
780ee5cbfSDavid du Colombier #define Percent(num, max) ((max)?((num)*100)/(max):0)
8*e288d156SDavid du Colombier #define prof prof5i
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier extern Inst itab[];
117dd7cddfSDavid du Colombier Inst *tables[] = { itab, 0 };
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier void
isum(void)147dd7cddfSDavid du Colombier isum(void)
157dd7cddfSDavid du Colombier {
167dd7cddfSDavid du Colombier Inst *i;
1780ee5cbfSDavid du Colombier int total, mems, arith, branch;
1880ee5cbfSDavid du Colombier int useddelay, taken, syscall;
197dd7cddfSDavid du Colombier int pct, j;
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier total = 0;
2280ee5cbfSDavid du Colombier mems = 0;
237dd7cddfSDavid du Colombier arith = 0;
247dd7cddfSDavid du Colombier branch = 0;
257dd7cddfSDavid du Colombier useddelay = 0;
267dd7cddfSDavid du Colombier taken = 0;
277dd7cddfSDavid du Colombier syscall = 0;
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier /* Compute the total so we can have percentages */
307dd7cddfSDavid du Colombier for(i = itab; i->func; i++)
317dd7cddfSDavid du Colombier if(i->name && i->count)
327dd7cddfSDavid du Colombier total += i->count;
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier Bprint(bioout, "\nInstruction summary.\n\n");
357dd7cddfSDavid du Colombier
367dd7cddfSDavid du Colombier for(j = 0; tables[j]; j++) {
377dd7cddfSDavid du Colombier for(i = tables[j]; i->func; i++) {
387dd7cddfSDavid du Colombier if(i->name) {
397dd7cddfSDavid du Colombier /* This is gross */
407dd7cddfSDavid du Colombier if(i->count == 0)
417dd7cddfSDavid du Colombier continue;
427dd7cddfSDavid du Colombier pct = Percent(i->count, total);
437dd7cddfSDavid du Colombier if(pct != 0)
447dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% %s\n",
457dd7cddfSDavid du Colombier i->count, Percent(i->count,
467dd7cddfSDavid du Colombier total), i->name);
477dd7cddfSDavid du Colombier else
487dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %s\n",
497dd7cddfSDavid du Colombier i->count, i->name);
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier
527dd7cddfSDavid du Colombier switch(i->type) {
537dd7cddfSDavid du Colombier default:
547dd7cddfSDavid du Colombier fatal(0, "isum bad stype %d\n", i->type);
5580ee5cbfSDavid du Colombier case Imem:
5680ee5cbfSDavid du Colombier mems += i->count;
577dd7cddfSDavid du Colombier break;
587dd7cddfSDavid du Colombier case Iarith:
597dd7cddfSDavid du Colombier arith += i->count;
607dd7cddfSDavid du Colombier break;
617dd7cddfSDavid du Colombier case Ibranch:
627dd7cddfSDavid du Colombier branch += i->count;
637dd7cddfSDavid du Colombier taken += i->taken;
647dd7cddfSDavid du Colombier useddelay += i->useddelay;
657dd7cddfSDavid du Colombier break;
667dd7cddfSDavid du Colombier case Isyscall:
677dd7cddfSDavid du Colombier syscall += i->count;
687dd7cddfSDavid du Colombier break;
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier }
727dd7cddfSDavid du Colombier }
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier
7580ee5cbfSDavid du Colombier Bprint(bioout, "\n%-8ud Memory cycles\n", mems+total);
767dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
7780ee5cbfSDavid du Colombier total, Percent(total, mems+total));
787dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
7980ee5cbfSDavid du Colombier mems, Percent(mems, mems+total));
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% Arithmetic\n",
827dd7cddfSDavid du Colombier arith, Percent(arith, total));
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% System calls\n",
857dd7cddfSDavid du Colombier syscall, Percent(syscall, total));
867dd7cddfSDavid du Colombier
877dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% Branches\n",
887dd7cddfSDavid du Colombier branch, Percent(branch, total));
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier Bprint(bioout, " %-8ud %3d%% Branches taken\n",
917dd7cddfSDavid du Colombier taken, Percent(taken, branch));
927dd7cddfSDavid du Colombier
937dd7cddfSDavid du Colombier Bprint(bioout, " %-8ud %3d%% Delay slots\n",
947dd7cddfSDavid du Colombier useddelay, Percent(useddelay, branch));
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier Bprint(bioout, " %-8ud %3d%% Unused delay slots\n",
977dd7cddfSDavid du Colombier branch-useddelay, Percent(branch-useddelay, branch));
987dd7cddfSDavid du Colombier
997dd7cddfSDavid du Colombier Bprint(bioout, "%-8ud %3d%% Program total delay slots\n",
1007dd7cddfSDavid du Colombier nopcount, Percent(nopcount, total));
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier void
tlbsum(void)1047dd7cddfSDavid du Colombier tlbsum(void)
1057dd7cddfSDavid du Colombier {
1067dd7cddfSDavid du Colombier if(tlb.on == 0)
1077dd7cddfSDavid du Colombier return;
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier Bprint(bioout, "\n\nTlb summary\n");
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier Bprint(bioout, "\n%-8d User entries\n", tlb.tlbsize);
1127dd7cddfSDavid du Colombier Bprint(bioout, "%-8d Accesses\n", tlb.hit+tlb.miss);
1137dd7cddfSDavid du Colombier Bprint(bioout, "%-8d Tlb hits\n", tlb.hit);
1147dd7cddfSDavid du Colombier Bprint(bioout, "%-8d Tlb misses\n", tlb.miss);
1157dd7cddfSDavid du Colombier Bprint(bioout, "%7d%% Hit rate\n", Percent(tlb.hit, tlb.hit+tlb.miss));
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier
1187dd7cddfSDavid du Colombier char *stype[] = { "Stack", "Text", "Data", "Bss" };
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier void
segsum(void)1217dd7cddfSDavid du Colombier segsum(void)
1227dd7cddfSDavid du Colombier {
1237dd7cddfSDavid du Colombier Segment *s;
1247dd7cddfSDavid du Colombier int i;
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier Bprint(bioout, "\n\nMemory Summary\n\n");
1277dd7cddfSDavid du Colombier Bprint(bioout, " Base End Resident References\n");
1287dd7cddfSDavid du Colombier for(i = 0; i < Nseg; i++) {
1297dd7cddfSDavid du Colombier s = &memory.seg[i];
1307dd7cddfSDavid du Colombier Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
1317dd7cddfSDavid du Colombier stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier typedef struct Prof Prof;
1367dd7cddfSDavid du Colombier struct Prof
1377dd7cddfSDavid du Colombier {
1387dd7cddfSDavid du Colombier Symbol s;
1397dd7cddfSDavid du Colombier long count;
1407dd7cddfSDavid du Colombier };
1417dd7cddfSDavid du Colombier Prof prof[5000];
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier int
profcmp(void * va,void * vb)1447dd7cddfSDavid du Colombier profcmp(void *va, void *vb)
1457dd7cddfSDavid du Colombier {
1467dd7cddfSDavid du Colombier Prof *a, *b;
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier a = va;
1497dd7cddfSDavid du Colombier b = vb;
1507dd7cddfSDavid du Colombier return b->count - a->count;
1517dd7cddfSDavid du Colombier }
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier void
iprofile(void)1547dd7cddfSDavid du Colombier iprofile(void)
1557dd7cddfSDavid du Colombier {
1567dd7cddfSDavid du Colombier Prof *p, *n;
1577dd7cddfSDavid du Colombier int i, b, e;
1587dd7cddfSDavid du Colombier ulong total;
1597dd7cddfSDavid du Colombier extern ulong textbase;
1607dd7cddfSDavid du Colombier
1617dd7cddfSDavid du Colombier i = 0;
1627dd7cddfSDavid du Colombier p = prof;
1637dd7cddfSDavid du Colombier if(textsym(&p->s, i) == 0)
1647dd7cddfSDavid du Colombier return;
1657dd7cddfSDavid du Colombier i++;
1667dd7cddfSDavid du Colombier for(;;) {
1677dd7cddfSDavid du Colombier n = p+1;
1687dd7cddfSDavid du Colombier if(textsym(&n->s, i) == 0)
1697dd7cddfSDavid du Colombier break;
1707dd7cddfSDavid du Colombier b = (p->s.value-textbase)/PROFGRAN;
1717dd7cddfSDavid du Colombier e = (n->s.value-textbase)/PROFGRAN;
1727dd7cddfSDavid du Colombier while(b < e)
1737dd7cddfSDavid du Colombier p->count += iprof[b++];
1747dd7cddfSDavid du Colombier i++;
1757dd7cddfSDavid du Colombier p = n;
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier qsort(prof, i, sizeof(Prof), profcmp);
1797dd7cddfSDavid du Colombier
1807dd7cddfSDavid du Colombier total = 0;
1817dd7cddfSDavid du Colombier for(b = 0; b < i; b++)
1827dd7cddfSDavid du Colombier total += prof[b].count;
1837dd7cddfSDavid du Colombier
1847dd7cddfSDavid du Colombier Bprint(bioout, " cycles %% symbol file\n");
1857dd7cddfSDavid du Colombier for(b = 0; b < i; b++) {
1867dd7cddfSDavid du Colombier if(prof[b].count == 0)
1877dd7cddfSDavid du Colombier continue;
1887dd7cddfSDavid du Colombier
1897dd7cddfSDavid du Colombier Bprint(bioout, "%8ld %3ld.%ld %-15s ",
1907dd7cddfSDavid du Colombier prof[b].count,
1917dd7cddfSDavid du Colombier 100*prof[b].count/total,
1927dd7cddfSDavid du Colombier (1000*prof[b].count/total)%10,
1937dd7cddfSDavid du Colombier prof[b].s.name);
1947dd7cddfSDavid du Colombier
1957dd7cddfSDavid du Colombier printsource(prof[b].s.value);
1967dd7cddfSDavid du Colombier Bputc(bioout, '\n');
1977dd7cddfSDavid du Colombier }
1987dd7cddfSDavid du Colombier memset(prof, 0, sizeof(Prof)*i);
1997dd7cddfSDavid du Colombier }
200