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