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