Home | History | Annotate | Line # | Download | only in common
sim-trace.c revision 1.1.1.7
      1      1.1  christos /* Simulator tracing/debugging support.
      2  1.1.1.7  christos    Copyright (C) 1997-2017 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.1.7  christos     }
    514  1.1.1.7  christos 
    515  1.1.1.7  christos   if (STATE_PROG_SYMS (sd))
    516      1.1  christos     free (STATE_PROG_SYMS (sd));
    517      1.1  christos }
    518      1.1  christos 
    519      1.1  christos /* compute the nr of trace data units consumed by data */
    521      1.1  christos static int
    522      1.1  christos save_data_size (TRACE_DATA *data,
    523      1.1  christos 		long size)
    524      1.1  christos {
    525      1.1  christos   return ((size + sizeof (TRACE_INPUT_DATA (data) [0]) - 1)
    526      1.1  christos 	  / sizeof (TRACE_INPUT_DATA (data) [0]));
    527      1.1  christos }
    528      1.1  christos 
    529  1.1.1.2  christos 
    530      1.1  christos /* Archive DATA into the trace buffer */
    531      1.1  christos void
    532      1.1  christos save_data (SIM_DESC sd,
    533      1.1  christos 	   TRACE_DATA *data,
    534      1.1  christos 	   data_fmt fmt,
    535      1.1  christos 	   long size,
    536      1.1  christos 	   const void *buf)
    537      1.1  christos {
    538      1.1  christos   int i = TRACE_INPUT_IDX (data);
    539      1.1  christos   if (i == sizeof (TRACE_INPUT_FMT (data)))
    540      1.1  christos     sim_io_error (sd, "trace buffer overflow");
    541      1.1  christos   TRACE_INPUT_FMT (data) [i] = fmt;
    542      1.1  christos   TRACE_INPUT_SIZE (data) [i] = size;
    543      1.1  christos   memcpy (&TRACE_INPUT_DATA (data) [i], buf, size);
    544      1.1  christos   i += save_data_size (data, size);
    545      1.1  christos   TRACE_INPUT_IDX (data) = i;
    546      1.1  christos }
    547      1.1  christos 
    548      1.1  christos static void
    549      1.1  christos print_data (SIM_DESC sd,
    550      1.1  christos 	    sim_cpu *cpu,
    551      1.1  christos 	    data_fmt fmt,
    552      1.1  christos 	    long size,
    553      1.1  christos 	    void *data)
    554      1.1  christos {
    555      1.1  christos   switch (fmt)
    556      1.1  christos     {
    557      1.1  christos     case trace_fmt_instruction_incomplete:
    558      1.1  christos       trace_printf (sd, cpu, " (instruction incomplete)");
    559      1.1  christos       break;
    560      1.1  christos     case trace_fmt_word:
    561      1.1  christos     case trace_fmt_addr:
    562      1.1  christos       {
    563      1.1  christos 	switch (size)
    564      1.1  christos 	  {
    565      1.1  christos 	  case sizeof (unsigned32):
    566      1.1  christos 	    trace_printf (sd, cpu, " 0x%08lx", (long) * (unsigned32*) data);
    567      1.1  christos 	    break;
    568      1.1  christos 	  case sizeof (unsigned64):
    569      1.1  christos 	    trace_printf (sd, cpu, " 0x%08lx%08lx",
    570      1.1  christos 			  (long) ((* (unsigned64*) data) >> 32),
    571      1.1  christos 			  (long) * (unsigned64*) data);
    572      1.1  christos 	    break;
    573      1.1  christos 	  default:
    574      1.1  christos 	    abort ();
    575      1.1  christos 	  }
    576      1.1  christos 	break;
    577      1.1  christos       }
    578      1.1  christos     case trace_fmt_bool:
    579      1.1  christos       {
    580      1.1  christos 	SIM_ASSERT (size == sizeof (int));
    581      1.1  christos 	trace_printf (sd, cpu, " %-8s",
    582      1.1  christos 		      (* (int*) data) ? "true" : "false");
    583      1.1  christos 	break;
    584      1.1  christos       }
    585      1.1  christos     case trace_fmt_fp:
    586      1.1  christos       {
    587      1.1  christos 	sim_fpu fp;
    588      1.1  christos 	switch (size)
    589      1.1  christos 	  {
    590      1.1  christos 	    /* FIXME: Assumes sizeof float == 4; sizeof double == 8 */
    591      1.1  christos 	  case 4:
    592      1.1  christos 	    sim_fpu_32to (&fp, *(unsigned32*)data);
    593      1.1  christos 	    break;
    594      1.1  christos 	  case 8:
    595      1.1  christos 	    sim_fpu_64to (&fp, *(unsigned64*)data);
    596      1.1  christos 	    break;
    597      1.1  christos 	  default:
    598      1.1  christos 	    abort ();
    599      1.1  christos 	  }
    600      1.1  christos 	trace_printf (sd, cpu, " %8g", sim_fpu_2d (&fp));
    601      1.1  christos 	switch (size)
    602      1.1  christos 	  {
    603      1.1  christos 	  case 4:
    604      1.1  christos 	    trace_printf (sd, cpu, " (0x%08lx)",
    605      1.1  christos 			  (long) *(unsigned32*)data);
    606      1.1  christos 	    break;
    607      1.1  christos 	  case 8:
    608      1.1  christos 	    trace_printf (sd, cpu, " (0x%08lx%08lx)",
    609      1.1  christos 			  (long) (*(unsigned64*)data >> 32),
    610      1.1  christos 			  (long) (*(unsigned64*)data));
    611      1.1  christos 	    break;
    612      1.1  christos 	  default:
    613      1.1  christos 	    abort ();
    614      1.1  christos 	  }
    615      1.1  christos 	break;
    616      1.1  christos       }
    617      1.1  christos     case trace_fmt_fpu:
    618      1.1  christos       /* FIXME: At present sim_fpu data is stored as a double */
    619      1.1  christos       trace_printf (sd, cpu, " %8g", * (double*) data);
    620      1.1  christos       break;
    621      1.1  christos     case trace_fmt_string:
    622      1.1  christos       trace_printf (sd, cpu, " %-8s", (char*) data);
    623      1.1  christos       break;
    624      1.1  christos     default:
    625      1.1  christos       abort ();
    626      1.1  christos     }
    627      1.1  christos }
    628      1.1  christos 
    629      1.1  christos static const char *
    630      1.1  christos trace_idx_to_str (int trace_idx)
    631      1.1  christos {
    632      1.1  christos   static char num[8];
    633  1.1.1.5  christos   switch (trace_idx)
    634  1.1.1.5  christos     {
    635  1.1.1.6  christos     case TRACE_ALU_IDX:      return "alu:     ";
    636  1.1.1.5  christos     case TRACE_INSN_IDX:     return "insn:    ";
    637  1.1.1.5  christos     case TRACE_DISASM_IDX:   return "disasm:  ";
    638  1.1.1.5  christos     case TRACE_DECODE_IDX:   return "decode:  ";
    639  1.1.1.5  christos     case TRACE_EXTRACT_IDX:  return "extract: ";
    640  1.1.1.5  christos     case TRACE_MEMORY_IDX:   return "memory:  ";
    641  1.1.1.5  christos     case TRACE_CORE_IDX:     return "core:    ";
    642  1.1.1.5  christos     case TRACE_EVENTS_IDX:   return "events:  ";
    643  1.1.1.5  christos     case TRACE_FPU_IDX:      return "fpu:     ";
    644  1.1.1.5  christos     case TRACE_BRANCH_IDX:   return "branch:  ";
    645  1.1.1.5  christos     case TRACE_SYSCALL_IDX:  return "syscall: ";
    646      1.1  christos     case TRACE_REGISTER_IDX: return "reg:     ";
    647      1.1  christos     case TRACE_VPU_IDX:      return "vpu:     ";
    648      1.1  christos     default:
    649      1.1  christos       sprintf (num, "?%d?", trace_idx);
    650      1.1  christos       return num;
    651      1.1  christos     }
    652      1.1  christos }
    653      1.1  christos 
    654      1.1  christos static void
    655      1.1  christos trace_results (SIM_DESC sd,
    656      1.1  christos 	       sim_cpu *cpu,
    657      1.1  christos 	       int trace_idx,
    658      1.1  christos 	       int last_input)
    659      1.1  christos {
    660      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    661      1.1  christos   int nr_out;
    662      1.1  christos   int i;
    663      1.1  christos 
    664      1.1  christos   /* cross check trace_idx against TRACE_IDX (data)? */
    665      1.1  christos 
    666      1.1  christos   /* prefix */
    667      1.1  christos   trace_printf (sd, cpu, "%s %s",
    668      1.1  christos 		trace_idx_to_str (TRACE_IDX (data)),
    669      1.1  christos 		TRACE_PREFIX (data));
    670      1.1  christos   TRACE_IDX (data) = 0;
    671      1.1  christos 
    672      1.1  christos   for (i = 0, nr_out = 0;
    673      1.1  christos        i < TRACE_INPUT_IDX (data);
    674      1.1  christos        i += save_data_size (data, TRACE_INPUT_SIZE (data) [i]), nr_out++)
    675      1.1  christos     {
    676      1.1  christos       if (i == last_input)
    677      1.1  christos 	{
    678      1.1  christos 	  int pad = (strlen (" 0x") + sizeof (unsigned_word) * 2);
    679      1.1  christos 	  int padding = pad * (3 - nr_out);
    680      1.1  christos 	  if (padding < 0)
    681      1.1  christos 	    padding = 0;
    682      1.1  christos 	  padding += strlen (" ::");
    683      1.1  christos 	  trace_printf (sd, cpu, "%*s", padding, " ::");
    684      1.1  christos 	}
    685      1.1  christos       print_data (sd, cpu,
    686      1.1  christos 		  TRACE_INPUT_FMT (data) [i],
    687      1.1  christos 		  TRACE_INPUT_SIZE (data) [i],
    688      1.1  christos 		  &TRACE_INPUT_DATA (data) [i]);
    689      1.1  christos     }
    690      1.1  christos   trace_printf (sd, cpu, "\n");
    691  1.1.1.7  christos }
    692  1.1.1.7  christos 
    693  1.1.1.7  christos int
    694  1.1.1.7  christos trace_load_symbols (SIM_DESC sd)
    695  1.1.1.7  christos {
    696  1.1.1.7  christos   bfd *abfd;
    697  1.1.1.7  christos   asymbol **asymbols;
    698  1.1.1.7  christos   long symsize;
    699  1.1.1.7  christos   long symbol_count;
    700  1.1.1.7  christos 
    701  1.1.1.7  christos   /* Already loaded, so nothing to do.  */
    702  1.1.1.7  christos   if (STATE_PROG_SYMS (sd))
    703  1.1.1.7  christos     return 1;
    704  1.1.1.7  christos 
    705  1.1.1.7  christos   abfd = STATE_PROG_BFD (sd);
    706  1.1.1.7  christos   if (abfd == NULL)
    707  1.1.1.7  christos     return 0;
    708  1.1.1.7  christos 
    709  1.1.1.7  christos   symsize = bfd_get_symtab_upper_bound (abfd);
    710  1.1.1.7  christos   if (symsize < 0)
    711  1.1.1.7  christos     return 0;
    712  1.1.1.7  christos 
    713  1.1.1.7  christos   asymbols = xmalloc (symsize);
    714  1.1.1.7  christos   symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
    715  1.1.1.7  christos   if (symbol_count < 0)
    716  1.1.1.7  christos     {
    717  1.1.1.7  christos       free (asymbols);
    718  1.1.1.7  christos       return 0;
    719  1.1.1.7  christos     }
    720  1.1.1.7  christos 
    721  1.1.1.7  christos   STATE_PROG_SYMS (sd) = asymbols;
    722  1.1.1.7  christos   STATE_PROG_SYMS_COUNT (sd) = symbol_count;
    723  1.1.1.7  christos   return 1;
    724  1.1.1.7  christos }
    725  1.1.1.7  christos 
    726  1.1.1.7  christos bfd_vma
    727  1.1.1.7  christos trace_sym_value (SIM_DESC sd, const char *name)
    728  1.1.1.7  christos {
    729  1.1.1.7  christos   asymbol **asymbols;
    730  1.1.1.7  christos   long i;
    731  1.1.1.7  christos 
    732  1.1.1.7  christos   if (!trace_load_symbols (sd))
    733  1.1.1.7  christos     return -1;
    734  1.1.1.7  christos 
    735  1.1.1.7  christos   asymbols = STATE_PROG_SYMS (sd);
    736  1.1.1.7  christos 
    737  1.1.1.7  christos   for (i = 0; i < STATE_PROG_SYMS_COUNT (sd); ++i)
    738  1.1.1.7  christos     if (strcmp (asymbols[i]->name, name) == 0)
    739  1.1.1.7  christos       return bfd_asymbol_value (asymbols[i]);
    740  1.1.1.7  christos 
    741  1.1.1.7  christos   return -1;
    742      1.1  christos }
    743      1.1  christos 
    744      1.1  christos void
    745      1.1  christos trace_prefix (SIM_DESC sd,
    746      1.1  christos 	      sim_cpu *cpu,
    747      1.1  christos 	      sim_cia cia,
    748      1.1  christos 	      address_word pc,
    749      1.1  christos 	      int line_p,
    750      1.1  christos 	      const char *filename,
    751      1.1  christos 	      int linenum,
    752      1.1  christos 	      const char *fmt,
    753      1.1  christos 	      ...)
    754      1.1  christos {
    755      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    756      1.1  christos   va_list ap;
    757      1.1  christos   char *prefix = TRACE_PREFIX (data);
    758      1.1  christos   char *chp;
    759      1.1  christos  /* FIXME: The TRACE_PREFIX_WIDTH should be determined at build time using
    760      1.1  christos     known information about the disassembled instructions. */
    761      1.1  christos #ifndef TRACE_PREFIX_WIDTH
    762      1.1  christos #define TRACE_PREFIX_WIDTH 48
    763      1.1  christos #endif
    764      1.1  christos   int width = TRACE_PREFIX_WIDTH;
    765      1.1  christos 
    766      1.1  christos   /* if the previous trace data wasn't flushed, flush it now with a
    767      1.1  christos      note indicating that the trace was incomplete. */
    768      1.1  christos   if (TRACE_IDX (data) != 0)
    769      1.1  christos     {
    770      1.1  christos       int last_input = TRACE_INPUT_IDX (data);
    771      1.1  christos       save_data (sd, data, trace_fmt_instruction_incomplete, 1, "");
    772      1.1  christos       trace_results (sd, cpu, TRACE_IDX (data), last_input);
    773      1.1  christos     }
    774      1.1  christos   TRACE_IDX (data) = 0;
    775      1.1  christos   TRACE_INPUT_IDX (data) = 0;
    776      1.1  christos 
    777      1.1  christos   /* Create the text prefix for this new instruction: */
    778      1.1  christos   if (!line_p)
    779      1.1  christos     {
    780      1.1  christos       if (filename)
    781      1.1  christos 	{
    782      1.1  christos 	  sprintf (prefix, "%s:%-*d 0x%.*lx ",
    783      1.1  christos 		   filename,
    784      1.1  christos 		   SIZE_LINE_NUMBER, linenum,
    785      1.1  christos 		   SIZE_PC, (long) pc);
    786      1.1  christos 	}
    787      1.1  christos       else
    788      1.1  christos 	{
    789      1.1  christos 	  sprintf (prefix, "0x%.*lx ",
    790      1.1  christos 		   SIZE_PC, (long) pc);
    791      1.1  christos 	  /* Shrink the width by the amount that we didn't print.  */
    792      1.1  christos 	  width -= SIZE_LINE_NUMBER + SIZE_PC + 8;
    793      1.1  christos 	}
    794      1.1  christos       chp = strchr (prefix, '\0');
    795      1.1  christos       va_start (ap, fmt);
    796      1.1  christos       vsprintf (chp, fmt, ap);
    797      1.1  christos       va_end (ap);
    798      1.1  christos     }
    799      1.1  christos   else
    800      1.1  christos     {
    801  1.1.1.7  christos       char buf[256];
    802  1.1.1.7  christos       buf[0] = 0;
    803  1.1.1.7  christos       if (STATE_TEXT_SECTION (sd)
    804      1.1  christos 	  && pc >= STATE_TEXT_START (sd)
    805      1.1  christos 	  && pc < STATE_TEXT_END (sd))
    806      1.1  christos 	{
    807      1.1  christos 	  const char *pc_filename = (const char *)0;
    808      1.1  christos 	  const char *pc_function = (const char *)0;
    809      1.1  christos 	  unsigned int pc_linenum = 0;
    810      1.1  christos 	  bfd *abfd;
    811  1.1.1.7  christos 	  asymbol **asymbols;
    812  1.1.1.7  christos 
    813      1.1  christos 	  if (!trace_load_symbols (sd))
    814  1.1.1.7  christos 	    sim_engine_abort (sd, cpu, cia, "could not load symbols");
    815  1.1.1.7  christos 
    816      1.1  christos 	  abfd = STATE_PROG_BFD (sd);
    817  1.1.1.7  christos 	  asymbols = STATE_PROG_SYMS (sd);
    818  1.1.1.7  christos 
    819      1.1  christos 	  if (bfd_find_nearest_line (abfd, STATE_TEXT_SECTION (sd), asymbols,
    820      1.1  christos 				     pc - STATE_TEXT_START (sd),
    821      1.1  christos 				     &pc_filename, &pc_function, &pc_linenum))
    822      1.1  christos 	    {
    823      1.1  christos 	      char *p = buf;
    824      1.1  christos 	      if (pc_linenum)
    825      1.1  christos 		{
    826      1.1  christos 		  sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum);
    827      1.1  christos 		  p += strlen (p);
    828      1.1  christos 		}
    829      1.1  christos 	      else
    830      1.1  christos 		{
    831      1.1  christos 		  sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
    832      1.1  christos 		  p += SIZE_LINE_NUMBER+2;
    833      1.1  christos 		}
    834      1.1  christos 
    835      1.1  christos 	      if (pc_function)
    836      1.1  christos 		{
    837      1.1  christos 		  sprintf (p, "%s ", pc_function);
    838      1.1  christos 		  p += strlen (p);
    839      1.1  christos 		}
    840      1.1  christos 	      else if (pc_filename)
    841      1.1  christos 		{
    842      1.1  christos 		  char *q = (char *) strrchr (pc_filename, '/');
    843      1.1  christos 		  sprintf (p, "%s ", (q) ? q+1 : pc_filename);
    844      1.1  christos 		  p += strlen (p);
    845      1.1  christos 		}
    846      1.1  christos 
    847      1.1  christos 	      if (*p == ' ')
    848      1.1  christos 		*p = '\0';
    849      1.1  christos 	    }
    850      1.1  christos 	}
    851      1.1  christos 
    852      1.1  christos       sprintf (prefix, "0x%.*x %-*.*s ",
    853      1.1  christos 	       SIZE_PC, (unsigned) pc,
    854      1.1  christos 	       SIZE_LOCATION, SIZE_LOCATION, buf);
    855      1.1  christos       chp = strchr (prefix, '\0');
    856      1.1  christos       va_start (ap, fmt);
    857      1.1  christos       vsprintf (chp, fmt, ap);
    858      1.1  christos       va_end (ap);
    859      1.1  christos     }
    860      1.1  christos 
    861      1.1  christos   /* Pad it out to TRACE_PREFIX_WIDTH.  */
    862      1.1  christos   chp = strchr (prefix, '\0');
    863      1.1  christos   if (chp - prefix < width)
    864      1.1  christos     {
    865      1.1  christos       memset (chp, ' ', width - (chp - prefix));
    866      1.1  christos       chp = &prefix [width];
    867      1.1  christos       *chp = '\0';
    868      1.1  christos     }
    869      1.1  christos   strcpy (chp, " -");
    870      1.1  christos 
    871      1.1  christos   /* check that we've not over flowed the prefix buffer */
    872      1.1  christos   if (strlen (prefix) >= sizeof (TRACE_PREFIX (data)))
    873      1.1  christos     abort ();
    874      1.1  christos }
    875      1.1  christos 
    876      1.1  christos void
    877      1.1  christos trace_generic (SIM_DESC sd,
    878      1.1  christos 	       sim_cpu *cpu,
    879      1.1  christos 	       int trace_idx,
    880      1.1  christos 	       const char *fmt,
    881      1.1  christos 	       ...)
    882      1.1  christos {
    883      1.1  christos   va_list ap;
    884      1.1  christos   trace_printf (sd, cpu, "%s %s",
    885      1.1  christos 		trace_idx_to_str (trace_idx),
    886      1.1  christos 		TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
    887      1.1  christos   va_start (ap, fmt);
    888      1.1  christos   trace_vprintf (sd, cpu, fmt, ap);
    889      1.1  christos   va_end (ap);
    890      1.1  christos   trace_printf (sd, cpu, "\n");
    891  1.1.1.6  christos }
    892  1.1.1.6  christos 
    893  1.1.1.6  christos static int
    894  1.1.1.6  christos dis_read (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
    895  1.1.1.6  christos 	  struct disassemble_info *dinfo)
    896  1.1.1.6  christos {
    897  1.1.1.6  christos   SIM_CPU *cpu = dinfo->application_data;
    898  1.1.1.6  christos   sim_core_read_buffer (CPU_STATE (cpu), cpu, NULL_CIA, myaddr, memaddr, length);
    899  1.1.1.6  christos   return 0;
    900  1.1.1.6  christos }
    901  1.1.1.6  christos 
    902  1.1.1.6  christos static int
    903  1.1.1.6  christos dis_printf (SIM_CPU *cpu, const char *fmt, ...)
    904  1.1.1.6  christos {
    905  1.1.1.6  christos   SIM_DESC sd = CPU_STATE (cpu);
    906  1.1.1.6  christos   va_list ap;
    907  1.1.1.6  christos   va_start (ap, fmt);
    908  1.1.1.6  christos   trace_vprintf (sd, cpu, fmt, ap);
    909  1.1.1.6  christos   va_end (ap);
    910  1.1.1.6  christos   return 0;
    911  1.1.1.6  christos }
    912  1.1.1.6  christos 
    913  1.1.1.6  christos void
    914  1.1.1.6  christos trace_disasm (SIM_DESC sd, sim_cpu *cpu, address_word addr)
    915  1.1.1.6  christos {
    916  1.1.1.6  christos   struct bfd *bfd = STATE_PROG_BFD (sd);
    917  1.1.1.6  christos   TRACE_DATA *trace_data = CPU_TRACE_DATA (cpu);
    918  1.1.1.6  christos   disassemble_info *info = &trace_data->dis_info;
    919  1.1.1.6  christos 
    920  1.1.1.6  christos   /* See if we need to set up the disassembly func.  */
    921  1.1.1.6  christos   if (trace_data->dis_bfd != bfd)
    922  1.1.1.6  christos     {
    923  1.1.1.6  christos       trace_data->dis_bfd = bfd;
    924  1.1.1.6  christos       trace_data->disassembler = disassembler (trace_data->dis_bfd);
    925  1.1.1.6  christos       INIT_DISASSEMBLE_INFO (*info, cpu, dis_printf);
    926  1.1.1.6  christos       info->read_memory_func = dis_read;
    927  1.1.1.6  christos       info->arch = bfd_get_arch (bfd);
    928  1.1.1.6  christos       info->mach = bfd_get_mach (bfd);
    929  1.1.1.6  christos       disassemble_init_for_target (info);
    930  1.1.1.6  christos     }
    931  1.1.1.6  christos 
    932  1.1.1.6  christos   info->application_data = cpu;
    933  1.1.1.6  christos 
    934  1.1.1.6  christos   trace_printf (sd, cpu, "%s %s",
    935  1.1.1.6  christos 		trace_idx_to_str (TRACE_DISASM_IDX),
    936  1.1.1.6  christos 		TRACE_PREFIX (trace_data));
    937  1.1.1.6  christos   trace_data->disassembler (addr, info);
    938  1.1.1.6  christos   trace_printf (sd, cpu, "\n");
    939      1.1  christos }
    940      1.1  christos 
    941      1.1  christos void
    942      1.1  christos trace_input0 (SIM_DESC sd,
    943      1.1  christos 	      sim_cpu *cpu,
    944      1.1  christos 	      int trace_idx)
    945      1.1  christos {
    946      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    947      1.1  christos   TRACE_IDX (data) = trace_idx;
    948      1.1  christos }
    949      1.1  christos 
    950      1.1  christos void
    951      1.1  christos trace_input_word1 (SIM_DESC sd,
    952      1.1  christos 		   sim_cpu *cpu,
    953      1.1  christos 		   int trace_idx,
    954      1.1  christos 		   unsigned_word d0)
    955      1.1  christos {
    956      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    957      1.1  christos   TRACE_IDX (data) = trace_idx;
    958      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
    959      1.1  christos }
    960      1.1  christos 
    961      1.1  christos void
    962      1.1  christos trace_input_word2 (SIM_DESC sd,
    963      1.1  christos 		   sim_cpu *cpu,
    964      1.1  christos 		   int trace_idx,
    965      1.1  christos 		   unsigned_word d0,
    966      1.1  christos 		   unsigned_word d1)
    967      1.1  christos {
    968      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    969      1.1  christos   TRACE_IDX (data) = trace_idx;
    970      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
    971      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
    972      1.1  christos }
    973      1.1  christos 
    974      1.1  christos void
    975      1.1  christos trace_input_word3 (SIM_DESC sd,
    976      1.1  christos 		   sim_cpu *cpu,
    977      1.1  christos 		   int trace_idx,
    978      1.1  christos 		   unsigned_word d0,
    979      1.1  christos 		   unsigned_word d1,
    980      1.1  christos 		   unsigned_word d2)
    981      1.1  christos {
    982      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    983      1.1  christos   TRACE_IDX (data) = trace_idx;
    984      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
    985      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
    986      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2);
    987      1.1  christos }
    988      1.1  christos 
    989      1.1  christos void
    990      1.1  christos trace_input_word4 (SIM_DESC sd,
    991      1.1  christos 		   sim_cpu *cpu,
    992      1.1  christos 		   int trace_idx,
    993      1.1  christos 		   unsigned_word d0,
    994      1.1  christos 		   unsigned_word d1,
    995      1.1  christos 		   unsigned_word d2,
    996      1.1  christos 		   unsigned_word d3)
    997      1.1  christos {
    998      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
    999      1.1  christos   TRACE_IDX (data) = trace_idx;
   1000      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (d0), &d0);
   1001      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (d1), &d1);
   1002      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (d2), &d2);
   1003      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (d3), &d3);
   1004      1.1  christos }
   1005      1.1  christos 
   1006      1.1  christos void
   1007      1.1  christos trace_input_bool1 (SIM_DESC sd,
   1008      1.1  christos 		   sim_cpu *cpu,
   1009      1.1  christos 		   int trace_idx,
   1010      1.1  christos 		   int d0)
   1011      1.1  christos {
   1012      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1013      1.1  christos   TRACE_IDX (data) = trace_idx;
   1014      1.1  christos   save_data (sd, data, trace_fmt_bool, sizeof (d0), &d0);
   1015      1.1  christos }
   1016      1.1  christos 
   1017      1.1  christos void
   1018      1.1  christos trace_input_addr1 (SIM_DESC sd,
   1019      1.1  christos 		   sim_cpu *cpu,
   1020      1.1  christos 		   int trace_idx,
   1021      1.1  christos 		   address_word d0)
   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_addr, sizeof (d0), &d0);
   1026      1.1  christos }
   1027      1.1  christos 
   1028      1.1  christos void
   1029      1.1  christos trace_input_fp1 (SIM_DESC sd,
   1030      1.1  christos 		 sim_cpu *cpu,
   1031      1.1  christos 		 int trace_idx,
   1032      1.1  christos 		 fp_word f0)
   1033      1.1  christos {
   1034      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1035      1.1  christos   TRACE_IDX (data) = trace_idx;
   1036      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
   1037      1.1  christos }
   1038      1.1  christos 
   1039      1.1  christos void
   1040      1.1  christos trace_input_fp2 (SIM_DESC sd,
   1041      1.1  christos 		 sim_cpu *cpu,
   1042      1.1  christos 		 int trace_idx,
   1043      1.1  christos 		 fp_word f0,
   1044      1.1  christos 		 fp_word f1)
   1045      1.1  christos {
   1046      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1047      1.1  christos   TRACE_IDX (data) = trace_idx;
   1048      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
   1049      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
   1050      1.1  christos }
   1051      1.1  christos 
   1052      1.1  christos void
   1053      1.1  christos trace_input_fp3 (SIM_DESC sd,
   1054      1.1  christos 		 sim_cpu *cpu,
   1055      1.1  christos 		 int trace_idx,
   1056      1.1  christos 		 fp_word f0,
   1057      1.1  christos 		 fp_word f1,
   1058      1.1  christos 		 fp_word f2)
   1059      1.1  christos {
   1060      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1061      1.1  christos   TRACE_IDX (data) = trace_idx;
   1062      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
   1063      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
   1064      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f2);
   1065      1.1  christos }
   1066      1.1  christos 
   1067      1.1  christos void
   1068      1.1  christos trace_input_fpu1 (SIM_DESC sd,
   1069      1.1  christos 		  sim_cpu *cpu,
   1070      1.1  christos 		  int trace_idx,
   1071      1.1  christos 		  sim_fpu *f0)
   1072      1.1  christos {
   1073      1.1  christos   double d;
   1074      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1075      1.1  christos   TRACE_IDX (data) = trace_idx;
   1076      1.1  christos   d = sim_fpu_2d (f0);
   1077      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1078      1.1  christos }
   1079      1.1  christos 
   1080      1.1  christos void
   1081      1.1  christos trace_input_fpu2 (SIM_DESC sd,
   1082      1.1  christos 		  sim_cpu *cpu,
   1083      1.1  christos 		  int trace_idx,
   1084      1.1  christos 		  sim_fpu *f0,
   1085      1.1  christos 		  sim_fpu *f1)
   1086      1.1  christos {
   1087      1.1  christos   double d;
   1088      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1089      1.1  christos   TRACE_IDX (data) = trace_idx;
   1090      1.1  christos   d = sim_fpu_2d (f0);
   1091      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1092      1.1  christos   d = sim_fpu_2d (f1);
   1093      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1094      1.1  christos }
   1095      1.1  christos 
   1096      1.1  christos void
   1097      1.1  christos trace_input_fpu3 (SIM_DESC sd,
   1098      1.1  christos 		  sim_cpu *cpu,
   1099      1.1  christos 		  int trace_idx,
   1100      1.1  christos 		  sim_fpu *f0,
   1101      1.1  christos 		  sim_fpu *f1,
   1102      1.1  christos 		  sim_fpu *f2)
   1103      1.1  christos {
   1104      1.1  christos   double d;
   1105      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1106      1.1  christos   TRACE_IDX (data) = trace_idx;
   1107      1.1  christos   d = sim_fpu_2d (f0);
   1108      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1109      1.1  christos   d = sim_fpu_2d (f1);
   1110      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1111      1.1  christos   d = sim_fpu_2d (f2);
   1112      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1113      1.1  christos }
   1114      1.1  christos 
   1115      1.1  christos void
   1116      1.1  christos trace_result_word1 (SIM_DESC sd,
   1117      1.1  christos 		    sim_cpu *cpu,
   1118      1.1  christos 		    int trace_idx,
   1119      1.1  christos 		    unsigned_word r0)
   1120      1.1  christos {
   1121      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1122      1.1  christos   int last_input;
   1123      1.1  christos 
   1124      1.1  christos   /* Append any results to the end of the inputs */
   1125      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1126      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
   1127      1.1  christos 
   1128      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1129      1.1  christos }
   1130      1.1  christos 
   1131      1.1  christos void
   1132      1.1  christos trace_result0 (SIM_DESC sd,
   1133      1.1  christos 	       sim_cpu *cpu,
   1134      1.1  christos 	       int trace_idx)
   1135      1.1  christos {
   1136      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1137      1.1  christos   int last_input;
   1138      1.1  christos 
   1139      1.1  christos   /* Append any results to the end of the inputs */
   1140      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1141      1.1  christos 
   1142      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1143      1.1  christos }
   1144      1.1  christos 
   1145      1.1  christos void
   1146      1.1  christos trace_result_word2 (SIM_DESC sd,
   1147      1.1  christos 		    sim_cpu *cpu,
   1148      1.1  christos 		    int trace_idx,
   1149      1.1  christos 		    unsigned_word r0,
   1150      1.1  christos 		    unsigned_word r1)
   1151      1.1  christos {
   1152      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1153      1.1  christos   int last_input;
   1154      1.1  christos 
   1155      1.1  christos   /* Append any results to the end of the inputs */
   1156      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1157      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
   1158      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
   1159      1.1  christos 
   1160      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1161      1.1  christos }
   1162      1.1  christos 
   1163      1.1  christos void
   1164      1.1  christos trace_result_word4 (SIM_DESC sd,
   1165      1.1  christos 		    sim_cpu *cpu,
   1166      1.1  christos 		    int trace_idx,
   1167      1.1  christos 		    unsigned_word r0,
   1168      1.1  christos 		    unsigned_word r1,
   1169      1.1  christos 		    unsigned_word r2,
   1170      1.1  christos 		    unsigned_word r3)
   1171      1.1  christos {
   1172      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1173      1.1  christos   int last_input;
   1174      1.1  christos 
   1175      1.1  christos   /* Append any results to the end of the inputs */
   1176      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1177      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
   1178      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
   1179      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r2), &r2);
   1180      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (r3), &r3);
   1181      1.1  christos 
   1182      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1183      1.1  christos }
   1184      1.1  christos 
   1185      1.1  christos void
   1186      1.1  christos trace_result_bool1 (SIM_DESC sd,
   1187      1.1  christos 		    sim_cpu *cpu,
   1188      1.1  christos 		    int trace_idx,
   1189      1.1  christos 		    int r0)
   1190      1.1  christos {
   1191      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1192      1.1  christos   int last_input;
   1193      1.1  christos 
   1194      1.1  christos   /* Append any results to the end of the inputs */
   1195      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1196      1.1  christos   save_data (sd, data, trace_fmt_bool, sizeof (r0), &r0);
   1197      1.1  christos 
   1198      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1199      1.1  christos }
   1200      1.1  christos 
   1201      1.1  christos void
   1202      1.1  christos trace_result_addr1 (SIM_DESC sd,
   1203      1.1  christos 		    sim_cpu *cpu,
   1204      1.1  christos 		    int trace_idx,
   1205      1.1  christos 		    address_word r0)
   1206      1.1  christos {
   1207      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1208      1.1  christos   int last_input;
   1209      1.1  christos 
   1210      1.1  christos   /* Append any results to the end of the inputs */
   1211      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1212      1.1  christos   save_data (sd, data, trace_fmt_addr, sizeof (r0), &r0);
   1213      1.1  christos 
   1214      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1215      1.1  christos }
   1216      1.1  christos 
   1217      1.1  christos void
   1218      1.1  christos trace_result_fp1 (SIM_DESC sd,
   1219      1.1  christos 		  sim_cpu *cpu,
   1220      1.1  christos 		  int trace_idx,
   1221      1.1  christos 		  fp_word f0)
   1222      1.1  christos {
   1223      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1224      1.1  christos   int last_input;
   1225      1.1  christos 
   1226      1.1  christos   /* Append any results to the end of the inputs */
   1227      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1228      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
   1229      1.1  christos 
   1230      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1231      1.1  christos }
   1232      1.1  christos 
   1233      1.1  christos void
   1234      1.1  christos trace_result_fp2 (SIM_DESC sd,
   1235      1.1  christos 		  sim_cpu *cpu,
   1236      1.1  christos 		  int trace_idx,
   1237      1.1  christos 		  fp_word f0,
   1238      1.1  christos 		  fp_word f1)
   1239      1.1  christos {
   1240      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1241      1.1  christos   int last_input;
   1242      1.1  christos 
   1243      1.1  christos   /* Append any results to the end of the inputs */
   1244      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1245      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (f0), &f0);
   1246      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (f1), &f1);
   1247      1.1  christos 
   1248      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1249      1.1  christos }
   1250      1.1  christos 
   1251      1.1  christos void
   1252      1.1  christos trace_result_fpu1 (SIM_DESC sd,
   1253      1.1  christos 		   sim_cpu *cpu,
   1254      1.1  christos 		   int trace_idx,
   1255      1.1  christos 		   sim_fpu *f0)
   1256      1.1  christos {
   1257      1.1  christos   double d;
   1258      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1259      1.1  christos   int last_input;
   1260      1.1  christos 
   1261      1.1  christos   /* Append any results to the end of the inputs */
   1262      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1263      1.1  christos   d = sim_fpu_2d (f0);
   1264      1.1  christos   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
   1265      1.1  christos 
   1266      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1267      1.1  christos }
   1268      1.1  christos 
   1269      1.1  christos void
   1270      1.1  christos trace_result_string1 (SIM_DESC sd,
   1271      1.1  christos 		      sim_cpu *cpu,
   1272      1.1  christos 		      int trace_idx,
   1273      1.1  christos 		      char *s0)
   1274      1.1  christos {
   1275      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1276      1.1  christos   int last_input;
   1277      1.1  christos 
   1278      1.1  christos   /* Append any results to the end of the inputs */
   1279      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1280      1.1  christos   save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
   1281      1.1  christos 
   1282      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1283      1.1  christos }
   1284      1.1  christos 
   1285      1.1  christos void
   1286      1.1  christos trace_result_word1_string1 (SIM_DESC sd,
   1287      1.1  christos 			    sim_cpu *cpu,
   1288      1.1  christos 			    int trace_idx,
   1289      1.1  christos 			    unsigned_word r0,
   1290      1.1  christos 			    char *s0)
   1291      1.1  christos {
   1292      1.1  christos   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
   1293      1.1  christos   int last_input;
   1294      1.1  christos 
   1295      1.1  christos   /* Append any results to the end of the inputs */
   1296      1.1  christos   last_input = TRACE_INPUT_IDX (data);
   1297      1.1  christos   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
   1298      1.1  christos   save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
   1299      1.1  christos 
   1300      1.1  christos   trace_results (sd, cpu, trace_idx, last_input);
   1301      1.1  christos }
   1302      1.1  christos 
   1303      1.1  christos void
   1305      1.1  christos trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap)
   1306      1.1  christos {
   1307      1.1  christos   if (cpu != NULL)
   1308      1.1  christos     {
   1309      1.1  christos       if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL)
   1310      1.1  christos 	vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap);
   1311      1.1  christos       else
   1312      1.1  christos 	sim_io_evprintf (sd, fmt, ap);
   1313      1.1  christos     }
   1314      1.1  christos   else
   1315      1.1  christos     {
   1316      1.1  christos       if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL)
   1317      1.1  christos 	vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap);
   1318      1.1  christos       else
   1319      1.1  christos 	sim_io_evprintf (sd, fmt, ap);
   1320      1.1  christos     }
   1321  1.1.1.3  christos }
   1322      1.1  christos 
   1323      1.1  christos void
   1324      1.1  christos trace_printf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...)
   1325  1.1.1.3  christos {
   1326      1.1  christos   va_list ap;
   1327      1.1  christos 
   1328      1.1  christos   va_start (ap, fmt);
   1329      1.1  christos 
   1330      1.1  christos   trace_vprintf (sd, cpu, fmt, ap);
   1331      1.1  christos 
   1332      1.1  christos   va_end (ap);
   1333  1.1.1.5  christos }
   1334      1.1  christos 
   1335      1.1  christos void
   1336      1.1  christos sim_debug_printf (sim_cpu *cpu, const char *fmt, ...)
   1337  1.1.1.3  christos {
   1338      1.1  christos   va_list ap;
   1339      1.1  christos 
   1340      1.1  christos   va_start (ap, fmt);
   1341      1.1  christos 
   1342      1.1  christos   if (CPU_DEBUG_FILE (cpu) == NULL)
   1343      1.1  christos     (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
   1344      1.1  christos       (STATE_CALLBACK (CPU_STATE (cpu)), fmt, ap);
   1345      1.1  christos   else
   1346      1.1  christos     vfprintf (CPU_DEBUG_FILE (cpu), fmt, ap);
   1347                    
   1348                      va_end (ap);
   1349                    }
   1350