154775Storek /*
2*62017Sbostic * Copyright (c) 1992, 1993
3*62017Sbostic * The Regents of the University of California. All rights reserved.
454775Storek *
554775Storek * This software was developed by the Computer Systems Engineering group
654775Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
754775Storek * contributed to Berkeley.
854775Storek *
954775Storek * %sccs.include.redist.c%
1054775Storek */
1154775Storek
1254775Storek #ifndef lint
13*62017Sbostic static char sccsid[] = "@(#)sparc.c 8.1 (Berkeley) 06/06/93";
1454775Storek #endif /* not lint */
1554775Storek
1654775Storek #include "gprof.h"
1754775Storek
1854775Storek /*
1954775Storek * a namelist entry to be the child of indirect calls
2054775Storek */
2154775Storek nltype indirectchild = {
2254775Storek "(*)" , /* the name */
2354775Storek (unsigned long) 0 , /* the pc entry point */
2454775Storek (unsigned long) 0 , /* entry point aligned to histogram */
2554775Storek (double) 0.0 , /* ticks in this routine */
2654775Storek (double) 0.0 , /* cumulative ticks in children */
2754775Storek (long) 0 , /* how many times called */
2854775Storek (long) 0 , /* times called by live arcs */
2954775Storek (long) 0 , /* how many calls to self */
3054775Storek (double) 1.0 , /* propagation fraction */
3154775Storek (double) 0.0 , /* self propagation time */
3254775Storek (double) 0.0 , /* child propagation time */
3354775Storek (short) 0 , /* print flag */
3454775Storek (short) 0 , /* flags */
3554775Storek (int) 0 , /* index in the graph list */
3654775Storek (int) 0 , /* graph call chain top-sort order */
3754775Storek (int) 0 , /* internal number of cycle on */
3854775Storek (int) 0 , /* number of live parent arcs */
3954775Storek (struct nl *) &indirectchild , /* pointer to head of cycle */
4054775Storek (struct nl *) 0 , /* pointer to next member of cycle */
4154775Storek (arctype *) 0 , /* list of caller arcs */
4254775Storek (arctype *) 0 /* list of callee arcs */
4354775Storek };
4454775Storek
findcall(parentp,p_lowpc,p_highpc)4554775Storek findcall(parentp, p_lowpc, p_highpc)
4654775Storek nltype *parentp;
4754775Storek unsigned long p_lowpc;
4854775Storek unsigned long p_highpc;
4954775Storek {
5054775Storek register u_long pc;
5154775Storek nltype *childp;
5254775Storek unsigned long destpc;
5354775Storek register long op;
5454775Storek register int off;
5554775Storek
5654775Storek if (textspace == 0)
5754775Storek return;
5854775Storek if (p_lowpc < s_lowpc)
5954775Storek p_lowpc = s_lowpc;
6054775Storek if (p_highpc > s_highpc)
6154775Storek p_highpc = s_highpc;
6254775Storek
6354775Storek for (pc = p_lowpc; pc < p_highpc; pc += 4) {
6454775Storek off = pc - s_lowpc;
6554775Storek op = *(u_long *)&textspace[off];
6654775Storek if ((op & 0xc0000000) == 0x40000000) {
6754775Storek /*
6854775Storek * a pc relative call insn -- check that this
6954775Storek * is the address of a function.
7054775Storek */
7154775Storek off = (op & 0x3fffffff) << 2;
7254775Storek destpc = pc + off;
7354775Storek if (destpc >= s_lowpc && destpc <= s_highpc) {
7454775Storek childp = nllookup(destpc);
7554775Storek if (childp != 0 && childp->value == destpc)
7654775Storek addarc(parentp, childp, 0L);
7754775Storek }
7854775Storek } else if ((op & 0xfff80000) == 0x9fc00000)
7954775Storek /*
8054775Storek * A jmpl with rd = 15 (%o7) -- an indirect call.
8154775Storek */
8254775Storek addarc(parentp, &indirectchild, 0L);
8354775Storek }
8454775Storek }
85