allow only /bin/csh, not /bin/oldcsh
[unix-history] / usr / src / usr.bin / gprof / vax.c
CommitLineData
a5040938 1#ifndef lint
a441395b 2 static char *sccsid = "@(#)vax.c 1.3 (Berkeley) %G%";
a5040938
PK
3#endif not lint
4
5#include "gprof.h"
6
7 /*
8 * a namelist entry to be the child of indirect calls
9 */
10nltype indirectchild = {
11 "(*)" , /* the name */
12 (unsigned long) 0 , /* the pc entry point */
13 (double) 0.0 , /* ticks in this routine */
14 (double) 0.0 , /* cumulative ticks in children */
15 (long) 0 , /* how many times called */
16 (long) 0 , /* how many calls to self */
a441395b
PK
17 (double) 1.0 , /* propagation fraction */
18 (double) 0.0 , /* self propagation time */
19 (double) 0.0 , /* child propagation time */
7ec9eedc 20 (bool) 0 , /* print flag */
a5040938
PK
21 (int) 0 , /* index in the graph list */
22 (int) 0 , /* graph call chain top-sort order */
23 (int) 0 , /* internal number of cycle on */
24 (struct nl *) &indirectchild , /* pointer to head of cycle */
25 (struct nl *) 0 , /* pointer to next member of cycle */
26 (arctype *) 0 , /* list of caller arcs */
27 (arctype *) 0 /* list of callee arcs */
28 };
29
30operandenum
31operandmode( modep )
32 struct modebyte *modep;
33{
34 long usesreg = modep -> regfield;
35
36 switch ( modep -> modefield ) {
37 case 0:
38 case 1:
39 case 2:
40 case 3:
41 return literal;
42 case 4:
43 return indexed;
44 case 5:
45 return reg;
46 case 6:
47 return regdef;
48 case 7:
49 return autodec;
50 case 8:
51 return ( usesreg != PC ? autoinc : immediate );
52 case 9:
53 return ( usesreg != PC ? autoincdef : absolute );
54 case 10:
55 return ( usesreg != PC ? bytedisp : byterel );
56 case 11:
57 return ( usesreg != PC ? bytedispdef : bytereldef );
58 case 12:
59 return ( usesreg != PC ? worddisp : wordrel );
60 case 13:
61 return ( usesreg != PC ? worddispdef : wordreldef );
62 case 14:
63 return ( usesreg != PC ? longdisp : longrel );
64 case 15:
65 return ( usesreg != PC ? longdispdef : longreldef );
66 }
67 /* NOTREACHED */
68}
69
70char *
71operandname( mode )
72 operandenum mode;
73{
74
75 switch ( mode ) {
76 case literal:
77 return "literal";
78 case indexed:
79 return "indexed";
80 case reg:
81 return "register";
82 case regdef:
83 return "register deferred";
84 case autodec:
85 return "autodecrement";
86 case autoinc:
87 return "autoincrement";
88 case autoincdef:
89 return "autoincrement deferred";
90 case bytedisp:
91 return "byte displacement";
92 case bytedispdef:
93 return "byte displacement deferred";
94 case byterel:
95 return "byte relative";
96 case bytereldef:
97 return "byte relative deferred";
98 case worddisp:
99 return "word displacement";
100 case worddispdef:
101 return "word displacement deferred";
102 case wordrel:
103 return "word relative";
104 case wordreldef:
105 return "word relative deferred";
106 case immediate:
107 return "immediate";
108 case absolute:
109 return "absolute";
110 case longdisp:
111 return "long displacement";
112 case longdispdef:
113 return "long displacement deferred";
114 case longrel:
115 return "long relative";
116 case longreldef:
117 return "long relative deferred";
118 }
119 /* NOTREACHED */
120}
121
122long
123operandlength( modep )
124 struct modebyte *modep;
125{
126
127 switch ( operandmode( modep ) ) {
128 case literal:
129 case reg:
130 case regdef:
131 case autodec:
132 case autoinc:
133 case autoincdef:
134 return 1;
135 case bytedisp:
136 case bytedispdef:
137 case byterel:
138 case bytereldef:
139 return 2;
140 case worddisp:
141 case worddispdef:
142 case wordrel:
143 case wordreldef:
144 return 3;
145 case immediate:
146 case absolute:
147 case longdisp:
148 case longdispdef:
149 case longrel:
150 case longreldef:
151 return 5;
152 case indexed:
153 return 1+operandlength( (struct modebyte *) ((char *) modep) + 1 );
154 }
155 /* NOTREACHED */
156}
157
158unsigned long
159reladdr( modep )
160 struct modebyte *modep;
161{
162 operandenum mode = operandmode( modep );
163 char *cp;
164 short *sp;
165 long *lp;
166
167 cp = (char *) modep;
168 cp += 1; /* skip over the mode */
169 switch ( mode ) {
170 default:
171 fprintf( stderr , "[reladdr] not relative address\n" );
172 return (unsigned long) modep;
173 case byterel:
174 return (unsigned long) ( cp + sizeof *cp + *cp );
175 case wordrel:
176 sp = (short *) cp;
177 return (unsigned long) ( cp + sizeof *sp + *sp );
178 case longrel:
179 lp = (long *) cp;
180 return (unsigned long) ( cp + sizeof *lp + *lp );
181 }
182}
183
184findcalls( parentp , p_lowpc , p_highpc )
185 nltype *parentp;
186 unsigned long p_lowpc;
187 unsigned long p_highpc;
188{
189 unsigned char *instructp;
190 long length;
191 nltype *childp;
192 operandenum mode;
193 operandenum firstmode;
194 unsigned long destpc;
195
196 if ( textspace == 0 ) {
197 return;
198 }
199 if ( p_lowpc < s_lowpc ) {
200 p_lowpc = s_lowpc;
201 }
202 if ( p_highpc > s_highpc ) {
203 p_highpc = s_highpc;
204 }
205# ifdef DEBUG
206 if ( debug & CALLSDEBUG ) {
207 printf( "[findcalls] %s: 0x%x to 0x%x\n" ,
208 parentp -> name , p_lowpc , p_highpc );
209 }
210# endif DEBUG
211 for ( instructp = textspace + p_lowpc ;
212 instructp < textspace + p_highpc ;
213 instructp += length ) {
214 length = 1;
215 if ( *instructp == CALLS ) {
216 /*
217 * maybe a calls, better check it out.
218 * skip the count of the number of arguments.
219 */
220# ifdef DEBUG
221 if ( debug & CALLSDEBUG ) {
222 printf( "[findcalls]\t0x%x:calls" , instructp - textspace );
223 }
224# endif DEBUG
225 firstmode = operandmode( (struct modebyte *) (instructp+length) );
226 switch ( firstmode ) {
227 case literal:
228 case immediate:
229 break;
230 default:
231 goto botched;
232 }
233 length += operandlength( (struct modebyte *) (instructp+length) );
234 mode = operandmode( (struct modebyte *) ( instructp + length ) );
235# ifdef DEBUG
236 if ( debug & CALLSDEBUG ) {
237 printf( "\tfirst operand is %s", operandname( firstmode ) );
238 printf( "\tsecond operand is %s\n" , operandname( mode ) );
239 }
240# endif DEBUG
241 switch ( mode ) {
242 case regdef:
243 case bytedispdef:
244 case worddispdef:
245 case longdispdef:
246 case bytereldef:
247 case wordreldef:
248 case longreldef:
249 /*
250 * indirect call: call through pointer
251 * either *d(r) as a parameter or local
252 * (r) as a return value
253 * *f as a global pointer
254 * [are there others that we miss?,
255 * e.g. arrays of pointers to functions???]
256 */
257 addarc( parentp , &indirectchild , (long) 0 );
258 length += operandlength(
259 (struct modebyte *) ( instructp + length ) );
260 continue;
261 case byterel:
262 case wordrel:
263 case longrel:
264 /*
265 * regular pc relative addressing
266 * check that this is the address of
267 * a function.
268 */
269 destpc = reladdr( (struct modebyte *) (instructp+length) )
270 - (unsigned long) textspace;
271 if ( destpc >= s_lowpc && destpc <= s_highpc ) {
272 childp = nllookup( destpc );
273# ifdef DEBUG
274 if ( debug & CALLSDEBUG ) {
275 printf( "[findcalls]\tdestpc 0x%x" , destpc );
276 printf( " childp->name %s" , childp -> name );
277 printf( " childp->value 0x%x\n" ,
278 childp -> value );
279 }
280# endif DEBUG
281 if ( childp -> value == destpc ) {
282 /*
283 * a hit
284 */
285 addarc( parentp , childp , (long) 0 );
286 length += operandlength( (struct modebyte *)
287 ( instructp + length ) );
288 continue;
289 }
290 goto botched;
291 }
292 /*
293 * else:
294 * it looked like a calls,
295 * but it wasn't to anywhere.
296 */
297 goto botched;
298 default:
299 botched:
300 /*
301 * something funny going on.
302 */
303# ifdef DEBUG
304 if ( debug & CALLSDEBUG ) {
305 printf( "[findcalls]\tbut it's a botch\n" );
306 }
307# endif DEBUG
308 length = 1;
309 continue;
310 }
311 }
312 }
313}