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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [common/] [sim-trace.c] - Blame information for rev 1771

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

Line No. Rev Author Line
1 106 markom
/* Simulator tracing/debugging support.
2
   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
3
   Contributed by Cygnus Support.
4
 
5
This file is part of GDB, the GNU debugger.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License along
18
with this program; if not, write to the Free Software Foundation, Inc.,
19
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sim-main.h"
22
#include "sim-io.h"
23
#include "sim-options.h"
24
#include "sim-fpu.h"
25
 
26
#include "bfd.h"
27
#include "libiberty.h"
28
 
29
#include "sim-assert.h"
30
 
31
#ifdef HAVE_STRING_H
32
#include <string.h>
33
#else
34
#ifdef HAVE_STRINGS_H
35
#include <strings.h>
36
#endif
37
#endif
38
#ifdef HAVE_STDLIB_H
39
#include <stdlib.h>
40
#endif
41
 
42
#ifndef SIZE_PHASE
43
#define SIZE_PHASE 8
44
#endif
45
 
46
#ifndef SIZE_LOCATION
47
#define SIZE_LOCATION 20
48
#endif
49
 
50
#ifndef SIZE_PC
51
#define SIZE_PC 6
52
#endif
53
 
54
#ifndef SIZE_LINE_NUMBER
55
#define SIZE_LINE_NUMBER 4
56
#endif
57
 
58
static MODULE_INIT_FN trace_init;
59
static MODULE_UNINSTALL_FN trace_uninstall;
60
 
61
static DECLARE_OPTION_HANDLER (trace_option_handler);
62
 
63
enum {
64
  OPTION_TRACE_INSN     = OPTION_START,
65
  OPTION_TRACE_DECODE,
66
  OPTION_TRACE_EXTRACT,
67
  OPTION_TRACE_LINENUM,
68
  OPTION_TRACE_MEMORY,
69
  OPTION_TRACE_MODEL,
70
  OPTION_TRACE_ALU,
71
  OPTION_TRACE_CORE,
72
  OPTION_TRACE_EVENTS,
73
  OPTION_TRACE_FPU,
74
  OPTION_TRACE_BRANCH,
75
  OPTION_TRACE_SEMANTICS,
76
  OPTION_TRACE_RANGE,
77
  OPTION_TRACE_FUNCTION,
78
  OPTION_TRACE_DEBUG,
79
  OPTION_TRACE_FILE
80
};
81
 
82
static const OPTION trace_options[] =
83
{
84
  /* This table is organized to group related instructions together.  */
85
  { {"trace", optional_argument, NULL, 't'},
86
      't', "on|off", "Trace useful things",
87
      trace_option_handler },
88
  { {"trace-insn", optional_argument, NULL, OPTION_TRACE_INSN},
89
      '\0', "on|off", "Perform instruction tracing",
90
      trace_option_handler },
91
  { {"trace-decode", optional_argument, NULL, OPTION_TRACE_DECODE},
92
      '\0', "on|off", "Trace instruction decoding",
93
      trace_option_handler },
94
  { {"trace-extract", optional_argument, NULL, OPTION_TRACE_EXTRACT},
95
      '\0', "on|off", "Trace instruction extraction",
96
      trace_option_handler },
97
  { {"trace-linenum", optional_argument, NULL, OPTION_TRACE_LINENUM},
98
      '\0', "on|off", "Perform line number tracing (implies --trace-insn)",
99
      trace_option_handler },
100
  { {"trace-memory", optional_argument, NULL, OPTION_TRACE_MEMORY},
101
      '\0', "on|off", "Trace memory operations",
102
      trace_option_handler },
103
  { {"trace-alu", optional_argument, NULL, OPTION_TRACE_ALU},
104
      '\0', "on|off", "Trace ALU operations",
105
      trace_option_handler },
106
  { {"trace-fpu", optional_argument, NULL, OPTION_TRACE_FPU},
107
      '\0', "on|off", "Trace FPU operations",
108
      trace_option_handler },
109
  { {"trace-branch", optional_argument, NULL, OPTION_TRACE_BRANCH},
110
      '\0', "on|off", "Trace branching",
111
      trace_option_handler },
112
  { {"trace-semantics", optional_argument, NULL, OPTION_TRACE_SEMANTICS},
113
      '\0', "on|off", "Perform ALU, FPU, MEMORY, and BRANCH tracing",
114
      trace_option_handler },
115
  { {"trace-model", optional_argument, NULL, OPTION_TRACE_MODEL},
116
      '\0', "on|off", "Include model performance data",
117
      trace_option_handler },
118
  { {"trace-core", optional_argument, NULL, OPTION_TRACE_CORE},
119
      '\0', "on|off", "Trace core operations",
120
      trace_option_handler },
121
  { {"trace-events", optional_argument, NULL, OPTION_TRACE_EVENTS},
122
      '\0', "on|off", "Trace events",
123
      trace_option_handler },
124
#ifdef SIM_HAVE_ADDR_RANGE
125
  { {"trace-range", required_argument, NULL, OPTION_TRACE_RANGE},
126
      '\0', "START,END", "Specify range of addresses for instruction tracing",
127
      trace_option_handler },
128
#if 0 /*wip*/
129
  { {"trace-function", required_argument, NULL, OPTION_TRACE_FUNCTION},
130
      '\0', "FUNCTION", "Specify function to trace",
131
      trace_option_handler },
132
#endif
133
#endif
134
  { {"trace-debug", optional_argument, NULL, OPTION_TRACE_DEBUG},
135
      '\0', "on|off", "Add information useful for debugging the simulator to the tracing output",
136
      trace_option_handler },
137
  { {"trace-file", required_argument, NULL, OPTION_TRACE_FILE},
138
      '\0', "FILE NAME", "Specify tracing output file",
139
      trace_option_handler },
140
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
141
};
142
 
143
/* Set/reset the trace options indicated in MASK.  */
144
 
145
static SIM_RC
146
set_trace_option_mask (sd, name, mask, arg)
147
     SIM_DESC sd;
148
     const char *name;
149
     int mask;
150
     const char *arg;
151
{
152
  int trace_nr;
153
  int cpu_nr;
154
  int trace_val = 1;
155
 
156
  if (arg != NULL)
157
    {
158
      if (strcmp (arg, "yes") == 0
159
          || strcmp (arg, "on") == 0
160
          || strcmp (arg, "1") == 0)
161
        trace_val = 1;
162
      else if (strcmp (arg, "no") == 0
163
               || strcmp (arg, "off") == 0
164
               || strcmp (arg, "0") == 0)
165
        trace_val = 0;
166
      else
167
        {
168
          sim_io_eprintf (sd, "Argument `%s' for `--trace%s' invalid, one of `on', `off', `yes', `no' expected\n", arg, name);
169
          return SIM_RC_FAIL;
170
        }
171
    }
172
 
173
  /* update applicable trace bits */
174
  for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
175
    {
176
      if ((mask & (1 << trace_nr)) == 0)
177
        continue;
178
 
179
      /* Set non-cpu specific values.  */
180
      switch (trace_nr)
181
        {
182
        case TRACE_EVENTS_IDX:
183
          STATE_EVENTS (sd)->trace = trace_val;
184
          break;
185
        case TRACE_DEBUG_IDX:
186
          STATE_TRACE_FLAGS (sd)[trace_nr] = trace_val;
187
          break;
188
        }
189
 
190
      /* Set cpu values.  */
191
      for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
192
        {
193
          CPU_TRACE_FLAGS (STATE_CPU (sd, cpu_nr))[trace_nr] = trace_val;
194
        }
195
    }
196
 
197
  /* Re-compute the cpu trace summary.  */
198
  if (trace_val)
199
    {
200
      for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
201
        CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
202
    }
203
  else
204
    {
205
      for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
206
        {
207
          CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 0;
208
          for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
209
            {
210
              if (CPU_TRACE_FLAGS (STATE_CPU (sd, cpu_nr))[trace_nr])
211
                {
212
                  CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
213
                  break;
214
                }
215
            }
216
        }
217
    }
218
 
219
  return SIM_RC_OK;
220
}
221
 
222
/* Set one trace option based on its IDX value.  */
223
 
224
static SIM_RC
225
set_trace_option (sd, name, idx, arg)
226
     SIM_DESC sd;
227
     const char *name;
228
     int idx;
229
     const char *arg;
230
{
231
  return set_trace_option_mask (sd, name, 1 << idx, arg);
232
}
233
 
234
 
235
static SIM_RC
236
trace_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
237
                      char *arg, int is_command)
238
{
239
  int n;
240
  int cpu_nr;
241
 
242
  switch (opt)
243
    {
244
    case 't' :
245
      if (! WITH_TRACE)
246
        sim_io_eprintf (sd, "Tracing not compiled in, `-t' ignored\n");
247
      else
248
        return set_trace_option_mask (sd, "trace", TRACE_USEFUL_MASK, arg);
249
      break;
250
 
251
    case OPTION_TRACE_INSN :
252
      if (WITH_TRACE_INSN_P)
253
        return set_trace_option (sd, "-insn", TRACE_INSN_IDX, arg);
254
      else
255
        sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-insn' ignored\n");
256
      break;
257
 
258
    case OPTION_TRACE_DECODE :
259
      if (WITH_TRACE_DECODE_P)
260
        return set_trace_option (sd, "-decode", TRACE_DECODE_IDX, arg);
261
      else
262
        sim_io_eprintf (sd, "Decode tracing not compiled in, `--trace-decode' ignored\n");
263
      break;
264
 
265
    case OPTION_TRACE_EXTRACT :
266
      if (WITH_TRACE_EXTRACT_P)
267
        return set_trace_option (sd, "-extract", TRACE_EXTRACT_IDX, arg);
268
      else
269
        sim_io_eprintf (sd, "Extract tracing not compiled in, `--trace-extract' ignored\n");
270
      break;
271
 
272
    case OPTION_TRACE_LINENUM :
273
      if (WITH_TRACE_LINENUM_P && WITH_TRACE_INSN_P)
274
        {
275
          if (set_trace_option (sd, "-linenum", TRACE_LINENUM_IDX, arg) != SIM_RC_OK
276
              || set_trace_option (sd, "-linenum", TRACE_INSN_IDX, arg) != SIM_RC_OK)
277
            return SIM_RC_FAIL;
278
        }
279
      else
280
        sim_io_eprintf (sd, "Line number or instruction tracing not compiled in, `--trace-linenum' ignored\n");
281
      break;
282
 
283
    case OPTION_TRACE_MEMORY :
284
      if (WITH_TRACE_MEMORY_P)
285
        return set_trace_option (sd, "-memory", TRACE_MEMORY_IDX, arg);
286
      else
287
        sim_io_eprintf (sd, "Memory tracing not compiled in, `--trace-memory' ignored\n");
288
      break;
289
 
290
    case OPTION_TRACE_MODEL :
291
      if (WITH_TRACE_MODEL_P)
292
        return set_trace_option (sd, "-model", TRACE_MODEL_IDX, arg);
293
      else
294
        sim_io_eprintf (sd, "Model tracing not compiled in, `--trace-model' ignored\n");
295
      break;
296
 
297
    case OPTION_TRACE_ALU :
298
      if (WITH_TRACE_ALU_P)
299
        return set_trace_option (sd, "-alu", TRACE_ALU_IDX, arg);
300
      else
301
        sim_io_eprintf (sd, "ALU tracing not compiled in, `--trace-alu' ignored\n");
302
      break;
303
 
304
    case OPTION_TRACE_CORE :
305
      if (WITH_TRACE_CORE_P)
306
        return set_trace_option (sd, "-core", TRACE_CORE_IDX, arg);
307
      else
308
        sim_io_eprintf (sd, "CORE tracing not compiled in, `--trace-core' ignored\n");
309
      break;
310
 
311
    case OPTION_TRACE_EVENTS :
312
      if (WITH_TRACE_EVENTS_P)
313
        return set_trace_option (sd, "-events", TRACE_EVENTS_IDX, arg);
314
      else
315
        sim_io_eprintf (sd, "EVENTS tracing not compiled in, `--trace-events' ignored\n");
316
      break;
317
 
318
    case OPTION_TRACE_FPU :
319
      if (WITH_TRACE_FPU_P)
320
        return set_trace_option (sd, "-fpu", TRACE_FPU_IDX, arg);
321
      else
322
        sim_io_eprintf (sd, "FPU tracing not compiled in, `--trace-fpu' ignored\n");
323
      break;
324
 
325
    case OPTION_TRACE_BRANCH :
326
      if (WITH_TRACE_BRANCH_P)
327
        return set_trace_option (sd, "-branch", TRACE_BRANCH_IDX, arg);
328
      else
329
        sim_io_eprintf (sd, "Branch tracing not compiled in, `--trace-branch' ignored\n");
330
      break;
331
 
332
    case OPTION_TRACE_SEMANTICS :
333
      if (WITH_TRACE_ALU_P
334
          && WITH_TRACE_FPU_P
335
          && WITH_TRACE_MEMORY_P
336
          && WITH_TRACE_BRANCH_P)
337
        {
338
          if (set_trace_option (sd, "-semantics", TRACE_ALU_IDX, arg) != SIM_RC_OK
339
              || set_trace_option (sd, "-semantics", TRACE_FPU_IDX, arg) != SIM_RC_OK
340
              || set_trace_option (sd, "-semantics", TRACE_MEMORY_IDX, arg) != SIM_RC_OK
341
              || set_trace_option (sd, "-semantics", TRACE_BRANCH_IDX, arg) != SIM_RC_OK)
342
            return SIM_RC_FAIL;
343
        }
344
      else
345
        sim_io_eprintf (sd, "Alu, fpu, memory, and/or branch tracing not compiled in, `--trace-semantics' ignored\n");
346
      break;
347
 
348
#ifdef SIM_HAVE_ADDR_RANGE
349
    case OPTION_TRACE_RANGE :
350
      if (WITH_TRACE)
351
        {
352
          char *chp = arg;
353
          unsigned long start,end;
354
          start = strtoul (chp, &chp, 0);
355
          if (*chp != ',')
356
            {
357
              sim_io_eprintf (sd, "--trace-range missing END argument\n");
358
              return SIM_RC_FAIL;
359
            }
360
          end = strtoul (chp + 1, NULL, 0);
361
          /* FIXME: Argument validation.  */
362
          if (cpu != NULL)
363
            sim_addr_range_add (TRACE_RANGE (CPU_PROFILE_DATA (cpu)),
364
                                start, end);
365
          else
366
            for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
367
              sim_addr_range_add (TRACE_RANGE (CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))),
368
                                  start, end);
369
        }
370
      else
371
        sim_io_eprintf (sd, "Tracing not compiled in, `--trace-range' ignored\n");
372
      break;
373
 
374
    case OPTION_TRACE_FUNCTION :
375
      if (WITH_TRACE)
376
        {
377
          /*wip: need to compute function range given name*/
378
        }
379
      else
380
        sim_io_eprintf (sd, "Tracing not compiled in, `--trace-function' ignored\n");
381
      break;
382
#endif /* SIM_HAVE_ADDR_RANGE */
383
 
384
    case OPTION_TRACE_DEBUG :
385
      if (WITH_TRACE_DEBUG_P)
386
        return set_trace_option (sd, "-debug", TRACE_DEBUG_IDX, arg);
387
      else
388
        sim_io_eprintf (sd, "Tracing debug support not compiled in, `--trace-debug' ignored\n");
389
      break;
390
 
391
    case OPTION_TRACE_FILE :
392
      if (! WITH_TRACE)
393
        sim_io_eprintf (sd, "Tracing not compiled in, `--trace-file' ignored\n");
394
      else
395
        {
396
          FILE *f = fopen (arg, "w");
397
 
398
          if (f == NULL)
399
            {
400
              sim_io_eprintf (sd, "Unable to open trace output file `%s'\n", arg);
401
              return SIM_RC_FAIL;
402
            }
403
          for (n = 0; n < MAX_NR_PROCESSORS; ++n)
404
            TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, n))) = f;
405
          TRACE_FILE (STATE_TRACE_DATA (sd)) = f;
406
        }
407
      break;
408
    }
409
 
410
  return SIM_RC_OK;
411
}
412
 
413
/* Install tracing support.  */
414
 
415
SIM_RC
416
trace_install (SIM_DESC sd)
417
{
418
  int i;
419
 
420
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
421
 
422
  sim_add_option_table (sd, NULL, trace_options);
423
  memset (STATE_TRACE_DATA (sd), 0, sizeof (* STATE_TRACE_DATA (sd)));
424
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
425
    memset (CPU_TRACE_DATA (STATE_CPU (sd, i)), 0,
426
            sizeof (* CPU_TRACE_DATA (STATE_CPU (sd, i))));
427
  sim_module_add_init_fn (sd, trace_init);
428
  sim_module_add_uninstall_fn (sd, trace_uninstall);
429
  return SIM_RC_OK;
430
}
431
 
432
static SIM_RC
433
trace_init (SIM_DESC sd)
434
{
435
#ifdef SIM_HAVE_ADDR_RANGE
436
  /* Check if a range has been specified without specifying what to
437
     collect.  */
438
  {
439
    int i;
440
 
441
    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
442
      {
443
        sim_cpu *cpu = STATE_CPU (sd, i);
444
 
445
        if (ADDR_RANGE_RANGES (TRACE_RANGE (CPU_TRACE_DATA (cpu)))
446
            && ! TRACE_INSN_P (cpu))
447
          {
448
            sim_io_eprintf_cpu (cpu, "Tracing address range specified without --trace-insn.\n");
449
            sim_io_eprintf_cpu (cpu, "Address range ignored.\n");
450
            sim_addr_range_delete (TRACE_RANGE (CPU_TRACE_DATA (cpu)),
451
                                   0, ~ (address_word) 0);
452
          }
453
      }
454
  }
455
#endif
456
 
457
  return SIM_RC_OK;
458
}
459
 
460
static void
461
trace_uninstall (SIM_DESC sd)
462
{
463
  int i,j;
464
  FILE *sfile = TRACE_FILE (STATE_TRACE_DATA (sd));
465
 
466
  if (sfile != NULL)
467
    fclose (sfile);
468
 
469
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
470
    {
471
      FILE *cfile = TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, i)));
472
      if (cfile != NULL && cfile != sfile)
473
        {
474
          /* If output from different cpus is going to the same file,
475
             avoid closing the file twice.  */
476
          for (j = 0; j < i; ++j)
477
            if (TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, j))) == cfile)
478
              break;
479
          if (i == j)
480
            fclose (cfile);
481
        }
482
    }
483
}
484
 
485
typedef enum {
486
  trace_fmt_invalid,
487
  trace_fmt_word,
488
  trace_fmt_fp,
489
  trace_fmt_fpu,
490
  trace_fmt_string,
491
  trace_fmt_bool,
492
  trace_fmt_addr,
493
  trace_fmt_instruction_incomplete,
494
} data_fmt;
495
 
496
/* compute the nr of trace data units consumed by data */
497
static int
498
save_data_size (TRACE_DATA *data,
499
                long size)
500
{
501
  return ((size + sizeof (TRACE_INPUT_DATA (data) [0]) - 1)
502
          / sizeof (TRACE_INPUT_DATA (data) [0]));
503
}
504
 
505
 
506
/* Archive DATA into the trace buffer */
507
static void
508
save_data (SIM_DESC sd,
509
           TRACE_DATA *data,
510
           data_fmt fmt,
511
           long size,
512
           void *buf)
513
{
514
  int i = TRACE_INPUT_IDX (data);
515
  if (i == sizeof (TRACE_INPUT_FMT (data)))
516
    sim_io_error (sd, "trace buffer overflow");
517
  TRACE_INPUT_FMT (data) [i] = fmt;
518
  TRACE_INPUT_SIZE (data) [i] = size;
519
  memcpy (&TRACE_INPUT_DATA (data) [i], buf, size);
520
  i += save_data_size (data, size);
521
  TRACE_INPUT_IDX (data) = i;
522
}
523
 
524
static void
525
print_data (SIM_DESC sd,
526
            sim_cpu *cpu,
527
            data_fmt fmt,
528
            long size,
529
            void *data)
530
{
531
  switch (fmt)
532
    {
533
    case trace_fmt_instruction_incomplete:
534
      trace_printf (sd, cpu, " (instruction incomplete)");
535
      break;
536
    case trace_fmt_word:
537
    case trace_fmt_addr:
538
      {
539
        switch (size)
540
          {
541
          case sizeof (unsigned32):
542
            trace_printf (sd, cpu, " 0x%08lx", (long) * (unsigned32*) data);
543
            break;
544
          case sizeof (unsigned64):
545
            trace_printf (sd, cpu, " 0x%08lx%08lx",
546
                          (long) ((* (unsigned64*) data) >> 32),
547
                          (long) * (unsigned64*) data);
548
            break;
549
          default:
550
            abort ();
551
          }
552
        break;
553
      }
554
    case trace_fmt_bool:
555
      {
556
        SIM_ASSERT (size == sizeof (int));
557
        trace_printf (sd, cpu, " %-8s",
558
                      (* (int*) data) ? "true" : "false");
559
        break;
560
      }
561
    case trace_fmt_fp:
562
      {
563
        sim_fpu fp;
564
        switch (size)
565
          {
566
            /* FIXME: Assumes sizeof float == 4; sizeof double == 8 */
567
          case 4:
568
            sim_fpu_32to (&fp, *(unsigned32*)data);
569
            break;
570
          case 8:
571
            sim_fpu_64to (&fp, *(unsigned64*)data);
572
            break;
573
          default:
574
            abort ();
575
          }
576
        trace_printf (sd, cpu, " %8g", sim_fpu_2d (&fp));
577
        switch (size)
578
          {
579
          case 4:
580
            trace_printf (sd, cpu, " (0x%08lx)",
581
                          (long) *(unsigned32*)data);
582
            break;
583
          case 8:
584
            trace_printf (sd, cpu, " (0x%08lx%08lx)",
585
                          (long) (*(unsigned64*)data >> 32),
586
                          (long) (*(unsigned64*)data));
587
            break;
588
          default:
589
            abort ();
590
          }
591
        break;
592
      }
593
    case trace_fmt_fpu:
594
      /* FIXME: At present sim_fpu data is stored as a double */
595
      trace_printf (sd, cpu, " %8g", * (double*) data);
596
      break;
597
    case trace_fmt_string:
598
      trace_printf (sd, cpu, " %-8s", (char*) data);
599
      break;
600
    default:
601
      abort ();
602
    }
603
}
604
 
605
static const char *
606
trace_idx_to_str (int trace_idx)
607
{
608
  static char num[8];
609
  switch (trace_idx)
610
    {
611
    case TRACE_ALU_IDX:     return "alu:     ";
612
    case TRACE_INSN_IDX:    return "insn:    ";
613
    case TRACE_DECODE_IDX:  return "decode:  ";
614
    case TRACE_EXTRACT_IDX: return "extract: ";
615
    case TRACE_MEMORY_IDX:  return "memory:  ";
616
    case TRACE_CORE_IDX:    return "core:    ";
617
    case TRACE_EVENTS_IDX:  return "events:  ";
618
    case TRACE_FPU_IDX:     return "fpu:     ";
619
    case TRACE_BRANCH_IDX:  return "branch:  ";
620
    default:
621
      sprintf (num, "?%d?", trace_idx);
622
      return num;
623
    }
624
}
625
 
626
static void
627
trace_results (SIM_DESC sd,
628
               sim_cpu *cpu,
629
               int trace_idx,
630
               int last_input)
631
{
632
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
633
  int nr_out;
634
  int i;
635
 
636
  /* cross check trace_idx against TRACE_IDX (data)? */
637
 
638
  /* prefix */
639
  trace_printf (sd, cpu, "%s %s",
640
                trace_idx_to_str (TRACE_IDX (data)),
641
                TRACE_PREFIX (data));
642
  TRACE_IDX (data) = 0;
643
 
644
  for (i = 0, nr_out = 0;
645
       i < TRACE_INPUT_IDX (data);
646
       i += save_data_size (data, TRACE_INPUT_SIZE (data) [i]), nr_out++)
647
    {
648
      if (i == last_input)
649
        {
650
          int pad = (strlen (" 0x") + sizeof (unsigned_word) * 2);
651
          int padding = pad * (3 - nr_out);
652
          if (padding < 0)
653
            padding = 0;
654
          padding += strlen (" ::");
655
          trace_printf (sd, cpu, "%*s", padding, " ::");
656
        }
657
      print_data (sd, cpu,
658
                  TRACE_INPUT_FMT (data) [i],
659
                  TRACE_INPUT_SIZE (data) [i],
660
                  &TRACE_INPUT_DATA (data) [i]);
661
    }
662
  trace_printf (sd, cpu, "\n");
663
}
664
 
665
void
666
trace_prefix (SIM_DESC sd,
667
              sim_cpu *cpu,
668
              sim_cia cia,
669
              address_word pc,
670
              int line_p,
671
              const char *filename,
672
              int linenum,
673
              const char *fmt,
674
              ...)
675
{
676
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
677
  va_list ap;
678
  char *prefix = TRACE_PREFIX (data);
679
  char *chp;
680
 /* FIXME: The TRACE_PREFIX_WIDTH should be determined at build time using
681
    known information about the disassembled instructions. */
682
#ifndef TRACE_PREFIX_WIDTH
683
#define TRACE_PREFIX_WIDTH 48
684
#endif
685
  int width = TRACE_PREFIX_WIDTH;
686
 
687
  /* if the previous trace data wasn't flushed, flush it now with a
688
     note indicating that the trace was incomplete. */
689
  if (TRACE_IDX (data) != 0)
690
    {
691
      int last_input = TRACE_INPUT_IDX (data);
692
      save_data (sd, data, trace_fmt_instruction_incomplete, 1, "");
693
      trace_results (sd, cpu, TRACE_IDX (data), last_input);
694
    }
695
  TRACE_IDX (data) = 0;
696
  TRACE_INPUT_IDX (data) = 0;
697
 
698
  /* Create the text prefix for this new instruction: */
699
  if (!line_p)
700
    {
701
      if (filename)
702
        {
703
          sprintf (prefix, "%s:%-*d 0x%.*lx ",
704
                   filename,
705
                   SIZE_LINE_NUMBER, linenum,
706
                   SIZE_PC, (long) pc);
707
        }
708
      else
709
        {
710
          sprintf (prefix, "0x%.*lx ",
711
                   SIZE_PC, (long) pc);
712
          /* Shrink the width by the amount that we didn't print.  */
713
          width -= SIZE_LINE_NUMBER + SIZE_PC + 8;
714
        }
715
      chp = strchr (prefix, '\0');
716
      va_start (ap, fmt);
717
      vsprintf (chp, fmt, ap);
718
      va_end (ap);
719
    }
720
  else
721
    {
722
      char buf[256];
723
      buf[0] = 0;
724
      if (STATE_TEXT_SECTION (CPU_STATE (cpu))
725
          && pc >= STATE_TEXT_START (CPU_STATE (cpu))
726
          && pc < STATE_TEXT_END (CPU_STATE (cpu)))
727
        {
728
          const char *pc_filename = (const char *)0;
729
          const char *pc_function = (const char *)0;
730
          unsigned int pc_linenum = 0;
731
          bfd *abfd;
732
          asymbol **asymbols;
733
 
734
          abfd = STATE_PROG_BFD (CPU_STATE (cpu));
735
          asymbols = STATE_PROG_SYMS (CPU_STATE (cpu));
736
          if (asymbols == NULL)
737
            {
738
              long symsize;
739
              long symbol_count;
740
 
741
              symsize = bfd_get_symtab_upper_bound (abfd);
742
              if (symsize < 0)
743
                {
744
                  sim_engine_abort (sd, cpu, cia, "could not read symbols");
745
                }
746
              asymbols = (asymbol **) xmalloc (symsize);
747
              symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
748
              if (symbol_count < 0)
749
                {
750
                  sim_engine_abort (sd, cpu, cia, "could not canonicalize symbols");
751
                }
752
              STATE_PROG_SYMS (CPU_STATE (cpu)) = asymbols;
753
            }
754
 
755
          if (bfd_find_nearest_line (abfd,
756
                                     STATE_TEXT_SECTION (CPU_STATE (cpu)),
757
                                     asymbols,
758
                                     pc - STATE_TEXT_START (CPU_STATE (cpu)),
759
                                     &pc_filename, &pc_function, &pc_linenum))
760
            {
761
              char *p = buf;
762
              if (pc_linenum)
763
                {
764
                  sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum);
765
                  p += strlen (p);
766
                }
767
              else
768
                {
769
                  sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
770
                  p += SIZE_LINE_NUMBER+2;
771
                }
772
 
773
              if (pc_function)
774
                {
775
                  sprintf (p, "%s ", pc_function);
776
                  p += strlen (p);
777
                }
778
              else if (pc_filename)
779
                {
780
                  char *q = (char *) strrchr (pc_filename, '/');
781
                  sprintf (p, "%s ", (q) ? q+1 : pc_filename);
782
                  p += strlen (p);
783
                }
784
 
785
              if (*p == ' ')
786
                *p = '\0';
787
            }
788
        }
789
 
790
      sprintf (prefix, "0x%.*x %-*.*s ",
791
               SIZE_PC, (unsigned) pc,
792
               SIZE_LOCATION, SIZE_LOCATION, buf);
793
      chp = strchr (prefix, '\0');
794
      va_start (ap, fmt);
795
      vsprintf (chp, fmt, ap);
796
      va_end (ap);
797
    }
798
 
799
  /* Pad it out to TRACE_PREFIX_WIDTH.  */
800
  chp = strchr (prefix, '\0');
801
  if (chp - prefix < width)
802
    {
803
      memset (chp, ' ', width - (chp - prefix));
804
      chp = &prefix [width];
805
      *chp = '\0';
806
    }
807
  strcpy (chp, " -");
808
 
809
  /* check that we've not over flowed the prefix buffer */
810
  if (strlen (prefix) >= sizeof (TRACE_PREFIX (data)))
811
    abort ();
812
}
813
 
814
void
815
trace_generic (SIM_DESC sd,
816
               sim_cpu *cpu,
817
               int trace_idx,
818
               const char *fmt,
819
               ...)
820
{
821
  va_list ap;
822
  trace_printf (sd, cpu, "%s %s",
823
                trace_idx_to_str (trace_idx),
824
                TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
825
  va_start (ap, fmt);
826
  trace_vprintf (sd, cpu, fmt, ap);
827
  va_end (ap);
828
  trace_printf (sd, cpu, "\n");
829
}
830
 
831
void
832
trace_input0 (SIM_DESC sd,
833
              sim_cpu *cpu,
834
              int trace_idx)
835
{
836
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
837
  TRACE_IDX (data) = trace_idx;
838
}
839
 
840
void
841
trace_input_word1 (SIM_DESC sd,
842
                   sim_cpu *cpu,
843
                   int trace_idx,
844
                   unsigned_word d0)
845
{
846
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
847
  TRACE_IDX (data) = trace_idx;
848
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
849
}
850
 
851
void
852
trace_input_word2 (SIM_DESC sd,
853
                   sim_cpu *cpu,
854
                   int trace_idx,
855
                   unsigned_word d0,
856
                   unsigned_word d1)
857
{
858
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
859
  TRACE_IDX (data) = trace_idx;
860
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
861
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
862
}
863
 
864
void
865
trace_input_word3 (SIM_DESC sd,
866
                   sim_cpu *cpu,
867
                   int trace_idx,
868
                   unsigned_word d0,
869
                   unsigned_word d1,
870
                   unsigned_word d2)
871
{
872
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
873
  TRACE_IDX (data) = trace_idx;
874
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
875
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
876
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2);
877
}
878
 
879
void
880
trace_input_word4 (SIM_DESC sd,
881
                   sim_cpu *cpu,
882
                   int trace_idx,
883
                   unsigned_word d0,
884
                   unsigned_word d1,
885
                   unsigned_word d2,
886
                   unsigned_word d3)
887
{
888
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
889
  TRACE_IDX (data) = trace_idx;
890
  save_data (sd, data, trace_fmt_word, sizeof (d0), &d0);
891
  save_data (sd, data, trace_fmt_word, sizeof (d1), &d1);
892
  save_data (sd, data, trace_fmt_word, sizeof (d2), &d2);
893
  save_data (sd, data, trace_fmt_word, sizeof (d3), &d3);
894
}
895
 
896
void
897
trace_input_bool1 (SIM_DESC sd,
898
                   sim_cpu *cpu,
899
                   int trace_idx,
900
                   int d0)
901
{
902
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
903
  TRACE_IDX (data) = trace_idx;
904
  save_data (sd, data, trace_fmt_bool, sizeof (d0), &d0);
905
}
906
 
907
void
908
trace_input_addr1 (SIM_DESC sd,
909
                   sim_cpu *cpu,
910
                   int trace_idx,
911
                   address_word d0)
912
{
913
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
914
  TRACE_IDX (data) = trace_idx;
915
  save_data (sd, data, trace_fmt_addr, sizeof (d0), &d0);
916
}
917
 
918
void
919
trace_input_fp1 (SIM_DESC sd,
920
                 sim_cpu *cpu,
921
                 int trace_idx,
922
                 fp_word f0)
923
{
924
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
925
  TRACE_IDX (data) = trace_idx;
926
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
927
}
928
 
929
void
930
trace_input_fp2 (SIM_DESC sd,
931
                 sim_cpu *cpu,
932
                 int trace_idx,
933
                 fp_word f0,
934
                 fp_word f1)
935
{
936
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
937
  TRACE_IDX (data) = trace_idx;
938
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
939
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
940
}
941
 
942
void
943
trace_input_fp3 (SIM_DESC sd,
944
                 sim_cpu *cpu,
945
                 int trace_idx,
946
                 fp_word f0,
947
                 fp_word f1,
948
                 fp_word f2)
949
{
950
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
951
  TRACE_IDX (data) = trace_idx;
952
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
953
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
954
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f2);
955
}
956
 
957
void
958
trace_input_fpu1 (SIM_DESC sd,
959
                  sim_cpu *cpu,
960
                  int trace_idx,
961
                  sim_fpu *f0)
962
{
963
  double d;
964
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
965
  TRACE_IDX (data) = trace_idx;
966
  d = sim_fpu_2d (f0);
967
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
968
}
969
 
970
void
971
trace_input_fpu2 (SIM_DESC sd,
972
                  sim_cpu *cpu,
973
                  int trace_idx,
974
                  sim_fpu *f0,
975
                  sim_fpu *f1)
976
{
977
  double d;
978
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
979
  TRACE_IDX (data) = trace_idx;
980
  d = sim_fpu_2d (f0);
981
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
982
  d = sim_fpu_2d (f1);
983
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
984
}
985
 
986
void
987
trace_input_fpu3 (SIM_DESC sd,
988
                  sim_cpu *cpu,
989
                  int trace_idx,
990
                  sim_fpu *f0,
991
                  sim_fpu *f1,
992
                  sim_fpu *f2)
993
{
994
  double d;
995
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
996
  TRACE_IDX (data) = trace_idx;
997
  d = sim_fpu_2d (f0);
998
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
999
  d = sim_fpu_2d (f1);
1000
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1001
  d = sim_fpu_2d (f2);
1002
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1003
}
1004
 
1005
void
1006
trace_result_word1 (SIM_DESC sd,
1007
                    sim_cpu *cpu,
1008
                    int trace_idx,
1009
                    unsigned_word r0)
1010
{
1011
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1012
  int last_input;
1013
 
1014
  /* Append any results to the end of the inputs */
1015
  last_input = TRACE_INPUT_IDX (data);
1016
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1017
 
1018
  trace_results (sd, cpu, trace_idx, last_input);
1019
}
1020
 
1021
void
1022
trace_result0 (SIM_DESC sd,
1023
               sim_cpu *cpu,
1024
               int trace_idx)
1025
{
1026
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1027
  int last_input;
1028
 
1029
  /* Append any results to the end of the inputs */
1030
  last_input = TRACE_INPUT_IDX (data);
1031
 
1032
  trace_results (sd, cpu, trace_idx, last_input);
1033
}
1034
 
1035
void
1036
trace_result_word2 (SIM_DESC sd,
1037
                    sim_cpu *cpu,
1038
                    int trace_idx,
1039
                    unsigned_word r0,
1040
                    unsigned_word r1)
1041
{
1042
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1043
  int last_input;
1044
 
1045
  /* Append any results to the end of the inputs */
1046
  last_input = TRACE_INPUT_IDX (data);
1047
  save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1048
  save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1049
 
1050
  trace_results (sd, cpu, trace_idx, last_input);
1051
}
1052
 
1053
void
1054
trace_result_word4 (SIM_DESC sd,
1055
                    sim_cpu *cpu,
1056
                    int trace_idx,
1057
                    unsigned_word r0,
1058
                    unsigned_word r1,
1059
                    unsigned_word r2,
1060
                    unsigned_word r3)
1061
{
1062
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1063
  int last_input;
1064
 
1065
  /* Append any results to the end of the inputs */
1066
  last_input = TRACE_INPUT_IDX (data);
1067
  save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1068
  save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1069
  save_data (sd, data, trace_fmt_word, sizeof (r2), &r2);
1070
  save_data (sd, data, trace_fmt_word, sizeof (r3), &r3);
1071
 
1072
  trace_results (sd, cpu, trace_idx, last_input);
1073
}
1074
 
1075
void
1076
trace_result_bool1 (SIM_DESC sd,
1077
                    sim_cpu *cpu,
1078
                    int trace_idx,
1079
                    int r0)
1080
{
1081
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1082
  int last_input;
1083
 
1084
  /* Append any results to the end of the inputs */
1085
  last_input = TRACE_INPUT_IDX (data);
1086
  save_data (sd, data, trace_fmt_bool, sizeof (r0), &r0);
1087
 
1088
  trace_results (sd, cpu, trace_idx, last_input);
1089
}
1090
 
1091
void
1092
trace_result_addr1 (SIM_DESC sd,
1093
                    sim_cpu *cpu,
1094
                    int trace_idx,
1095
                    address_word r0)
1096
{
1097
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1098
  int last_input;
1099
 
1100
  /* Append any results to the end of the inputs */
1101
  last_input = TRACE_INPUT_IDX (data);
1102
  save_data (sd, data, trace_fmt_addr, sizeof (r0), &r0);
1103
 
1104
  trace_results (sd, cpu, trace_idx, last_input);
1105
}
1106
 
1107
void
1108
trace_result_fp1 (SIM_DESC sd,
1109
                  sim_cpu *cpu,
1110
                  int trace_idx,
1111
                  fp_word f0)
1112
{
1113
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1114
  int last_input;
1115
 
1116
  /* Append any results to the end of the inputs */
1117
  last_input = TRACE_INPUT_IDX (data);
1118
  save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1119
 
1120
  trace_results (sd, cpu, trace_idx, last_input);
1121
}
1122
 
1123
void
1124
trace_result_fp2 (SIM_DESC sd,
1125
                  sim_cpu *cpu,
1126
                  int trace_idx,
1127
                  fp_word f0,
1128
                  fp_word f1)
1129
{
1130
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1131
  int last_input;
1132
 
1133
  /* Append any results to the end of the inputs */
1134
  last_input = TRACE_INPUT_IDX (data);
1135
  save_data (sd, data, trace_fmt_fp, sizeof (f0), &f0);
1136
  save_data (sd, data, trace_fmt_fp, sizeof (f1), &f1);
1137
 
1138
  trace_results (sd, cpu, trace_idx, last_input);
1139
}
1140
 
1141
void
1142
trace_result_fpu1 (SIM_DESC sd,
1143
                   sim_cpu *cpu,
1144
                   int trace_idx,
1145
                   sim_fpu *f0)
1146
{
1147
  double d;
1148
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1149
  int last_input;
1150
 
1151
  /* Append any results to the end of the inputs */
1152
  last_input = TRACE_INPUT_IDX (data);
1153
  d = sim_fpu_2d (f0);
1154
  save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1155
 
1156
  trace_results (sd, cpu, trace_idx, last_input);
1157
}
1158
 
1159
void
1160
trace_result_string1 (SIM_DESC sd,
1161
                      sim_cpu *cpu,
1162
                      int trace_idx,
1163
                      char *s0)
1164
{
1165
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1166
  int last_input;
1167
 
1168
  /* Append any results to the end of the inputs */
1169
  last_input = TRACE_INPUT_IDX (data);
1170
  save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1171
 
1172
  trace_results (sd, cpu, trace_idx, last_input);
1173
}
1174
 
1175
void
1176
trace_result_word1_string1 (SIM_DESC sd,
1177
                            sim_cpu *cpu,
1178
                            int trace_idx,
1179
                            unsigned_word r0,
1180
                            char *s0)
1181
{
1182
  TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1183
  int last_input;
1184
 
1185
  /* Append any results to the end of the inputs */
1186
  last_input = TRACE_INPUT_IDX (data);
1187
  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1188
  save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1189
 
1190
  trace_results (sd, cpu, trace_idx, last_input);
1191
}
1192
 
1193
void
1194
trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap)
1195
{
1196
  if (cpu != NULL)
1197
    {
1198
      if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL)
1199
        vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap);
1200
      else
1201
        sim_io_evprintf (sd, fmt, ap);
1202
    }
1203
  else
1204
    {
1205
      if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL)
1206
        vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap);
1207
      else
1208
        sim_io_evprintf (sd, fmt, ap);
1209
    }
1210
}
1211
 
1212
/* The function trace_one_insn has been replaced by the function pair
1213
   trace_prefix() + trace_generic().  It is still used. */
1214
void
1215
trace_one_insn (SIM_DESC sd, sim_cpu *cpu, address_word pc,
1216
                int line_p, const char *filename, int linenum,
1217
                const char *phase_wo_colon, const char *fmt,
1218
                ...)
1219
{
1220
  va_list ap;
1221
  char phase[SIZE_PHASE+2];
1222
 
1223
  strncpy (phase, phase_wo_colon, SIZE_PHASE);
1224
  strcat (phase, ":");
1225
 
1226
  if (!line_p)
1227
    {
1228
      trace_printf (sd, cpu, "%-*s %s:%-*d 0x%.*lx ",
1229
                    SIZE_PHASE+1, phase,
1230
                    filename,
1231
                    SIZE_LINE_NUMBER, linenum,
1232
                    SIZE_PC, (long)pc);
1233
      va_start (ap, fmt);
1234
      trace_vprintf (sd, cpu, fmt, ap);
1235
      va_end (ap);
1236
      trace_printf (sd, cpu, "\n");
1237
    }
1238
  else
1239
    {
1240
      char buf[256];
1241
 
1242
      buf[0] = 0;
1243
      if (STATE_TEXT_SECTION (CPU_STATE (cpu))
1244
          && pc >= STATE_TEXT_START (CPU_STATE (cpu))
1245
          && pc < STATE_TEXT_END (CPU_STATE (cpu)))
1246
        {
1247
          const char *pc_filename = (const char *)0;
1248
          const char *pc_function = (const char *)0;
1249
          unsigned int pc_linenum = 0;
1250
 
1251
          if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu)),
1252
                                     STATE_TEXT_SECTION (CPU_STATE (cpu)),
1253
                                     (struct symbol_cache_entry **) 0,
1254
                                     pc - STATE_TEXT_START (CPU_STATE (cpu)),
1255
                                     &pc_filename, &pc_function, &pc_linenum))
1256
            {
1257
              char *p = buf;
1258
              if (pc_linenum)
1259
                {
1260
                  sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum);
1261
                  p += strlen (p);
1262
                }
1263
              else
1264
                {
1265
                  sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
1266
                  p += SIZE_LINE_NUMBER+2;
1267
                }
1268
 
1269
              if (pc_function)
1270
                {
1271
                  sprintf (p, "%s ", pc_function);
1272
                  p += strlen (p);
1273
                }
1274
              else if (pc_filename)
1275
                {
1276
                  char *q = (char *) strrchr (pc_filename, '/');
1277
                  sprintf (p, "%s ", (q) ? q+1 : pc_filename);
1278
                  p += strlen (p);
1279
                }
1280
 
1281
              if (*p == ' ')
1282
                *p = '\0';
1283
            }
1284
        }
1285
 
1286
      trace_printf (sd, cpu, "%-*s 0x%.*x %-*.*s ",
1287
                    SIZE_PHASE+1, phase,
1288
                    SIZE_PC, (unsigned) pc,
1289
                    SIZE_LOCATION, SIZE_LOCATION, buf);
1290
      va_start (ap, fmt);
1291
      trace_vprintf (sd, cpu, fmt, ap);
1292
      va_end (ap);
1293
      trace_printf (sd, cpu, "\n");
1294
    }
1295
}
1296
 
1297
void
1298
trace_printf VPARAMS ((SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...))
1299
{
1300
#if !defined __STDC__ && !defined ALMOST_STDC
1301
  SIM_DESC sd;
1302
  sim_cpu *cpu;
1303
  const char *fmt;
1304
#endif
1305
  va_list ap;
1306
 
1307
  VA_START (ap, fmt);
1308
#if !defined __STDC__ && !defined ALMOST_STDC
1309
  sd = va_arg (ap, SIM_DESC);
1310
  cpu = va_arg (ap, sim_cpu *);
1311
  fmt = va_arg (ap, const char *);
1312
#endif
1313
 
1314
  trace_vprintf (sd, cpu, fmt, ap);
1315
 
1316
  va_end (ap);
1317
}
1318
 
1319
void
1320
debug_printf VPARAMS ((sim_cpu *cpu, const char *fmt, ...))
1321
{
1322
#if !defined __STDC__ && !defined ALMOST_STDC
1323
  sim_cpu *cpu;
1324
  const char *fmt;
1325
#endif
1326
  va_list ap;
1327
 
1328
  VA_START (ap, fmt);
1329
#if !defined __STDC__ && !defined ALMOST_STDC
1330
  cpu = va_arg (ap, sim_cpu *);
1331
  fmt = va_arg (ap, const char *);
1332
#endif
1333
 
1334
  if (CPU_DEBUG_FILE (cpu) == NULL)
1335
    (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
1336
      (STATE_CALLBACK (CPU_STATE (cpu)), fmt, ap);
1337
  else
1338
    vfprintf (CPU_DEBUG_FILE (cpu), fmt, ap);
1339
 
1340
  va_end (ap);
1341
}

powered by: WebSVN 2.1.0

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