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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [common/] [sim-trace.c] - Blame information for rev 855

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

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

powered by: WebSVN 2.1.0

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