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