Initial revision
[external/binutils.git] / gprof / sparc.c
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that: (1) source distributions retain this entire copyright
7  * notice and comment, and (2) distributions including binaries display
8  * the following acknowledgement:  ``This product includes software
9  * developed by the University of California, Berkeley and its contributors''
10  * in the documentation or other materials provided with the distribution
11  * and in all advertising materials mentioning features or use of this
12  * software. Neither the name of the University nor the names of its
13  * contributors may be used to endorse or promote products derived
14  * from this software without specific prior written permission.
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  */
19
20 #ifndef lint
21 static char sccsid[] = "@(#)tahoe.c     1.5 (Berkeley) 6/1/90";
22 #endif /* not lint */
23
24 #include        "gprof.h"
25
26     /*
27      *  a namelist entry to be the child of indirect callf
28      */
29 nltype  indirectchild = {
30         "(*)" ,                         /* the name */
31         (unsigned long) 0 ,             /* the pc entry point */
32         (unsigned long) 0 ,             /* entry point aligned to histogram */
33         (double) 0.0 ,                  /* ticks in this routine */
34         (double) 0.0 ,                  /* cumulative ticks in children */
35         (long) 0 ,                      /* how many times called */
36         (long) 0 ,                      /* how many calls to self */
37         (double) 1.0 ,                  /* propagation fraction */
38         (double) 0.0 ,                  /* self propagation time */
39         (double) 0.0 ,                  /* child propagation time */
40         (bool) 0 ,                      /* print flag */
41         (int) 0 ,                       /* index in the graph list */
42         (int) 0 ,                       /* graph call chain top-sort order */
43         (int) 0 ,                       /* internal number of cycle on */
44         (struct nl *) &indirectchild ,  /* pointer to head of cycle */
45         (struct nl *) 0 ,               /* pointer to next member of cycle */
46         (arctype *) 0 ,                 /* list of caller arcs */
47         (arctype *) 0                   /* list of callee arcs */
48     };
49
50 findcall( parentp , p_lowpc , p_highpc )
51     nltype              *parentp;
52     unsigned long       p_lowpc;
53     unsigned long       p_highpc;
54 {
55     unsigned char       *instructp;
56     long                length;
57     nltype              *childp;
58     unsigned long       destpc;
59
60     if ( textspace == 0 ) {
61         return;
62     }
63     if ( p_lowpc < s_lowpc ) {
64         p_lowpc = s_lowpc;
65     }
66     if ( p_highpc > s_highpc ) {
67         p_highpc = s_highpc;
68     }
69 #   ifdef DEBUG
70         if ( debug & CALLDEBUG ) {
71             printf( "[findcall] %s: 0x%x to 0x%x\n" ,
72                     parentp -> name , p_lowpc , p_highpc );
73         }
74 #   endif DEBUG
75     for (   instructp = textspace + p_lowpc ;
76             instructp < textspace + p_highpc ;
77             instructp += length ) {
78         length = 1;
79         if ( (*instructp & CALL) ) {
80 #           ifdef DEBUG
81           if ( debug & CALLDEBUG ) {
82             printf( "[findcall]\t0x%x:callf" , instructp - textspace );
83           }
84 #           endif DEBUG
85           length += 4;  /* constant length in a SPARC */
86           /*
87            *    regular pc relative addressing
88            *    check that this is the address of 
89            *    a function.
90            */
91           destpc = ( (unsigned long)instructp + (*(long *)instructp & ~CALL) )
92             - (unsigned long) textspace;
93           if ( destpc >= s_lowpc && destpc <= s_highpc ) {
94             childp = nllookup( destpc );
95 #                       ifdef DEBUG
96             if ( debug & CALLDEBUG ) {
97               printf( "[findcall]\tdestpc 0x%x" , destpc );
98               printf( " childp->name %s" , childp -> name );
99               printf( " childp->value 0x%x\n" ,
100                      childp -> value );
101             }
102 #                       endif DEBUG
103             if ( childp -> value == destpc ) {
104               /*
105                *        a hit
106                */
107               addarc( parentp , childp , (long) 0 );
108               length += 4;      /* constant lengths */
109               continue;
110             }
111             goto botched;
112           }
113           /*
114            *    else:
115            *    it looked like a callf,
116            *    but it wasn't to anywhere.
117            */
118         botched:
119           /*
120            *    something funny going on.
121            */
122 #                   ifdef DEBUG
123           if ( debug & CALLDEBUG ) {
124             printf( "[findcall]\tbut it's a botch\n" );
125           }
126 #                   endif DEBUG
127           length = 1;
128           continue;
129         }
130       }
131   }