158579Sralph /*
2*62017Sbostic * Copyright (c) 1992, 1993
3*62017Sbostic * The Regents of the University of California. All rights reserved.
458579Sralph *
558579Sralph * This software was developed by the Computer Systems Engineering group
658579Sralph * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
758579Sralph * contributed to Berkeley. Modified by Ralph Campbell for mips.
858579Sralph *
958579Sralph * %sccs.include.redist.c%
1058579Sralph *
1158579Sralph * From: sparc.c 5.1 (Berkeley) 7/7/92
1258579Sralph */
1358579Sralph
1458579Sralph #ifndef lint
15*62017Sbostic static char sccsid[] = "@(#)mips.c 8.1 (Berkeley) 06/06/93";
1658579Sralph #endif /* not lint */
1758579Sralph
1858579Sralph #include "gprof.h"
1958579Sralph
2058579Sralph /*
2158579Sralph * a namelist entry to be the child of indirect calls
2258579Sralph */
2358579Sralph nltype indirectchild = {
2458579Sralph "(*)" , /* the name */
2558579Sralph (unsigned long) 0 , /* the pc entry point */
2658579Sralph (unsigned long) 0 , /* entry point aligned to histogram */
2758579Sralph (double) 0.0 , /* ticks in this routine */
2858579Sralph (double) 0.0 , /* cumulative ticks in children */
2958579Sralph (long) 0 , /* how many times called */
3058579Sralph (long) 0 , /* times called by live arcs */
3158579Sralph (long) 0 , /* how many calls to self */
3258579Sralph (double) 1.0 , /* propagation fraction */
3358579Sralph (double) 0.0 , /* self propagation time */
3458579Sralph (double) 0.0 , /* child propagation time */
3558579Sralph (short) 0 , /* print flag */
3658579Sralph (short) 0 , /* flags */
3758579Sralph (int) 0 , /* index in the graph list */
3858579Sralph (int) 0 , /* graph call chain top-sort order */
3958579Sralph (int) 0 , /* internal number of cycle on */
4058579Sralph (int) 0 , /* number of live parent arcs */
4158579Sralph (struct nl *) &indirectchild , /* pointer to head of cycle */
4258579Sralph (struct nl *) 0 , /* pointer to next member of cycle */
4358579Sralph (arctype *) 0 , /* list of caller arcs */
4458579Sralph (arctype *) 0 /* list of callee arcs */
4558579Sralph };
4658579Sralph
findcall(parentp,p_lowpc,p_highpc)4758579Sralph findcall(parentp, p_lowpc, p_highpc)
4858579Sralph nltype *parentp;
4958579Sralph unsigned long p_lowpc;
5058579Sralph unsigned long p_highpc;
5158579Sralph {
5258579Sralph register u_long pc;
5358579Sralph nltype *childp;
5458579Sralph unsigned long destpc;
5558579Sralph register long op;
5658579Sralph register int off;
5758579Sralph
5858579Sralph if (textspace == 0)
5958579Sralph return;
6058579Sralph if (p_lowpc < s_lowpc)
6158579Sralph p_lowpc = s_lowpc;
6258579Sralph if (p_highpc > s_highpc)
6358579Sralph p_highpc = s_highpc;
6458579Sralph
6558579Sralph for (pc = p_lowpc; pc < p_highpc; pc += 4) {
6658579Sralph off = pc - s_lowpc;
6758579Sralph op = *(u_long *)&textspace[off];
6858579Sralph if ((op & 0xfc000000) == 0x0c000000) {
6958579Sralph /*
7058579Sralph * a jal insn -- check that this
7158579Sralph * is the address of a function.
7258579Sralph */
7358579Sralph off = (op & 0x03ffffff) << 2;
7458579Sralph destpc = (pc & 0xf0000000) | off;
7558579Sralph if (destpc >= s_lowpc && destpc <= s_highpc) {
7658579Sralph childp = nllookup(destpc);
7758579Sralph if (childp != 0 && childp->value == destpc)
7858579Sralph addarc(parentp, childp, 0L);
7958579Sralph }
8058579Sralph } else if ((op & 0xfc00f83f) == 0x0000f809)
8158579Sralph /*
8258579Sralph * A jalr -- an indirect call.
8358579Sralph */
8458579Sralph addarc(parentp, &indirectchild, 0L);
8558579Sralph }
8658579Sralph }
87