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