xref: /csrg-svn/usr.bin/gprof/mips.c (revision 58579)
1*58579Sralph /*
2*58579Sralph  * Copyright (c) 1992 Regents of the University of California.
3*58579Sralph  * All rights reserved.
4*58579Sralph  *
5*58579Sralph  * This software was developed by the Computer Systems Engineering group
6*58579Sralph  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7*58579Sralph  * contributed to Berkeley. Modified by Ralph Campbell for mips.
8*58579Sralph  *
9*58579Sralph  * %sccs.include.redist.c%
10*58579Sralph  *
11*58579Sralph  * From: sparc.c 5.1 (Berkeley) 7/7/92
12*58579Sralph  */
13*58579Sralph 
14*58579Sralph #ifndef lint
15*58579Sralph static char sccsid[] = "@(#)mips.c	5.1 (Berkeley) 03/08/93";
16*58579Sralph #endif /* not lint */
17*58579Sralph 
18*58579Sralph #include	"gprof.h"
19*58579Sralph 
20*58579Sralph     /*
21*58579Sralph      *	a namelist entry to be the child of indirect calls
22*58579Sralph      */
23*58579Sralph nltype	indirectchild = {
24*58579Sralph 	"(*)" ,				/* the name */
25*58579Sralph 	(unsigned long) 0 ,		/* the pc entry point */
26*58579Sralph 	(unsigned long) 0 ,		/* entry point aligned to histogram */
27*58579Sralph 	(double) 0.0 ,			/* ticks in this routine */
28*58579Sralph 	(double) 0.0 ,			/* cumulative ticks in children */
29*58579Sralph 	(long) 0 ,			/* how many times called */
30*58579Sralph 	(long) 0 ,			/* times called by live arcs */
31*58579Sralph 	(long) 0 ,			/* how many calls to self */
32*58579Sralph 	(double) 1.0 ,			/* propagation fraction */
33*58579Sralph 	(double) 0.0 ,			/* self propagation time */
34*58579Sralph 	(double) 0.0 ,			/* child propagation time */
35*58579Sralph 	(short) 0 ,			/* print flag */
36*58579Sralph 	(short) 0 ,			/* flags */
37*58579Sralph 	(int) 0 ,			/* index in the graph list */
38*58579Sralph 	(int) 0 , 			/* graph call chain top-sort order */
39*58579Sralph 	(int) 0 ,			/* internal number of cycle on */
40*58579Sralph 	(int) 0 ,			/* number of live parent arcs */
41*58579Sralph 	(struct nl *) &indirectchild ,	/* pointer to head of cycle */
42*58579Sralph 	(struct nl *) 0 ,		/* pointer to next member of cycle */
43*58579Sralph 	(arctype *) 0 ,			/* list of caller arcs */
44*58579Sralph 	(arctype *) 0 			/* list of callee arcs */
45*58579Sralph };
46*58579Sralph 
47*58579Sralph findcall(parentp, p_lowpc, p_highpc)
48*58579Sralph 	nltype		*parentp;
49*58579Sralph 	unsigned long	p_lowpc;
50*58579Sralph 	unsigned long	p_highpc;
51*58579Sralph {
52*58579Sralph 	register u_long pc;
53*58579Sralph 	nltype *childp;
54*58579Sralph 	unsigned long destpc;
55*58579Sralph 	register long op;
56*58579Sralph 	register int off;
57*58579Sralph 
58*58579Sralph 	if (textspace == 0)
59*58579Sralph 		return;
60*58579Sralph 	if (p_lowpc < s_lowpc)
61*58579Sralph 		p_lowpc = s_lowpc;
62*58579Sralph 	if (p_highpc > s_highpc)
63*58579Sralph 		p_highpc = s_highpc;
64*58579Sralph 
65*58579Sralph 	for (pc = p_lowpc; pc < p_highpc; pc += 4) {
66*58579Sralph 		off = pc - s_lowpc;
67*58579Sralph 		op = *(u_long *)&textspace[off];
68*58579Sralph 		if ((op & 0xfc000000) == 0x0c000000) {
69*58579Sralph 			/*
70*58579Sralph 			 * a jal insn -- check that this
71*58579Sralph 			 * is the address of a function.
72*58579Sralph 			 */
73*58579Sralph 			off = (op & 0x03ffffff) << 2;
74*58579Sralph 			destpc = (pc & 0xf0000000) | off;
75*58579Sralph 			if (destpc >= s_lowpc && destpc <= s_highpc) {
76*58579Sralph 				childp = nllookup(destpc);
77*58579Sralph 				if (childp != 0 && childp->value == destpc)
78*58579Sralph 					addarc(parentp, childp, 0L);
79*58579Sralph 			}
80*58579Sralph 		} else if ((op & 0xfc00f83f) == 0x0000f809)
81*58579Sralph 			/*
82*58579Sralph 			 * A jalr -- an indirect call.
83*58579Sralph 			 */
84*58579Sralph 			addarc(parentp, &indirectchild, 0L);
85*58579Sralph 	}
86*58579Sralph }
87