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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [common/] [sim-trace.c] - Blame information for rev 309

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

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

powered by: WebSVN 2.1.0

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