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