]> Git Repo - binutils.git/blame - sim/ppc/mon.c
Automatic date update in version.in
[binutils.git] / sim / ppc / mon.c
CommitLineData
c906108c
SS
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, Andrew Cagney <[email protected]>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
3fd725ef 7 the Free Software Foundation; either version 3 of the License, or
c906108c
SS
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
51b318de 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
c906108c
SS
17
18 */
19
20
21#ifndef _MON_C_
22#define _MON_C_
23
1352aabb
OS
24#include "defs.h"
25
c906108c
SS
26#include <stdio.h>
27
c906108c 28#include <string.h>
c906108c
SS
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
c906108c 32#include <stdlib.h>
c906108c
SS
33#ifdef HAVE_SYS_TYPES_H
34#include <sys/types.h>
35#endif
c906108c 36#include <time.h>
c906108c 37#include <sys/time.h>
c906108c
SS
38
39#ifdef HAVE_SYS_RESOURCE_H
40#include <sys/resource.h>
41int getrusage();
42#endif
43
1352aabb
OS
44#include "basics.h"
45#include "cpu.h"
46#include "mon.h"
47
c906108c
SS
48#define MAX_BYTE_READWRITE 9
49#define MAX_SHIFT_READWRITE 3
50
51struct _cpu_mon {
52 count_type issue_count[nr_itable_entries];
53 count_type read_count;
54 count_type read_byte_count[MAX_BYTE_READWRITE];
55 count_type write_count;
56 count_type write_byte_count[MAX_BYTE_READWRITE];
57 count_type unaligned_read_count;
58 count_type unaligned_write_count;
59 count_type event_count[nr_mon_events];
60};
61
62struct _mon {
63 int nr_cpus;
64 cpu_mon cpu_monitor[MAX_NR_PROCESSORS];
65};
66
67
68INLINE_MON\
69(mon *)
70mon_create(void)
71{
72 mon *monitor = ZALLOC(mon);
73 return monitor;
74}
75
76
77INLINE_MON\
78(cpu_mon *)
79mon_cpu(mon *monitor,
80 int cpu_nr)
81{
82 if (cpu_nr < 0 || cpu_nr >= MAX_NR_PROCESSORS)
83 error("mon_cpu() - invalid cpu number\n");
84 return &monitor->cpu_monitor[cpu_nr];
85}
86
87
88INLINE_MON\
89(void)
90mon_init(mon *monitor,
91 int nr_cpus)
92{
93 memset(monitor, 0, sizeof(*monitor));
94 monitor->nr_cpus = nr_cpus;
95}
96
97
98INLINE_MON\
99(void)
100mon_issue(itable_index index,
101 cpu *processor,
102 unsigned_word cia)
103{
104 cpu_mon *monitor = cpu_monitor(processor);
105 ASSERT(index <= nr_itable_entries);
106 monitor->issue_count[index] += 1;
107}
108
109
110INLINE_MON\
111(void)
112mon_read(unsigned_word ea,
113 unsigned_word ra,
114 unsigned nr_bytes,
115 cpu *processor,
116 unsigned_word cia)
117{
118 cpu_mon *monitor = cpu_monitor(processor);
119 monitor->read_count += 1;
120 monitor->read_byte_count[nr_bytes] += 1;
121 if ((nr_bytes - 1) & ea)
122 monitor->unaligned_read_count += 1;
123}
124
125
126INLINE_MON\
127(void)
128mon_write(unsigned_word ea,
129 unsigned_word ra,
130 unsigned nr_bytes,
131 cpu *processor,
132 unsigned_word cia)
133{
134 cpu_mon *monitor = cpu_monitor(processor);
135 monitor->write_count += 1;
136 monitor->write_byte_count[nr_bytes] += 1;
137 if ((nr_bytes - 1) & ea)
138 monitor->unaligned_write_count += 1;
139}
140
141INLINE_MON\
142(void)
143mon_event(mon_events event,
144 cpu *processor,
145 unsigned_word cia)
146{
147 cpu_mon *monitor = cpu_monitor(processor);
148 ASSERT(event < nr_mon_events);
149 monitor->event_count[event] += 1;
150}
151
152INLINE_MON\
153(unsigned)
154mon_get_number_of_insns(mon *monitor,
155 int cpu_nr)
156{
157 itable_index index;
158 unsigned total_insns = 0;
159 ASSERT(cpu_nr >= 0 && cpu_nr < monitor->nr_cpus);
160 for (index = 0; index < nr_itable_entries; index++)
161 total_insns += monitor->cpu_monitor[cpu_nr].issue_count[index];
162 return total_insns;
163}
164
165STATIC_INLINE_MON\
166(int)
167mon_sort_instruction_names(const void *ptr_a, const void *ptr_b)
168{
169 itable_index a = *(const itable_index *)ptr_a;
170 itable_index b = *(const itable_index *)ptr_b;
171
172 return strcmp (itable[a].name, itable[b].name);
173}
174
175STATIC_INLINE_MON\
176(char *)
177mon_add_commas(char *buf,
178 int sizeof_buf,
179 count_type value)
180{
181 int comma = 3;
182 char *endbuf = buf + sizeof_buf - 1;
183
184 *--endbuf = '\0';
185 do {
186 if (comma-- == 0)
187 {
188 *--endbuf = ',';
189 comma = 2;
190 }
191
192 *--endbuf = (value % 10) + '0';
193 } while ((value /= 10) != 0);
194
195 ASSERT(endbuf >= buf);
196 return endbuf;
197}
198
199
200INLINE_MON\
201(void)
202mon_print_info(psim *system,
203 mon *monitor,
204 int verbose)
205{
206 char buffer[20];
207 char buffer1[20];
208 char buffer2[20];
209 char buffer4[20];
210 char buffer8[20];
211 int cpu_nr;
212 int len_cpu;
213 int len_num = 0;
214 int len_sub_num[MAX_BYTE_READWRITE];
215 int len;
216 int i;
217 long total_insns = 0;
218 long cpu_insns_second = 0;
219 long total_sim_cycles = 0;
220 long sim_cycles_second = 0;
221 double cpu_time = 0.0;
222
223 for (i = 0; i < MAX_BYTE_READWRITE; i++)
224 len_sub_num[i] = 0;
225
226 for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
227 count_type num_insns = mon_get_number_of_insns(monitor, cpu_nr);
228
229 total_insns += num_insns;
230 len = strlen (mon_add_commas(buffer, sizeof(buffer), num_insns));
231 if (len_num < len)
232 len_num = len;
233
234 for (i = 0; i <= MAX_SHIFT_READWRITE; i++) {
235 int size = 1<<i;
236 len = strlen (mon_add_commas(buffer, sizeof(buffer),
237 monitor->cpu_monitor[cpu_nr].read_byte_count[size]));
238 if (len_sub_num[size] < len)
239 len_sub_num[size] = len;
240
241 len = strlen (mon_add_commas(buffer, sizeof(buffer),
242 monitor->cpu_monitor[cpu_nr].write_byte_count[size]));
243 if (len_sub_num[size] < len)
244 len_sub_num[size] = len;
245 }
246 }
247
248 sprintf (buffer, "%d", (int)monitor->nr_cpus + 1);
249 len_cpu = strlen (buffer);
250
251#ifdef HAVE_GETRUSAGE
252 {
253 struct rusage mytime;
254 if (getrusage (RUSAGE_SELF, &mytime) == 0
255 && (mytime.ru_utime.tv_sec > 0 || mytime.ru_utime.tv_usec > 0)) {
256
257 cpu_time = (double)mytime.ru_utime.tv_sec + (((double)mytime.ru_utime.tv_usec) / 1000000.0);
258 }
259 }
260 if (WITH_EVENTS)
261 total_sim_cycles = event_queue_time(psim_event_queue(system)) - 1;
262 if (cpu_time > 0) {
263 if (total_insns > 0)
264 cpu_insns_second = (long)(((double)total_insns / cpu_time) + 0.5);
265 if (total_sim_cycles) {
266 sim_cycles_second = (long)(((double)total_sim_cycles / cpu_time) + 0.5);
267 }
268 }
269#endif
270
271 for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
272
273 if (verbose > 1) {
274 itable_index sort_insns[nr_itable_entries];
275 int nr_sort_insns = 0;
276 itable_index index;
277 int index2;
278
279 if (cpu_nr)
280 printf_filtered ("\n");
281
282 for (index = 0; index < nr_itable_entries; index++) {
283 if (monitor->cpu_monitor[cpu_nr].issue_count[index]) {
284 sort_insns[nr_sort_insns++] = index;
285 }
286 }
287
288 qsort((void *)sort_insns, nr_sort_insns, sizeof(sort_insns[0]), mon_sort_instruction_names);
289
290 for (index2 = 0; index2 < nr_sort_insns; index2++) {
291 index = sort_insns[index2];
292 printf_filtered("CPU #%*d executed %*s %s instruction%s.\n",
293 len_cpu, cpu_nr+1,
294 len_num, mon_add_commas(buffer,
295 sizeof(buffer),
296 monitor->cpu_monitor[cpu_nr].issue_count[index]),
297 itable[index].name,
298 (monitor->cpu_monitor[cpu_nr].issue_count[index] == 1) ? "" : "s");
299 }
300
301 printf_filtered ("\n");
302 }
303
304 if (CURRENT_MODEL_ISSUE > 0)
305 {
306 model_data *model_ptr = cpu_model(psim_cpu(system, cpu_nr));
307 model_print *ptr = model_mon_info(model_ptr);
308 model_print *orig_ptr = ptr;
309
310 while (ptr) {
311 if (ptr->count)
312 printf_filtered("CPU #%*d executed %*s %s%s.\n",
313 len_cpu, cpu_nr+1,
314 len_num, mon_add_commas(buffer,
315 sizeof(buffer),
316 ptr->count),
317 ptr->name,
318 ((ptr->count == 1)
319 ? ptr->suffix_singular
320 : ptr->suffix_plural));
321
322 ptr = ptr->next;
323 }
324
325 model_mon_info_free(model_ptr, orig_ptr);
326 }
327
328 if (monitor->cpu_monitor[cpu_nr].read_count)
329 printf_filtered ("CPU #%*d executed %*s read%s (%*s 1-byte, %*s 2-byte, %*s 4-byte, %*s 8-byte).\n",
330 len_cpu, cpu_nr+1,
331 len_num, mon_add_commas(buffer,
332 sizeof(buffer),
333 monitor->cpu_monitor[cpu_nr].read_count),
334 (monitor->cpu_monitor[cpu_nr].read_count == 1) ? "" : "s",
335 len_sub_num[1], mon_add_commas(buffer1,
336 sizeof(buffer1),
337 monitor->cpu_monitor[cpu_nr].read_byte_count[1]),
338 len_sub_num[2], mon_add_commas(buffer2,
339 sizeof(buffer2),
340 monitor->cpu_monitor[cpu_nr].read_byte_count[2]),
341 len_sub_num[4], mon_add_commas(buffer4,
342 sizeof(buffer4),
343 monitor->cpu_monitor[cpu_nr].read_byte_count[4]),
344 len_sub_num[8], mon_add_commas(buffer8,
345 sizeof(buffer8),
346 monitor->cpu_monitor[cpu_nr].read_byte_count[8]));
347
348 if (monitor->cpu_monitor[cpu_nr].write_count)
349 printf_filtered ("CPU #%*d executed %*s write%s (%*s 1-byte, %*s 2-byte, %*s 4-byte, %*s 8-byte).\n",
350 len_cpu, cpu_nr+1,
351 len_num, mon_add_commas(buffer,
352 sizeof(buffer),
353 monitor->cpu_monitor[cpu_nr].write_count),
354 (monitor->cpu_monitor[cpu_nr].write_count == 1) ? "" : "s",
355 len_sub_num[1], mon_add_commas(buffer1,
356 sizeof(buffer1),
357 monitor->cpu_monitor[cpu_nr].write_byte_count[1]),
358 len_sub_num[2], mon_add_commas(buffer2,
359 sizeof(buffer2),
360 monitor->cpu_monitor[cpu_nr].write_byte_count[2]),
361 len_sub_num[4], mon_add_commas(buffer4,
362 sizeof(buffer4),
363 monitor->cpu_monitor[cpu_nr].write_byte_count[4]),
364 len_sub_num[8], mon_add_commas(buffer8,
365 sizeof(buffer8),
366 monitor->cpu_monitor[cpu_nr].write_byte_count[8]));
367
368 if (monitor->cpu_monitor[cpu_nr].unaligned_read_count)
369 printf_filtered ("CPU #%*d executed %*s unaligned read%s.\n",
370 len_cpu, cpu_nr+1,
371 len_num, mon_add_commas(buffer,
372 sizeof(buffer),
373 monitor->cpu_monitor[cpu_nr].unaligned_read_count),
374 (monitor->cpu_monitor[cpu_nr].unaligned_read_count == 1) ? "" : "s");
375
376 if (monitor->cpu_monitor[cpu_nr].unaligned_write_count)
377 printf_filtered ("CPU #%*d executed %*s unaligned write%s.\n",
378 len_cpu, cpu_nr+1,
379 len_num, mon_add_commas(buffer,
380 sizeof(buffer),
381 monitor->cpu_monitor[cpu_nr].unaligned_write_count),
382 (monitor->cpu_monitor[cpu_nr].unaligned_write_count == 1) ? "" : "s");
383
384 if (monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss])
385 printf_filtered ("CPU #%*d executed %*s icache miss%s.\n",
386 len_cpu, cpu_nr+1,
387 len_num, mon_add_commas(buffer,
388 sizeof(buffer),
389 monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss]),
390 (monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss] == 1) ? "" : "es");
391
392 {
393 long nr_insns = mon_get_number_of_insns(monitor, cpu_nr);
394 if (nr_insns > 0)
395 printf_filtered("CPU #%*d executed %*s instructions in total.\n",
396 len_cpu, cpu_nr+1,
397 len_num, mon_add_commas(buffer,
398 sizeof(buffer),
399 nr_insns));
400 }
401 }
402
403 if (total_insns > 0) {
404 if (monitor->nr_cpus > 1)
405 printf_filtered("\nAll CPUs executed %s instructions in total.\n",
406 mon_add_commas(buffer, sizeof(buffer), total_insns));
407 }
408 else if (total_sim_cycles > 0) {
409 printf_filtered("\nSimulator performed %s simulation cycles.\n",
410 mon_add_commas(buffer, sizeof(buffer), total_sim_cycles));
411 }
412
413 if (cpu_insns_second)
414 printf_filtered ("%sSimulator speed was %s instructions/second.\n",
415 (monitor->nr_cpus > 1) ? "" : "\n",
416 mon_add_commas(buffer, sizeof(buffer), cpu_insns_second));
417 else if (sim_cycles_second)
418 printf_filtered ("Simulator speed was %s simulation cycles/second\n",
419 mon_add_commas(buffer, sizeof(buffer), sim_cycles_second));
420 else if (cpu_time > 0.0)
421 printf_filtered ("%sSimulator executed for %.2f seconds\n",
422 (monitor->nr_cpus > 1) ? "" : "\n", cpu_time);
423
424}
425
426#endif /* _MON_C_ */
This page took 2.285639 seconds and 5 git commands to generate.