17d9195a7SDavid du Colombier #include <u.h>
27d9195a7SDavid du Colombier #include <libc.h>
37d9195a7SDavid du Colombier #include <bio.h>
47d9195a7SDavid du Colombier #include <mach.h>
57d9195a7SDavid du Colombier #define Extern extern
67d9195a7SDavid du Colombier #include "power.h"
77d9195a7SDavid du Colombier
87d9195a7SDavid du Colombier #define prof profqi
97d9195a7SDavid du Colombier #define Percent(num, max) (int)(((vlong)(num)*100)/(max))
107d9195a7SDavid du Colombier
117d9195a7SDavid du Colombier Inset *tables[] = { &ops0, &ops19, &ops31, &ops59, &ops63a, &ops63b, 0 };
127d9195a7SDavid du Colombier
137d9195a7SDavid du Colombier void
isum(void)147d9195a7SDavid du Colombier isum(void)
157d9195a7SDavid du Colombier {
167d9195a7SDavid du Colombier Inst *i;
177d9195a7SDavid du Colombier int pct, j, k;
187d9195a7SDavid du Colombier int total, loads, stores, arith, branch;
197d9195a7SDavid du Colombier int taken, powerreg, syscall, realarith, control;
207d9195a7SDavid du Colombier
217d9195a7SDavid du Colombier total = 0;
227d9195a7SDavid du Colombier loads = 0;
237d9195a7SDavid du Colombier stores = 0;
247d9195a7SDavid du Colombier arith = 0;
257d9195a7SDavid du Colombier branch = 0;
267d9195a7SDavid du Colombier taken = 0;
277d9195a7SDavid du Colombier powerreg = 0;
287d9195a7SDavid du Colombier syscall = 0;
297d9195a7SDavid du Colombier realarith = 0;
307d9195a7SDavid du Colombier control = 0;
317d9195a7SDavid du Colombier
327d9195a7SDavid du Colombier /* Compute the total so we can have percentages */
337d9195a7SDavid du Colombier for(j = 0; tables[j]; j++)
347d9195a7SDavid du Colombier for(k = tables[j]->nel; --k >= 0;) {
357d9195a7SDavid du Colombier i = &tables[j]->tab[k];
367d9195a7SDavid du Colombier if(i->name && i->func)
377d9195a7SDavid du Colombier total += i->count;
387d9195a7SDavid du Colombier }
397d9195a7SDavid du Colombier
407d9195a7SDavid du Colombier Bprint(bioout, "\nInstruction summary.\n\n");
417d9195a7SDavid du Colombier
427d9195a7SDavid du Colombier for(j = 0; tables[j]; j++) {
437d9195a7SDavid du Colombier for(k =tables[j]->nel; --k>=0; ) {
447d9195a7SDavid du Colombier i = &tables[j]->tab[k];
457d9195a7SDavid du Colombier if(i->name && i->func) {
467d9195a7SDavid du Colombier if(i->count == 0)
477d9195a7SDavid du Colombier continue;
487d9195a7SDavid du Colombier pct = Percent(i->count, total);
497d9195a7SDavid du Colombier if(pct != 0)
507d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% %s\n",
517d9195a7SDavid du Colombier i->count, Percent(i->count, total), i->name);
527d9195a7SDavid du Colombier else
537d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %s\n",
547d9195a7SDavid du Colombier i->count, i->name);
557d9195a7SDavid du Colombier
567d9195a7SDavid du Colombier switch(i->type) {
577d9195a7SDavid du Colombier default:
587d9195a7SDavid du Colombier fatal(0, "isum bad stype %d\n", i->type);
597d9195a7SDavid du Colombier case Iload:
607d9195a7SDavid du Colombier loads += i->count;
617d9195a7SDavid du Colombier break;
627d9195a7SDavid du Colombier case Istore:
637d9195a7SDavid du Colombier stores += i->count;
647d9195a7SDavid du Colombier break;
657d9195a7SDavid du Colombier case Ilog:
667d9195a7SDavid du Colombier case Iarith:
677d9195a7SDavid du Colombier arith += i->count;
687d9195a7SDavid du Colombier break;
697d9195a7SDavid du Colombier case Ibranch:
707d9195a7SDavid du Colombier branch += i->count;
717d9195a7SDavid du Colombier taken += i->taken;
727d9195a7SDavid du Colombier break;
737d9195a7SDavid du Colombier case Ireg:
747d9195a7SDavid du Colombier powerreg += i->count;
757d9195a7SDavid du Colombier break;
767d9195a7SDavid du Colombier case Isyscall:
777d9195a7SDavid du Colombier syscall += i->count;
787d9195a7SDavid du Colombier break;
797d9195a7SDavid du Colombier case Ifloat:
807d9195a7SDavid du Colombier realarith += i->count;
817d9195a7SDavid du Colombier break;
827d9195a7SDavid du Colombier case Inop:
837d9195a7SDavid du Colombier arith += i->count;
847d9195a7SDavid du Colombier i->count -= nopcount;
857d9195a7SDavid du Colombier break;
867d9195a7SDavid du Colombier case Icontrol:
877d9195a7SDavid du Colombier control += i->count;
887d9195a7SDavid du Colombier break;
897d9195a7SDavid du Colombier }
907d9195a7SDavid du Colombier }
917d9195a7SDavid du Colombier }
927d9195a7SDavid du Colombier }
937d9195a7SDavid du Colombier
947d9195a7SDavid du Colombier Bprint(bioout, "\n%-8ud Memory cycles\n", loads+stores+total);
957d9195a7SDavid du Colombier
96*6891d857SDavid du Colombier if(total == 0)
97*6891d857SDavid du Colombier return;
98*6891d857SDavid du Colombier
997d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
1007d9195a7SDavid du Colombier total, Percent(total, loads+stores+total));
1017d9195a7SDavid du Colombier
1027d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
1037d9195a7SDavid du Colombier loads+stores, Percent(loads+stores, loads+stores+total));
1047d9195a7SDavid du Colombier
1057d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));
1067d9195a7SDavid du Colombier
1077d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));
1087d9195a7SDavid du Colombier
1097d9195a7SDavid du Colombier Bprint(bioout, " %-8ud Store stall\n", stores*2);
1107d9195a7SDavid du Colombier
1117d9195a7SDavid du Colombier Bprint(bioout, " %-8lud Load stall\n", loadlock);
1127d9195a7SDavid du Colombier
1137d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));
1147d9195a7SDavid du Colombier
1157d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Floating point\n",
1167d9195a7SDavid du Colombier realarith, Percent(realarith, total));
1177d9195a7SDavid du Colombier
1187d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% PowerPC special register load/stores\n",
1197d9195a7SDavid du Colombier powerreg, Percent(powerreg, total));
1207d9195a7SDavid du Colombier
1217d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% PowerPC control instructions\n",
1227d9195a7SDavid du Colombier control, Percent(control, total));
1237d9195a7SDavid du Colombier
1247d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));
1257d9195a7SDavid du Colombier
1267d9195a7SDavid du Colombier Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));
1277d9195a7SDavid du Colombier
1287d9195a7SDavid du Colombier Bprint(bioout, " %-8ud %3d%% Branches taken\n",
1297d9195a7SDavid du Colombier taken, Percent(taken, branch));
1307d9195a7SDavid du Colombier }
1317d9195a7SDavid du Colombier
1327d9195a7SDavid du Colombier char *stype[] = { "Stack", "Text", "Data", "Bss" };
1337d9195a7SDavid du Colombier
1347d9195a7SDavid du Colombier void
segsum(void)1357d9195a7SDavid du Colombier segsum(void)
1367d9195a7SDavid du Colombier {
1377d9195a7SDavid du Colombier Segment *s;
1387d9195a7SDavid du Colombier int i;
1397d9195a7SDavid du Colombier
1407d9195a7SDavid du Colombier Bprint(bioout, "\n\nMemory Summary\n\n");
1417d9195a7SDavid du Colombier Bprint(bioout, " Base End Resident References\n");
1427d9195a7SDavid du Colombier for(i = 0; i < Nseg; i++) {
1437d9195a7SDavid du Colombier s = &memory.seg[i];
1447d9195a7SDavid du Colombier Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
1457d9195a7SDavid du Colombier stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
1467d9195a7SDavid du Colombier }
1477d9195a7SDavid du Colombier }
1487d9195a7SDavid du Colombier
1497d9195a7SDavid du Colombier typedef struct Prof Prof;
1507d9195a7SDavid du Colombier struct Prof
1517d9195a7SDavid du Colombier {
1527d9195a7SDavid du Colombier Symbol s;
1537d9195a7SDavid du Colombier long count;
1547d9195a7SDavid du Colombier };
1557d9195a7SDavid du Colombier Prof prof[5000];
1567d9195a7SDavid du Colombier
1577d9195a7SDavid du Colombier int
profcmp(void * a,void * b)1587d9195a7SDavid du Colombier profcmp(void *a, void *b)
1597d9195a7SDavid du Colombier {
1607d9195a7SDavid du Colombier return ((Prof*)b)->count - ((Prof*)a)->count;
1617d9195a7SDavid du Colombier }
1627d9195a7SDavid du Colombier
1637d9195a7SDavid du Colombier void
iprofile(void)1647d9195a7SDavid du Colombier iprofile(void)
1657d9195a7SDavid du Colombier {
1667d9195a7SDavid du Colombier Prof *p, *n;
1677d9195a7SDavid du Colombier int i, b, e;
1687d9195a7SDavid du Colombier ulong total;
1697d9195a7SDavid du Colombier extern ulong textbase;
1707d9195a7SDavid du Colombier
1717d9195a7SDavid du Colombier i = 0;
1727d9195a7SDavid du Colombier p = prof;
1737d9195a7SDavid du Colombier if(textsym(&p->s, i) == 0)
1747d9195a7SDavid du Colombier return;
1757d9195a7SDavid du Colombier i++;
1767d9195a7SDavid du Colombier for(;;) {
1777d9195a7SDavid du Colombier n = p+1;
1787d9195a7SDavid du Colombier if(textsym(&n->s, i) == 0)
1797d9195a7SDavid du Colombier break;
1807d9195a7SDavid du Colombier b = (p->s.value-textbase)/PROFGRAN;
1817d9195a7SDavid du Colombier e = (n->s.value-textbase)/PROFGRAN;
1827d9195a7SDavid du Colombier while(b < e)
1837d9195a7SDavid du Colombier p->count += iprof[b++];
1847d9195a7SDavid du Colombier i++;
1857d9195a7SDavid du Colombier p = n;
1867d9195a7SDavid du Colombier }
1877d9195a7SDavid du Colombier
1887d9195a7SDavid du Colombier qsort(prof, i, sizeof(Prof), profcmp);
1897d9195a7SDavid du Colombier
1907d9195a7SDavid du Colombier total = 0;
1917d9195a7SDavid du Colombier for(b = 0; b < i; b++)
1927d9195a7SDavid du Colombier total += prof[b].count;
1937d9195a7SDavid du Colombier
1947d9195a7SDavid du Colombier Bprint(bioout, " cycles %% symbol file\n");
1957d9195a7SDavid du Colombier for(b = 0; b < i; b++) {
1967d9195a7SDavid du Colombier if(prof[b].count == 0)
1977d9195a7SDavid du Colombier continue;
1987d9195a7SDavid du Colombier
1997d9195a7SDavid du Colombier Bprint(bioout, "%8ld %3ld.%ld %-15s ",
2007d9195a7SDavid du Colombier prof[b].count,
2017d9195a7SDavid du Colombier 100*prof[b].count/total,
2027d9195a7SDavid du Colombier (1000*prof[b].count/total)%10,
2037d9195a7SDavid du Colombier prof[b].s.name);
2047d9195a7SDavid du Colombier
2057d9195a7SDavid du Colombier printsource(prof[b].s.value);
2067d9195a7SDavid du Colombier Bputc(bioout, '\n');
2077d9195a7SDavid du Colombier }
2087d9195a7SDavid du Colombier memset(prof, 0, sizeof(Prof)*i);
2097d9195a7SDavid du Colombier }
210