Commit | Line | Data |
---|---|---|
d158005d CT |
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. | |
8 | * | |
9 | * %sccs.include.redist.c% | |
10 | */ | |
11 | ||
12 | #ifndef lint | |
13 | static char sccsid[] = "@(#)sparc.c 5.1 (Berkeley) %G%"; | |
14 | #endif /* not lint */ | |
15 | ||
16 | #include "gprof.h" | |
17 | ||
18 | /* | |
19 | * a namelist entry to be the child of indirect calls | |
20 | */ | |
21 | nltype indirectchild = { | |
22 | "(*)" , /* the name */ | |
23 | (unsigned long) 0 , /* the pc entry point */ | |
24 | (unsigned long) 0 , /* entry point aligned to histogram */ | |
25 | (double) 0.0 , /* ticks in this routine */ | |
26 | (double) 0.0 , /* cumulative ticks in children */ | |
27 | (long) 0 , /* how many times called */ | |
28 | (long) 0 , /* times called by live arcs */ | |
29 | (long) 0 , /* how many calls to self */ | |
30 | (double) 1.0 , /* propagation fraction */ | |
31 | (double) 0.0 , /* self propagation time */ | |
32 | (double) 0.0 , /* child propagation time */ | |
33 | (short) 0 , /* print flag */ | |
34 | (short) 0 , /* flags */ | |
35 | (int) 0 , /* index in the graph list */ | |
36 | (int) 0 , /* graph call chain top-sort order */ | |
37 | (int) 0 , /* internal number of cycle on */ | |
38 | (int) 0 , /* number of live parent arcs */ | |
39 | (struct nl *) &indirectchild , /* pointer to head of cycle */ | |
40 | (struct nl *) 0 , /* pointer to next member of cycle */ | |
41 | (arctype *) 0 , /* list of caller arcs */ | |
42 | (arctype *) 0 /* list of callee arcs */ | |
43 | }; | |
44 | ||
45 | findcall(parentp, p_lowpc, p_highpc) | |
46 | nltype *parentp; | |
47 | unsigned long p_lowpc; | |
48 | unsigned long p_highpc; | |
49 | { | |
50 | register u_long pc; | |
51 | nltype *childp; | |
52 | unsigned long destpc; | |
53 | register long op; | |
54 | register int off; | |
55 | ||
56 | if (textspace == 0) | |
57 | return; | |
58 | if (p_lowpc < s_lowpc) | |
59 | p_lowpc = s_lowpc; | |
60 | if (p_highpc > s_highpc) | |
61 | p_highpc = s_highpc; | |
62 | ||
63 | for (pc = p_lowpc; pc < p_highpc; pc += 4) { | |
64 | off = pc - s_lowpc; | |
65 | op = *(u_long *)&textspace[off]; | |
66 | if ((op & 0xc0000000) == 0x40000000) { | |
67 | /* | |
68 | * a pc relative call insn -- check that this | |
69 | * is the address of a function. | |
70 | */ | |
71 | off = (op & 0x3fffffff) << 2; | |
72 | destpc = pc + off; | |
73 | if (destpc >= s_lowpc && destpc <= s_highpc) { | |
74 | childp = nllookup(destpc); | |
75 | if (childp != 0 && childp->value == destpc) | |
76 | addarc(parentp, childp, 0L); | |
77 | } | |
78 | } else if ((op & 0xfff80000) == 0x9fc00000) | |
79 | /* | |
80 | * A jmpl with rd = 15 (%o7) -- an indirect call. | |
81 | */ | |
82 | addarc(parentp, &indirectchild, 0L); | |
83 | } | |
84 | } |