OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [ppc/] [mon.c] - Blame information for rev 106

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.