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