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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [common/] [sim-trace.c] - Blame information for rev 868

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

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

powered by: WebSVN 2.1.0

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