Home | History | Annotate | Line # | Download | only in mips
interp.c revision 1.1.1.1.2.1
      1 /*> interp.c <*/
      2 /* Simulator for the MIPS architecture.
      3 
      4    This file is part of the MIPS sim
      5 
      6 		THIS SOFTWARE IS NOT COPYRIGHTED
      7 
      8    Cygnus offers the following for use in the public domain.  Cygnus
      9    makes no warranty with regard to the software or it's performance
     10    and the user accepts the software "AS IS" with all faults.
     11 
     12    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
     13    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     14    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     15 
     16 NOTEs:
     17 
     18 The IDT monitor (found on the VR4300 board), seems to lie about
     19 register contents. It seems to treat the registers as sign-extended
     20 32-bit values. This cause *REAL* problems when single-stepping 64-bit
     21 code on the hardware.
     22 
     23 */
     24 
     25 /* The TRACE manifests enable the provision of extra features. If they
     26    are not defined then a simpler (quicker) simulator is constructed
     27    without the required run-time checks, etc. */
     28 #if 1 /* 0 to allow user build selection, 1 to force inclusion */
     29 #define TRACE (1)
     30 #endif
     31 
     32 #include "config.h"
     33 #include "bfd.h"
     34 #include "sim-main.h"
     35 #include "sim-utils.h"
     36 #include "sim-options.h"
     37 #include "sim-assert.h"
     38 #include "sim-hw.h"
     39 
     40 #include "itable.h"
     41 
     42 
     43 #include "config.h"
     44 
     45 #include <stdio.h>
     46 #include <stdarg.h>
     47 #include <ansidecl.h>
     48 #include <ctype.h>
     49 #include <limits.h>
     50 #include <math.h>
     51 #ifdef HAVE_STDLIB_H
     52 #include <stdlib.h>
     53 #endif
     54 #ifdef HAVE_STRING_H
     55 #include <string.h>
     56 #else
     57 #ifdef HAVE_STRINGS_H
     58 #include <strings.h>
     59 #endif
     60 #endif
     61 
     62 #include "getopt.h"
     63 #include "libiberty.h"
     64 #include "bfd.h"
     65 #include "gdb/callback.h"   /* GDB simulator callback interface */
     66 #include "gdb/remote-sim.h" /* GDB simulator interface */
     67 
     68 #ifndef PARAMS
     69 #define PARAMS(x)
     70 #endif
     71 
     72 char* pr_addr PARAMS ((SIM_ADDR addr));
     73 char* pr_uword64 PARAMS ((uword64 addr));
     74 
     75 
     76 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
     77 #define CPU cpu
     78 #define SD sd
     79 
     80 
     81 /* The following reserved instruction value is used when a simulator
     82    trap is required. NOTE: Care must be taken, since this value may be
     83    used in later revisions of the MIPS ISA. */
     84 
     85 #define RSVD_INSTRUCTION           (0x00000005)
     86 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
     87 
     88 #define RSVD_INSTRUCTION_ARG_SHIFT 6
     89 #define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF
     90 
     91 
     92 /* Bits in the Debug register */
     93 #define Debug_DBD 0x80000000   /* Debug Branch Delay */
     94 #define Debug_DM  0x40000000   /* Debug Mode         */
     95 #define Debug_DBp 0x00000002   /* Debug Breakpoint indicator */
     96 
     97 /*---------------------------------------------------------------------------*/
     98 /*-- GDB simulator interface ------------------------------------------------*/
     99 /*---------------------------------------------------------------------------*/
    100 
    101 static void ColdReset PARAMS((SIM_DESC sd));
    102 
    103 /*---------------------------------------------------------------------------*/
    104 
    105 
    106 
    107 #define DELAYSLOT()     {\
    108                           if (STATE & simDELAYSLOT)\
    109                             sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
    110                           STATE |= simDELAYSLOT;\
    111                         }
    112 
    113 #define JALDELAYSLOT()	{\
    114 			  DELAYSLOT ();\
    115 			  STATE |= simJALDELAYSLOT;\
    116 			}
    117 
    118 #define NULLIFY()       {\
    119                           STATE &= ~simDELAYSLOT;\
    120                           STATE |= simSKIPNEXT;\
    121                         }
    122 
    123 #define CANCELDELAYSLOT() {\
    124                             DSSTATE = 0;\
    125                             STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
    126                           }
    127 
    128 #define INDELAYSLOT()	((STATE & simDELAYSLOT) != 0)
    129 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
    130 
    131 /* Note that the monitor code essentially assumes this layout of memory.
    132    If you change these, change the monitor code, too.  */
    133 /* FIXME Currently addresses are truncated to 32-bits, see
    134    mips/sim-main.c:address_translation(). If that changes, then these
    135    values will need to be extended, and tested for more carefully. */
    136 #define K0BASE  (0x80000000)
    137 #define K0SIZE  (0x20000000)
    138 #define K1BASE  (0xA0000000)
    139 #define K1SIZE  (0x20000000)
    140 
    141 /* Simple run-time monitor support.
    142 
    143    We emulate the monitor by placing magic reserved instructions at
    144    the monitor's entry points; when we hit these instructions, instead
    145    of raising an exception (as we would normally), we look at the
    146    instruction and perform the appropriate monitory operation.
    147 
    148    `*_monitor_base' are the physical addresses at which the corresponding
    149         monitor vectors are located.  `0' means none.  By default,
    150         install all three.
    151     The RSVD_INSTRUCTION... macros specify the magic instructions we
    152     use at the monitor entry points.  */
    153 static int firmware_option_p = 0;
    154 static SIM_ADDR idt_monitor_base =     0xBFC00000;
    155 static SIM_ADDR pmon_monitor_base =    0xBFC00500;
    156 static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
    157 
    158 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
    159 
    160 
    161 #define MEM_SIZE (8 << 20)	/* 8 MBytes */
    162 
    163 
    164 #if defined(TRACE)
    165 static char *tracefile = "trace.din"; /* default filename for trace log */
    166 FILE *tracefh = NULL;
    167 static void open_trace PARAMS((SIM_DESC sd));
    168 #endif /* TRACE */
    169 
    170 static const char * get_insn_name (sim_cpu *, int);
    171 
    172 /* simulation target board.  NULL=canonical */
    173 static char* board = NULL;
    174 
    175 
    176 static DECLARE_OPTION_HANDLER (mips_option_handler);
    177 
    178 enum {
    179   OPTION_DINERO_TRACE = OPTION_START,
    180   OPTION_DINERO_FILE,
    181   OPTION_FIRMWARE,
    182   OPTION_INFO_MEMORY,
    183   OPTION_BOARD
    184 };
    185 
    186 static int display_mem_info = 0;
    187 
    188 static SIM_RC
    189 mips_option_handler (sd, cpu, opt, arg, is_command)
    190      SIM_DESC sd;
    191      sim_cpu *cpu;
    192      int opt;
    193      char *arg;
    194      int is_command;
    195 {
    196   int cpu_nr;
    197   switch (opt)
    198     {
    199     case OPTION_DINERO_TRACE: /* ??? */
    200 #if defined(TRACE)
    201       /* Eventually the simTRACE flag could be treated as a toggle, to
    202 	 allow external control of the program points being traced
    203 	 (i.e. only from main onwards, excluding the run-time setup,
    204 	 etc.). */
    205       for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
    206 	{
    207 	  sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
    208 	  if (arg == NULL)
    209 	    STATE |= simTRACE;
    210 	  else if (strcmp (arg, "yes") == 0)
    211 	    STATE |= simTRACE;
    212 	  else if (strcmp (arg, "no") == 0)
    213 	    STATE &= ~simTRACE;
    214 	  else if (strcmp (arg, "on") == 0)
    215 	    STATE |= simTRACE;
    216 	  else if (strcmp (arg, "off") == 0)
    217 	    STATE &= ~simTRACE;
    218 	  else
    219 	    {
    220 	      fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
    221 	      return SIM_RC_FAIL;
    222 	    }
    223 	}
    224       return SIM_RC_OK;
    225 #else /* !TRACE */
    226       fprintf(stderr,"\
    227 Simulator constructed without dinero tracing support (for performance).\n\
    228 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
    229       return SIM_RC_FAIL;
    230 #endif /* !TRACE */
    231 
    232     case OPTION_DINERO_FILE:
    233 #if defined(TRACE)
    234       if (optarg != NULL) {
    235 	char *tmp;
    236 	tmp = (char *)malloc(strlen(optarg) + 1);
    237 	if (tmp == NULL)
    238 	  {
    239 	    sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
    240 	    return SIM_RC_FAIL;
    241 	  }
    242 	else {
    243 	  strcpy(tmp,optarg);
    244 	  tracefile = tmp;
    245 	  sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
    246 	}
    247       }
    248 #endif /* TRACE */
    249       return SIM_RC_OK;
    250 
    251     case OPTION_FIRMWARE:
    252       return sim_firmware_command (sd, arg);
    253 
    254     case OPTION_BOARD:
    255       {
    256 	if (arg)
    257 	  {
    258 	    board = zalloc(strlen(arg) + 1);
    259 	    strcpy(board, arg);
    260 	  }
    261 	return SIM_RC_OK;
    262       }
    263 
    264     case OPTION_INFO_MEMORY:
    265       display_mem_info = 1;
    266       break;
    267     }
    268 
    269   return SIM_RC_OK;
    270 }
    271 
    272 
    273 static const OPTION mips_options[] =
    274 {
    275   { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
    276       '\0', "on|off", "Enable dinero tracing",
    277       mips_option_handler },
    278   { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
    279       '\0', "FILE", "Write dinero trace to FILE",
    280       mips_option_handler },
    281   { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
    282     '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
    283     mips_option_handler },
    284   { {"board", required_argument, NULL, OPTION_BOARD},
    285      '\0', "none" /* rely on compile-time string concatenation for other options */
    286 
    287 #define BOARD_JMR3904 "jmr3904"
    288            "|" BOARD_JMR3904
    289 #define BOARD_JMR3904_PAL "jmr3904pal"
    290            "|" BOARD_JMR3904_PAL
    291 #define BOARD_JMR3904_DEBUG "jmr3904debug"
    292            "|" BOARD_JMR3904_DEBUG
    293 #define BOARD_BSP "bsp"
    294            "|" BOARD_BSP
    295 
    296     , "Customize simulation for a particular board.", mips_option_handler },
    297 
    298   /* These next two options have the same names as ones found in the
    299      memory_options[] array in common/sim-memopt.c.  This is because
    300      the intention is to provide an alternative handler for those two
    301      options.  We need an alternative handler because the memory
    302      regions are not set up until after the command line arguments
    303      have been parsed, and so we cannot display the memory info whilst
    304      processing the command line.  There is a hack in sim_open to
    305      remove these handlers when we want the real --memory-info option
    306      to work.  */
    307   { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY },
    308     '\0', NULL, "List configured memory regions", mips_option_handler },
    309   { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY },
    310     '\0', NULL, NULL, mips_option_handler },
    311 
    312   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
    313 };
    314 
    315 
    316 int interrupt_pending;
    317 
    318 void
    319 interrupt_event (SIM_DESC sd, void *data)
    320 {
    321   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
    322   address_word cia = CIA_GET (cpu);
    323   if (SR & status_IE)
    324     {
    325       interrupt_pending = 0;
    326       SignalExceptionInterrupt (1); /* interrupt "1" */
    327     }
    328   else if (!interrupt_pending)
    329     sim_events_schedule (sd, 1, interrupt_event, data);
    330 }
    331 
    332 
    333 /*---------------------------------------------------------------------------*/
    334 /*-- Device registration hook -----------------------------------------------*/
    335 /*---------------------------------------------------------------------------*/
    336 static void device_init(SIM_DESC sd) {
    337 #ifdef DEVICE_INIT
    338   extern void register_devices(SIM_DESC);
    339   register_devices(sd);
    340 #endif
    341 }
    342 
    343 /*---------------------------------------------------------------------------*/
    344 /*-- GDB simulator interface ------------------------------------------------*/
    345 /*---------------------------------------------------------------------------*/
    346 
    347 SIM_DESC
    348 sim_open (kind, cb, abfd, argv)
    349      SIM_OPEN_KIND kind;
    350      host_callback *cb;
    351      struct bfd *abfd;
    352      char **argv;
    353 {
    354   SIM_DESC sd = sim_state_alloc (kind, cb);
    355   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
    356 
    357   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    358 
    359   /* FIXME: watchpoints code shouldn't need this */
    360   STATE_WATCHPOINTS (sd)->pc = &(PC);
    361   STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
    362   STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
    363 
    364   /* Initialize the mechanism for doing insn profiling.  */
    365   CPU_INSN_NAME (cpu) = get_insn_name;
    366   CPU_MAX_INSNS (cpu) = nr_itable_entries;
    367 
    368   STATE = 0;
    369 
    370   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    371     return 0;
    372   sim_add_option_table (sd, NULL, mips_options);
    373 
    374 
    375   /* getopt will print the error message so we just have to exit if this fails.
    376      FIXME: Hmmm...  in the case of gdb we need getopt to call
    377      print_filtered.  */
    378   if (sim_parse_args (sd, argv) != SIM_RC_OK)
    379     {
    380       /* Uninstall the modules to avoid memory leaks,
    381 	 file descriptor leaks, etc.  */
    382       sim_module_uninstall (sd);
    383       return 0;
    384     }
    385 
    386   /* handle board-specific memory maps */
    387   if (board == NULL)
    388     {
    389       /* Allocate core managed memory */
    390       sim_memopt *entry, *match = NULL;
    391       address_word mem_size = 0;
    392       int mapped = 0;
    393 
    394       /* For compatibility with the old code - under this (at level one)
    395 	 are the kernel spaces K0 & K1.  Both of these map to a single
    396 	 smaller sub region */
    397       sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
    398 
    399       /* Look for largest memory region defined on command-line at
    400 	 phys address 0. */
    401 #ifdef SIM_HAVE_FLATMEM
    402       mem_size = STATE_MEM_SIZE (sd);
    403 #endif
    404       for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
    405 	{
    406 	  /* If we find an entry at address 0, then we will end up
    407 	     allocating a new buffer in the "memory alias" command
    408 	     below. The region at address 0 will be deleted. */
    409 	  address_word size = (entry->modulo != 0
    410 			       ? entry->modulo : entry->nr_bytes);
    411 	  if (entry->addr == 0
    412 	      && (!match || entry->level < match->level))
    413 	    match = entry;
    414 	  else if (entry->addr == K0BASE || entry->addr == K1BASE)
    415 	    mapped = 1;
    416 	  else
    417 	    {
    418 	      sim_memopt *alias;
    419 	      for (alias = entry->alias; alias != NULL; alias = alias->next)
    420 		{
    421 		  if (alias->addr == 0
    422 		      && (!match || entry->level < match->level))
    423 		    match = entry;
    424 		  else if (alias->addr == K0BASE || alias->addr == K1BASE)
    425 		    mapped = 1;
    426 		}
    427 	    }
    428 	}
    429 
    430       if (!mapped)
    431 	{
    432 	  if (match)
    433 	    {
    434 	      /* Get existing memory region size. */
    435 	      mem_size = (match->modulo != 0
    436 			  ? match->modulo : match->nr_bytes);
    437 	      /* Delete old region. */
    438 	      sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
    439 			       match->space, match->addr, match->level);
    440 	    }
    441 	  else if (mem_size == 0)
    442 	    mem_size = MEM_SIZE;
    443 	  /* Limit to KSEG1 size (512MB) */
    444 	  if (mem_size > K1SIZE)
    445 	    mem_size = K1SIZE;
    446 	  /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
    447 	  sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
    448 			   K1BASE, K1SIZE, (long)mem_size, K0BASE);
    449 	}
    450 
    451       device_init(sd);
    452     }
    453   else if (board != NULL
    454 	   && (strcmp(board, BOARD_BSP) == 0))
    455     {
    456       int i;
    457 
    458       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
    459 
    460       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
    461       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    462 		       0x9FC00000,
    463 		       4 * 1024 * 1024, /* 4 MB */
    464 		       0xBFC00000);
    465 
    466       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
    467       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    468 		       0x80000000,
    469 		       4 * 1024 * 1024, /* 4 MB */
    470 		       0xA0000000);
    471 
    472       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
    473       for (i=0; i<8; i++) /* 32 MB total */
    474 	{
    475 	  unsigned size = 4 * 1024 * 1024;  /* 4 MB */
    476 	  sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    477 			   0x88000000 + (i * size),
    478 			   size,
    479 			   0xA8000000 + (i * size));
    480 	}
    481     }
    482 #if (WITH_HW)
    483   else if (board != NULL
    484 	   && (strcmp(board, BOARD_JMR3904) == 0 ||
    485 	       strcmp(board, BOARD_JMR3904_PAL) == 0 ||
    486 	       strcmp(board, BOARD_JMR3904_DEBUG) == 0))
    487     {
    488       /* match VIRTUAL memory layout of JMR-TX3904 board */
    489       int i;
    490 
    491       /* --- disable monitor unless forced on by user --- */
    492 
    493       if (! firmware_option_p)
    494 	{
    495 	  idt_monitor_base = 0;
    496 	  pmon_monitor_base = 0;
    497 	  lsipmon_monitor_base = 0;
    498 	}
    499 
    500       /* --- environment --- */
    501 
    502       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
    503 
    504       /* --- memory --- */
    505 
    506       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
    507       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    508 		       0x9FC00000,
    509 		       4 * 1024 * 1024, /* 4 MB */
    510 		       0xBFC00000);
    511 
    512       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
    513       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    514 		       0x80000000,
    515 		       4 * 1024 * 1024, /* 4 MB */
    516 		       0xA0000000);
    517 
    518       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
    519       for (i=0; i<8; i++) /* 32 MB total */
    520 	{
    521 	  unsigned size = 4 * 1024 * 1024;  /* 4 MB */
    522 	  sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
    523 			   0x88000000 + (i * size),
    524 			   size,
    525 			   0xA8000000 + (i * size));
    526 	}
    527 
    528       /* Dummy memory regions for unsimulated devices - sorted by address */
    529 
    530       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
    531       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
    532       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
    533       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
    534       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
    535       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
    536       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
    537       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
    538       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
    539 
    540 
    541       /* --- simulated devices --- */
    542       sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
    543       sim_hw_parse (sd, "/tx3904cpu");
    544       sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
    545       sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
    546       sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
    547       sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
    548       {
    549 	/* FIXME: poking at dv-sockser internals, use tcp backend if
    550 	 --sockser_addr option was given.*/
    551 	extern char* sockser_addr;
    552 	if(sockser_addr == NULL)
    553 	  sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
    554 	else
    555 	  sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
    556       }
    557       sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
    558       sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
    559 
    560       /* -- device connections --- */
    561       sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
    562       sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
    563       sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
    564       sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
    565       sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
    566       sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
    567 
    568       /* add PAL timer & I/O module */
    569       if(! strcmp(board, BOARD_JMR3904_PAL))
    570 	{
    571 	 /* the device */
    572 	 sim_hw_parse (sd, "/pal@0xffff0000");
    573 	 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
    574 
    575 	 /* wire up interrupt ports to irc */
    576 	 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
    577 	 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
    578 	 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
    579 	}
    580 
    581       if(! strcmp(board, BOARD_JMR3904_DEBUG))
    582 	{
    583 	  /* -- DEBUG: glue interrupt generators --- */
    584 	  sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
    585 	  sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
    586 	  sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
    587 	  sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
    588 	  sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
    589 	  sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
    590 	  sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
    591 	  sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
    592 	  sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
    593 	  sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
    594 	  sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
    595 	  sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
    596 	  sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
    597 	  sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
    598 	  sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
    599 	  sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
    600 	  sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
    601 	  sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
    602 	  sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
    603 	}
    604 
    605       device_init(sd);
    606     }
    607 #endif
    608 
    609   if (display_mem_info)
    610     {
    611       struct option_list * ol;
    612       struct option_list * prev;
    613 
    614       /* This is a hack.  We want to execute the real --memory-info command
    615 	 line switch which is handled in common/sim-memopts.c, not the
    616 	 override we have defined in this file.  So we remove the
    617 	 mips_options array from the state options list.  This is safe
    618          because we have now processed all of the command line.  */
    619       for (ol = STATE_OPTIONS (sd), prev = NULL;
    620 	   ol != NULL;
    621 	   prev = ol, ol = ol->next)
    622 	if (ol->options == mips_options)
    623 	  break;
    624 
    625       SIM_ASSERT (ol != NULL);
    626 
    627       if (prev == NULL)
    628 	STATE_OPTIONS (sd) = ol->next;
    629       else
    630 	prev->next = ol->next;
    631 
    632       sim_do_commandf (sd, "memory-info");
    633     }
    634 
    635   /* check for/establish the a reference program image */
    636   if (sim_analyze_program (sd,
    637 			   (STATE_PROG_ARGV (sd) != NULL
    638 			    ? *STATE_PROG_ARGV (sd)
    639 			    : NULL),
    640 			   abfd) != SIM_RC_OK)
    641     {
    642       sim_module_uninstall (sd);
    643       return 0;
    644     }
    645 
    646   /* Configure/verify the target byte order and other runtime
    647      configuration options */
    648   if (sim_config (sd) != SIM_RC_OK)
    649     {
    650       sim_module_uninstall (sd);
    651       return 0;
    652     }
    653 
    654   if (sim_post_argv_init (sd) != SIM_RC_OK)
    655     {
    656       /* Uninstall the modules to avoid memory leaks,
    657 	 file descriptor leaks, etc.  */
    658       sim_module_uninstall (sd);
    659       return 0;
    660     }
    661 
    662   /* verify assumptions the simulator made about the host type system.
    663      This macro does not return if there is a problem */
    664   SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
    665   SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
    666 
    667   /* This is NASTY, in that we are assuming the size of specific
    668      registers: */
    669   {
    670     int rn;
    671     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
    672       {
    673 	if (rn < 32)
    674 	  cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
    675 	else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
    676 	  cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
    677 	else if ((rn >= 33) && (rn <= 37))
    678 	  cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
    679 	else if ((rn == SRIDX)
    680 		 || (rn == FCR0IDX)
    681 		 || (rn == FCR31IDX)
    682 		 || ((rn >= 72) && (rn <= 89)))
    683 	  cpu->register_widths[rn] = 32;
    684 	else
    685 	  cpu->register_widths[rn] = 0;
    686       }
    687 
    688 
    689   }
    690 
    691 #if defined(TRACE)
    692   if (STATE & simTRACE)
    693     open_trace(sd);
    694 #endif /* TRACE */
    695 
    696   /*
    697   sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
    698 		  idt_monitor_base,
    699 		  pmon_monitor_base,
    700 		  lsipmon_monitor_base);
    701   */
    702 
    703   /* Write the monitor trap address handlers into the monitor (eeprom)
    704      address space.  This can only be done once the target endianness
    705      has been determined. */
    706   if (idt_monitor_base != 0)
    707     {
    708       unsigned loop;
    709       unsigned idt_monitor_size = 1 << 11;
    710 
    711       /* the default monitor region */
    712       sim_do_commandf (sd, "memory region 0x%x,0x%x",
    713 		       idt_monitor_base, idt_monitor_size);
    714 
    715       /* Entry into the IDT monitor is via fixed address vectors, and
    716 	 not using machine instructions. To avoid clashing with use of
    717 	 the MIPS TRAP system, we place our own (simulator specific)
    718 	 "undefined" instructions into the relevant vector slots. */
    719       for (loop = 0; (loop < idt_monitor_size); loop += 4)
    720 	{
    721 	  address_word vaddr = (idt_monitor_base + loop);
    722 	  unsigned32 insn = (RSVD_INSTRUCTION |
    723 			     (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
    724 			      << RSVD_INSTRUCTION_ARG_SHIFT));
    725 	  H2T (insn);
    726 	  sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
    727 	}
    728     }
    729 
    730   if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
    731     {
    732     /* The PMON monitor uses the same address space, but rather than
    733        branching into it the address of a routine is loaded. We can
    734        cheat for the moment, and direct the PMON routine to IDT style
    735        instructions within the monitor space. This relies on the IDT
    736        monitor not using the locations from 0xBFC00500 onwards as its
    737        entry points.*/
    738       unsigned loop;
    739       for (loop = 0; (loop < 24); loop++)
    740 	{
    741 	  unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
    742 	  switch (loop)
    743 	    {
    744             case 0: /* read */
    745               value = 7;
    746               break;
    747             case 1: /* write */
    748               value = 8;
    749               break;
    750             case 2: /* open */
    751               value = 6;
    752               break;
    753             case 3: /* close */
    754               value = 10;
    755               break;
    756             case 5: /* printf */
    757               value = ((0x500 - 16) / 8); /* not an IDT reason code */
    758               break;
    759             case 8: /* cliexit */
    760               value = 17;
    761               break;
    762             case 11: /* flush_cache */
    763               value = 28;
    764               break;
    765           }
    766 
    767 	SIM_ASSERT (idt_monitor_base != 0);
    768         value = ((unsigned int) idt_monitor_base + (value * 8));
    769 	H2T (value);
    770 
    771 	if (pmon_monitor_base != 0)
    772 	  {
    773 	    address_word vaddr = (pmon_monitor_base + (loop * 4));
    774 	    sim_write (sd, vaddr, (char *)&value, sizeof (value));
    775 	  }
    776 
    777 	if (lsipmon_monitor_base != 0)
    778 	  {
    779 	    address_word vaddr = (lsipmon_monitor_base + (loop * 4));
    780 	    sim_write (sd, vaddr, (char *)&value, sizeof (value));
    781 	  }
    782       }
    783 
    784   /* Write an abort sequence into the TRAP (common) exception vector
    785      addresses.  This is to catch code executing a TRAP (et.al.)
    786      instruction without installing a trap handler. */
    787   if ((idt_monitor_base != 0) ||
    788       (pmon_monitor_base != 0) ||
    789       (lsipmon_monitor_base != 0))
    790     {
    791       unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
    792 			     HALT_INSTRUCTION /* BREAK */ };
    793       H2T (halt[0]);
    794       H2T (halt[1]);
    795       sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
    796       sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
    797       sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
    798       /* XXX: Write here unconditionally? */
    799       sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
    800       sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
    801       sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
    802     }
    803   }
    804 
    805 
    806 
    807   return sd;
    808 }
    809 
    810 #if defined(TRACE)
    811 static void
    812 open_trace(sd)
    813      SIM_DESC sd;
    814 {
    815   tracefh = fopen(tracefile,"wb+");
    816   if (tracefh == NULL)
    817     {
    818       sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
    819       tracefh = stderr;
    820   }
    821 }
    822 #endif /* TRACE */
    823 
    824 /* Return name of an insn, used by insn profiling.  */
    825 static const char *
    826 get_insn_name (sim_cpu *cpu, int i)
    827 {
    828   return itable[i].name;
    829 }
    830 
    831 void
    832 sim_close (sd, quitting)
    833      SIM_DESC sd;
    834      int quitting;
    835 {
    836 #ifdef DEBUG
    837   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
    838 #endif
    839 
    840 
    841   /* "quitting" is non-zero if we cannot hang on errors */
    842 
    843   /* shut down modules */
    844   sim_module_uninstall (sd);
    845 
    846   /* Ensure that any resources allocated through the callback
    847      mechanism are released: */
    848   sim_io_shutdown (sd);
    849 
    850 #if defined(TRACE)
    851   if (tracefh != NULL && tracefh != stderr)
    852    fclose(tracefh);
    853   tracefh = NULL;
    854 #endif /* TRACE */
    855 
    856   /* FIXME - free SD */
    857 
    858   return;
    859 }
    860 
    861 
    862 int
    863 sim_write (sd,addr,buffer,size)
    864      SIM_DESC sd;
    865      SIM_ADDR addr;
    866      const unsigned char *buffer;
    867      int size;
    868 {
    869   int index;
    870   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
    871 
    872   /* Return the number of bytes written, or zero if error. */
    873 #ifdef DEBUG
    874   sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
    875 #endif
    876 
    877   /* We use raw read and write routines, since we do not want to count
    878      the GDB memory accesses in our statistics gathering. */
    879 
    880   for (index = 0; index < size; index++)
    881     {
    882       address_word vaddr = (address_word)addr + index;
    883       address_word paddr;
    884       int cca;
    885       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
    886 	break;
    887       if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
    888 	break;
    889     }
    890 
    891   return(index);
    892 }
    893 
    894 int
    895 sim_read (sd,addr,buffer,size)
    896      SIM_DESC sd;
    897      SIM_ADDR addr;
    898      unsigned char *buffer;
    899      int size;
    900 {
    901   int index;
    902   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
    903 
    904   /* Return the number of bytes read, or zero if error. */
    905 #ifdef DEBUG
    906   sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
    907 #endif /* DEBUG */
    908 
    909   for (index = 0; (index < size); index++)
    910     {
    911       address_word vaddr = (address_word)addr + index;
    912       address_word paddr;
    913       int cca;
    914       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
    915 	break;
    916       if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
    917 	break;
    918     }
    919 
    920   return(index);
    921 }
    922 
    923 int
    924 sim_store_register (sd,rn,memory,length)
    925      SIM_DESC sd;
    926      int rn;
    927      unsigned char *memory;
    928      int length;
    929 {
    930   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
    931   /* NOTE: gdb (the client) stores registers in target byte order
    932      while the simulator uses host byte order */
    933 #ifdef DEBUG
    934   sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
    935 #endif /* DEBUG */
    936 
    937   /* Unfortunately this suffers from the same problem as the register
    938      numbering one. We need to know what the width of each logical
    939      register number is for the architecture being simulated. */
    940 
    941   if (cpu->register_widths[rn] == 0)
    942     {
    943       sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
    944       return 0;
    945     }
    946 
    947 
    948 
    949   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
    950     {
    951       cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
    952       if (cpu->register_widths[rn] == 32)
    953 	{
    954 	  if (length == 8)
    955 	    {
    956 	      cpu->fgr[rn - FGR_BASE] =
    957 		(unsigned32) T2H_8 (*(unsigned64*)memory);
    958 	      return 8;
    959 	    }
    960 	  else
    961 	    {
    962 	      cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
    963 	      return 4;
    964 	    }
    965 	}
    966       else
    967 	{
    968           if (length == 8)
    969 	    {
    970 	      cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
    971 	      return 8;
    972 	    }
    973 	  else
    974 	    {
    975 	      cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
    976 	      return 4;
    977 	    }
    978 	}
    979     }
    980 
    981   if (cpu->register_widths[rn] == 32)
    982     {
    983       if (length == 8)
    984 	{
    985 	  cpu->registers[rn] =
    986 	    (unsigned32) T2H_8 (*(unsigned64*)memory);
    987 	  return 8;
    988 	}
    989       else
    990 	{
    991 	  cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
    992 	  return 4;
    993 	}
    994     }
    995   else
    996     {
    997       if (length == 8)
    998 	{
    999 	  cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
   1000 	  return 8;
   1001 	}
   1002       else
   1003 	{
   1004 	  cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
   1005 	  return 4;
   1006 	}
   1007     }
   1008 
   1009   return 0;
   1010 }
   1011 
   1012 int
   1013 sim_fetch_register (sd,rn,memory,length)
   1014      SIM_DESC sd;
   1015      int rn;
   1016      unsigned char *memory;
   1017      int length;
   1018 {
   1019   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
   1020   /* NOTE: gdb (the client) stores registers in target byte order
   1021      while the simulator uses host byte order */
   1022 #ifdef DEBUG
   1023 #if 0  /* FIXME: doesn't compile */
   1024   sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
   1025 #endif
   1026 #endif /* DEBUG */
   1027 
   1028   if (cpu->register_widths[rn] == 0)
   1029     {
   1030       sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
   1031       return 0;
   1032     }
   1033 
   1034 
   1035 
   1036   /* Any floating point register */
   1037   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
   1038     {
   1039       if (cpu->register_widths[rn] == 32)
   1040 	{
   1041 	  if (length == 8)
   1042 	    {
   1043 	      *(unsigned64*)memory =
   1044 		H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE]));
   1045 	      return 8;
   1046 	    }
   1047 	  else
   1048 	    {
   1049 	      *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
   1050 	      return 4;
   1051 	    }
   1052 	}
   1053       else
   1054 	{
   1055 	  if (length == 8)
   1056 	    {
   1057 	      *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
   1058 	      return 8;
   1059 	    }
   1060 	  else
   1061 	    {
   1062 	      *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
   1063 	      return 4;
   1064 	    }
   1065 	}
   1066     }
   1067 
   1068   if (cpu->register_widths[rn] == 32)
   1069     {
   1070       if (length == 8)
   1071 	{
   1072 	  *(unsigned64*)memory =
   1073 	    H2T_8 ((unsigned32) (cpu->registers[rn]));
   1074 	  return 8;
   1075 	}
   1076       else
   1077 	{
   1078 	  *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
   1079 	  return 4;
   1080 	}
   1081     }
   1082   else
   1083     {
   1084       if (length == 8)
   1085 	{
   1086 	  *(unsigned64*)memory =
   1087 	    H2T_8 ((unsigned64) (cpu->registers[rn]));
   1088 	  return 8;
   1089 	}
   1090       else
   1091 	{
   1092 	  *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
   1093 	  return 4;
   1094 	}
   1095     }
   1096 
   1097   return 0;
   1098 }
   1099 
   1100 
   1101 SIM_RC
   1102 sim_create_inferior (sd, abfd, argv,env)
   1103      SIM_DESC sd;
   1104      struct bfd *abfd;
   1105      char **argv;
   1106      char **env;
   1107 {
   1108 
   1109 #ifdef DEBUG
   1110 #if 0 /* FIXME: doesn't compile */
   1111   printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
   1112 	 pr_addr(PC));
   1113 #endif
   1114 #endif /* DEBUG */
   1115 
   1116   ColdReset(sd);
   1117 
   1118   if (abfd != NULL)
   1119     {
   1120       /* override PC value set by ColdReset () */
   1121       int cpu_nr;
   1122       for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
   1123 	{
   1124 	  sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
   1125 	  CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
   1126 	}
   1127     }
   1128 
   1129 #if 0 /* def DEBUG */
   1130   if (argv || env)
   1131     {
   1132       /* We should really place the argv slot values into the argument
   1133 	 registers, and onto the stack as required. However, this
   1134 	 assumes that we have a stack defined, which is not
   1135 	 necessarily true at the moment. */
   1136       char **cptr;
   1137       sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
   1138       for (cptr = argv; (cptr && *cptr); cptr++)
   1139 	printf("DBG: arg \"%s\"\n",*cptr);
   1140     }
   1141 #endif /* DEBUG */
   1142 
   1143   return SIM_RC_OK;
   1144 }
   1145 
   1146 /*---------------------------------------------------------------------------*/
   1147 /*-- Private simulator support interface ------------------------------------*/
   1148 /*---------------------------------------------------------------------------*/
   1149 
   1150 /* Read a null terminated string from memory, return in a buffer */
   1151 static char *
   1152 fetch_str (SIM_DESC sd,
   1153 	   address_word addr)
   1154 {
   1155   char *buf;
   1156   int nr = 0;
   1157   char null;
   1158   while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
   1159     nr++;
   1160   buf = NZALLOC (char, nr + 1);
   1161   sim_read (sd, addr, buf, nr);
   1162   return buf;
   1163 }
   1164 
   1165 
   1166 /* Implements the "sim firmware" command:
   1167 	sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
   1168 		NAME can be idt, pmon, or lsipmon.  If omitted, ADDRESS
   1169 		defaults to the normal address for that monitor.
   1170 	sim firmware none --- don't emulate any ROM monitor.  Useful
   1171 		if you need a clean address space.  */
   1172 static SIM_RC
   1173 sim_firmware_command (SIM_DESC sd, char *arg)
   1174 {
   1175   int address_present = 0;
   1176   SIM_ADDR address;
   1177 
   1178   /* Signal occurrence of this option. */
   1179   firmware_option_p = 1;
   1180 
   1181   /* Parse out the address, if present.  */
   1182   {
   1183     char *p = strchr (arg, '@');
   1184     if (p)
   1185       {
   1186 	char *q;
   1187 	address_present = 1;
   1188 	p ++; /* skip over @ */
   1189 
   1190 	address = strtoul (p, &q, 0);
   1191 	if (*q != '\0')
   1192 	  {
   1193 	    sim_io_printf (sd, "Invalid address given to the"
   1194 			   "`sim firmware NAME@ADDRESS' command: %s\n",
   1195 			   p);
   1196 	    return SIM_RC_FAIL;
   1197 	  }
   1198       }
   1199     else
   1200       {
   1201 	address_present = 0;
   1202 	address = -1; /* Dummy value.  */
   1203       }
   1204   }
   1205 
   1206   if (! strncmp (arg, "idt", 3))
   1207     {
   1208       idt_monitor_base = address_present ? address : 0xBFC00000;
   1209       pmon_monitor_base = 0;
   1210       lsipmon_monitor_base = 0;
   1211     }
   1212   else if (! strncmp (arg, "pmon", 4))
   1213     {
   1214       /* pmon uses indirect calls.  Hook into implied idt. */
   1215       pmon_monitor_base = address_present ? address : 0xBFC00500;
   1216       idt_monitor_base = pmon_monitor_base - 0x500;
   1217       lsipmon_monitor_base = 0;
   1218     }
   1219   else if (! strncmp (arg, "lsipmon", 7))
   1220     {
   1221       /* lsipmon uses indirect calls.  Hook into implied idt. */
   1222       pmon_monitor_base = 0;
   1223       lsipmon_monitor_base = address_present ? address : 0xBFC00200;
   1224       idt_monitor_base = lsipmon_monitor_base - 0x200;
   1225     }
   1226   else if (! strncmp (arg, "none", 4))
   1227     {
   1228       if (address_present)
   1229 	{
   1230 	  sim_io_printf (sd,
   1231 			 "The `sim firmware none' command does "
   1232 			 "not take an `ADDRESS' argument.\n");
   1233 	  return SIM_RC_FAIL;
   1234 	}
   1235       idt_monitor_base = 0;
   1236       pmon_monitor_base = 0;
   1237       lsipmon_monitor_base = 0;
   1238     }
   1239   else
   1240     {
   1241       sim_io_printf (sd, "\
   1242 Unrecognized name given to the `sim firmware NAME' command: %s\n\
   1243 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
   1244 		     arg);
   1245       return SIM_RC_FAIL;
   1246     }
   1247 
   1248   return SIM_RC_OK;
   1249 }
   1250 
   1251 
   1252 
   1253 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
   1254 int
   1255 sim_monitor (SIM_DESC sd,
   1256 	     sim_cpu *cpu,
   1257 	     address_word cia,
   1258 	     unsigned int reason)
   1259 {
   1260 #ifdef DEBUG
   1261   printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
   1262 #endif /* DEBUG */
   1263 
   1264   /* The IDT monitor actually allows two instructions per vector
   1265      slot. However, the simulator currently causes a trap on each
   1266      individual instruction. We cheat, and lose the bottom bit. */
   1267   reason >>= 1;
   1268 
   1269   /* The following callback functions are available, however the
   1270      monitor we are simulating does not make use of them: get_errno,
   1271      isatty, lseek, rename, system, time and unlink */
   1272   switch (reason)
   1273     {
   1274 
   1275     case 6: /* int open(char *path,int flags) */
   1276       {
   1277 	char *path = fetch_str (sd, A0);
   1278 	V0 = sim_io_open (sd, path, (int)A1);
   1279 	free (path);
   1280 	break;
   1281       }
   1282 
   1283     case 7: /* int read(int file,char *ptr,int len) */
   1284       {
   1285 	int fd = A0;
   1286 	int nr = A2;
   1287 	char *buf = zalloc (nr);
   1288 	V0 = sim_io_read (sd, fd, buf, nr);
   1289 	sim_write (sd, A1, buf, nr);
   1290 	free (buf);
   1291       }
   1292       break;
   1293 
   1294     case 8: /* int write(int file,char *ptr,int len) */
   1295       {
   1296 	int fd = A0;
   1297 	int nr = A2;
   1298 	char *buf = zalloc (nr);
   1299 	sim_read (sd, A1, buf, nr);
   1300 	V0 = sim_io_write (sd, fd, buf, nr);
   1301 	if (fd == 1)
   1302 	    sim_io_flush_stdout (sd);
   1303 	else if (fd == 2)
   1304 	    sim_io_flush_stderr (sd);
   1305 	free (buf);
   1306 	break;
   1307       }
   1308 
   1309     case 10: /* int close(int file) */
   1310       {
   1311 	V0 = sim_io_close (sd, (int)A0);
   1312 	break;
   1313       }
   1314 
   1315     case 2:  /* Densan monitor: char inbyte(int waitflag) */
   1316       {
   1317 	if (A0 == 0)	/* waitflag == NOWAIT */
   1318 	  V0 = (unsigned_word)-1;
   1319       }
   1320      /* Drop through to case 11 */
   1321 
   1322     case 11: /* char inbyte(void) */
   1323       {
   1324         char tmp;
   1325 	/* ensure that all output has gone... */
   1326 	sim_io_flush_stdout (sd);
   1327         if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
   1328 	  {
   1329 	    sim_io_error(sd,"Invalid return from character read");
   1330 	    V0 = (unsigned_word)-1;
   1331 	  }
   1332         else
   1333 	  V0 = (unsigned_word)tmp;
   1334 	break;
   1335       }
   1336 
   1337     case 3:  /* Densan monitor: void co(char chr) */
   1338     case 12: /* void outbyte(char chr) : write a byte to "stdout" */
   1339       {
   1340         char tmp = (char)(A0 & 0xFF);
   1341         sim_io_write_stdout (sd, &tmp, sizeof(char));
   1342 	break;
   1343       }
   1344 
   1345     case 17: /* void _exit() */
   1346       {
   1347 	sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
   1348 	sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
   1349 			 (unsigned int)(A0 & 0xFFFFFFFF));
   1350 	break;
   1351       }
   1352 
   1353     case 28: /* PMON flush_cache */
   1354       break;
   1355 
   1356     case 55: /* void get_mem_info(unsigned int *ptr) */
   1357       /* in:  A0 = pointer to three word memory location */
   1358       /* out: [A0 + 0] = size */
   1359       /*      [A0 + 4] = instruction cache size */
   1360       /*      [A0 + 8] = data cache size */
   1361       {
   1362 	unsigned_4 value;
   1363 	unsigned_4 zero = 0;
   1364 	address_word mem_size;
   1365 	sim_memopt *entry, *match = NULL;
   1366 
   1367 	/* Search for memory region mapped to KSEG0 or KSEG1. */
   1368 	for (entry = STATE_MEMOPT (sd);
   1369 	     entry != NULL;
   1370 	     entry = entry->next)
   1371 	  {
   1372 	    if ((entry->addr == K0BASE || entry->addr == K1BASE)
   1373 		&& (!match || entry->level < match->level))
   1374 	      match = entry;
   1375 	    else
   1376 	      {
   1377 		sim_memopt *alias;
   1378 		for (alias = entry->alias;
   1379 		     alias != NULL;
   1380 		     alias = alias->next)
   1381 		  if ((alias->addr == K0BASE || alias->addr == K1BASE)
   1382 		      && (!match || entry->level < match->level))
   1383 		    match = entry;
   1384 	      }
   1385 	  }
   1386 
   1387 	/* Get region size, limit to KSEG1 size (512MB). */
   1388 	SIM_ASSERT (match != NULL);
   1389 	mem_size = (match->modulo != 0
   1390 		    ? match->modulo : match->nr_bytes);
   1391 	if (mem_size > K1SIZE)
   1392 	  mem_size = K1SIZE;
   1393 
   1394 	value = mem_size;
   1395 	H2T (value);
   1396 	sim_write (sd, A0 + 0, (char *)&value, 4);
   1397 	sim_write (sd, A0 + 4, (char *)&zero, 4);
   1398 	sim_write (sd, A0 + 8, (char *)&zero, 4);
   1399 	/* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
   1400 	break;
   1401       }
   1402 
   1403     case 158: /* PMON printf */
   1404       /* in:  A0 = pointer to format string */
   1405       /*      A1 = optional argument 1 */
   1406       /*      A2 = optional argument 2 */
   1407       /*      A3 = optional argument 3 */
   1408       /* out: void */
   1409       /* The following is based on the PMON printf source */
   1410       {
   1411 	address_word s = A0;
   1412 	char c;
   1413 	signed_word *ap = &A1; /* 1st argument */
   1414         /* This isn't the quickest way, since we call the host print
   1415            routine for every character almost. But it does avoid
   1416            having to allocate and manage a temporary string buffer. */
   1417 	/* TODO: Include check that we only use three arguments (A1,
   1418            A2 and A3) */
   1419 	while (sim_read (sd, s++, &c, 1) && c != '\0')
   1420 	  {
   1421             if (c == '%')
   1422 	      {
   1423 		char tmp[40];
   1424 		enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
   1425 		int width = 0, trunc = 0, haddot = 0, longlong = 0;
   1426 		while (sim_read (sd, s++, &c, 1) && c != '\0')
   1427 		  {
   1428 		    if (strchr ("dobxXulscefg%", c))
   1429 		      break;
   1430 		    else if (c == '-')
   1431 		      fmt = FMT_LJUST;
   1432 		    else if (c == '0')
   1433 		      fmt = FMT_RJUST0;
   1434 		    else if (c == '~')
   1435 		      fmt = FMT_CENTER;
   1436 		    else if (c == '*')
   1437 		      {
   1438 			if (haddot)
   1439 			  trunc = (int)*ap++;
   1440 			else
   1441 			  width = (int)*ap++;
   1442 		      }
   1443 		    else if (c >= '1' && c <= '9')
   1444 		      {
   1445 			address_word t = s;
   1446 			unsigned int n;
   1447 			while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
   1448 			  tmp[s - t] = c;
   1449 			tmp[s - t] = '\0';
   1450 			n = (unsigned int)strtol(tmp,NULL,10);
   1451 			if (haddot)
   1452 			  trunc = n;
   1453 			else
   1454 			  width = n;
   1455 			s--;
   1456 		      }
   1457 		    else if (c == '.')
   1458 		      haddot = 1;
   1459 		  }
   1460 		switch (c)
   1461 		  {
   1462 		  case '%':
   1463 		    sim_io_printf (sd, "%%");
   1464 		    break;
   1465 		  case 's':
   1466 		    if ((int)*ap != 0)
   1467 		      {
   1468 			address_word p = *ap++;
   1469 			char ch;
   1470 			while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
   1471 			  sim_io_printf(sd, "%c", ch);
   1472 		      }
   1473 		    else
   1474 		      sim_io_printf(sd,"(null)");
   1475 		    break;
   1476 		  case 'c':
   1477 		    sim_io_printf (sd, "%c", (int)*ap++);
   1478 		    break;
   1479 		  default:
   1480 		    if (c == 'l')
   1481 		      {
   1482 			sim_read (sd, s++, &c, 1);
   1483 			if (c == 'l')
   1484 			  {
   1485 			    longlong = 1;
   1486 			    sim_read (sd, s++, &c, 1);
   1487 			  }
   1488 		      }
   1489 		    if (strchr ("dobxXu", c))
   1490 		      {
   1491 			word64 lv = (word64) *ap++;
   1492 			if (c == 'b')
   1493 			  sim_io_printf(sd,"<binary not supported>");
   1494 			else
   1495 			  {
   1496 			    sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
   1497 			    if (longlong)
   1498 			      sim_io_printf(sd, tmp, lv);
   1499 			    else
   1500 			      sim_io_printf(sd, tmp, (int)lv);
   1501 			  }
   1502 		      }
   1503 		    else if (strchr ("eEfgG", c))
   1504 		      {
   1505 			double dbl = *(double*)(ap++);
   1506 			sprintf (tmp, "%%%d.%d%c", width, trunc, c);
   1507 			sim_io_printf (sd, tmp, dbl);
   1508 			trunc = 0;
   1509 		      }
   1510 		  }
   1511 	      }
   1512 	    else
   1513 	      sim_io_printf(sd, "%c", c);
   1514 	  }
   1515 	break;
   1516       }
   1517 
   1518     default:
   1519       /* Unknown reason.  */
   1520       return 0;
   1521   }
   1522   return 1;
   1523 }
   1524 
   1525 /* Store a word into memory.  */
   1526 
   1527 static void
   1528 store_word (SIM_DESC sd,
   1529 	    sim_cpu *cpu,
   1530 	    address_word cia,
   1531 	    uword64 vaddr,
   1532 	    signed_word val)
   1533 {
   1534   address_word paddr;
   1535   int uncached;
   1536 
   1537   if ((vaddr & 3) != 0)
   1538     SignalExceptionAddressStore ();
   1539   else
   1540     {
   1541       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
   1542 			      isTARGET, isREAL))
   1543 	{
   1544 	  const uword64 mask = 7;
   1545 	  uword64 memval;
   1546 	  unsigned int byte;
   1547 
   1548 	  paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
   1549 	  byte = (vaddr & mask) ^ (BigEndianCPU << 2);
   1550 	  memval = ((uword64) val) << (8 * byte);
   1551 	  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
   1552 		       isREAL);
   1553 	}
   1554     }
   1555 }
   1556 
   1557 /* Load a word from memory.  */
   1558 
   1559 static signed_word
   1560 load_word (SIM_DESC sd,
   1561 	   sim_cpu *cpu,
   1562 	   address_word cia,
   1563 	   uword64 vaddr)
   1564 {
   1565   if ((vaddr & 3) != 0)
   1566     {
   1567       SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
   1568     }
   1569   else
   1570     {
   1571       address_word paddr;
   1572       int uncached;
   1573 
   1574       if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
   1575 			      isTARGET, isREAL))
   1576 	{
   1577 	  const uword64 mask = 0x7;
   1578 	  const unsigned int reverse = ReverseEndian ? 1 : 0;
   1579 	  const unsigned int bigend = BigEndianCPU ? 1 : 0;
   1580 	  uword64 memval;
   1581 	  unsigned int byte;
   1582 
   1583 	  paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
   1584 	  LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
   1585 			       isDATA, isREAL);
   1586 	  byte = (vaddr & mask) ^ (bigend << 2);
   1587 	  return EXTEND32 (memval >> (8 * byte));
   1588 	}
   1589     }
   1590 
   1591   return 0;
   1592 }
   1593 
   1594 /* Simulate the mips16 entry and exit pseudo-instructions.  These
   1595    would normally be handled by the reserved instruction exception
   1596    code, but for ease of simulation we just handle them directly.  */
   1597 
   1598 static void
   1599 mips16_entry (SIM_DESC sd,
   1600 	      sim_cpu *cpu,
   1601 	      address_word cia,
   1602 	      unsigned int insn)
   1603 {
   1604   int aregs, sregs, rreg;
   1605 
   1606 #ifdef DEBUG
   1607   printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
   1608 #endif /* DEBUG */
   1609 
   1610   aregs = (insn & 0x700) >> 8;
   1611   sregs = (insn & 0x0c0) >> 6;
   1612   rreg =  (insn & 0x020) >> 5;
   1613 
   1614   /* This should be checked by the caller.  */
   1615   if (sregs == 3)
   1616     abort ();
   1617 
   1618   if (aregs < 5)
   1619     {
   1620       int i;
   1621       signed_word tsp;
   1622 
   1623       /* This is the entry pseudo-instruction.  */
   1624 
   1625       for (i = 0; i < aregs; i++)
   1626 	store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
   1627 
   1628       tsp = SP;
   1629       SP -= 32;
   1630 
   1631       if (rreg)
   1632 	{
   1633 	  tsp -= 4;
   1634 	  store_word (SD, CPU, cia, (uword64) tsp, RA);
   1635 	}
   1636 
   1637       for (i = 0; i < sregs; i++)
   1638 	{
   1639 	  tsp -= 4;
   1640 	  store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
   1641 	}
   1642     }
   1643   else
   1644     {
   1645       int i;
   1646       signed_word tsp;
   1647 
   1648       /* This is the exit pseudo-instruction.  */
   1649 
   1650       tsp = SP + 32;
   1651 
   1652       if (rreg)
   1653 	{
   1654 	  tsp -= 4;
   1655 	  RA = load_word (SD, CPU, cia, (uword64) tsp);
   1656 	}
   1657 
   1658       for (i = 0; i < sregs; i++)
   1659 	{
   1660 	  tsp -= 4;
   1661 	  GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
   1662 	}
   1663 
   1664       SP += 32;
   1665 
   1666       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   1667 	{
   1668 	  if (aregs == 5)
   1669 	    {
   1670 	      FGR[0] = WORD64LO (GPR[4]);
   1671 	      FPR_STATE[0] = fmt_uninterpreted;
   1672 	    }
   1673 	  else if (aregs == 6)
   1674 	    {
   1675 	      FGR[0] = WORD64LO (GPR[5]);
   1676 	      FGR[1] = WORD64LO (GPR[4]);
   1677 	      FPR_STATE[0] = fmt_uninterpreted;
   1678 	      FPR_STATE[1] = fmt_uninterpreted;
   1679 	    }
   1680 	}
   1681 
   1682       PC = RA;
   1683     }
   1684 
   1685 }
   1686 
   1687 /*-- trace support ----------------------------------------------------------*/
   1688 
   1689 /* The TRACE support is provided (if required) in the memory accessing
   1690    routines. Since we are also providing the architecture specific
   1691    features, the architecture simulation code can also deal with
   1692    notifying the TRACE world of cache flushes, etc. Similarly we do
   1693    not need to provide profiling support in the simulator engine,
   1694    since we can sample in the instruction fetch control loop. By
   1695    defining the TRACE manifest, we add tracing as a run-time
   1696    option. */
   1697 
   1698 #if defined(TRACE)
   1699 /* Tracing by default produces "din" format (as required by
   1700    dineroIII). Each line of such a trace file *MUST* have a din label
   1701    and address field. The rest of the line is ignored, so comments can
   1702    be included if desired. The first field is the label which must be
   1703    one of the following values:
   1704 
   1705 	0       read data
   1706         1       write data
   1707         2       instruction fetch
   1708         3       escape record (treated as unknown access type)
   1709         4       escape record (causes cache flush)
   1710 
   1711    The address field is a 32bit (lower-case) hexadecimal address
   1712    value. The address should *NOT* be preceded by "0x".
   1713 
   1714    The size of the memory transfer is not important when dealing with
   1715    cache lines (as long as no more than a cache line can be
   1716    transferred in a single operation :-), however more information
   1717    could be given following the dineroIII requirement to allow more
   1718    complete memory and cache simulators to provide better
   1719    results. i.e. the University of Pisa has a cache simulator that can
   1720    also take bus size and speed as (variable) inputs to calculate
   1721    complete system performance (a much more useful ability when trying
   1722    to construct an end product, rather than a processor). They
   1723    currently have an ARM version of their tool called ChARM. */
   1724 
   1725 
   1726 void
   1727 dotrace (SIM_DESC sd,
   1728 	 sim_cpu *cpu,
   1729 	 FILE *tracefh,
   1730 	 int type,
   1731 	 SIM_ADDR address,
   1732 	 int width,
   1733 	 char *comment,...)
   1734 {
   1735   if (STATE & simTRACE) {
   1736     va_list ap;
   1737     fprintf(tracefh,"%d %s ; width %d ; ",
   1738 		type,
   1739 		pr_addr(address),
   1740 		width);
   1741     va_start(ap,comment);
   1742     vfprintf(tracefh,comment,ap);
   1743     va_end(ap);
   1744     fprintf(tracefh,"\n");
   1745   }
   1746   /* NOTE: Since the "din" format will only accept 32bit addresses, and
   1747      we may be generating 64bit ones, we should put the hi-32bits of the
   1748      address into the comment field. */
   1749 
   1750   /* TODO: Provide a buffer for the trace lines. We can then avoid
   1751      performing writes until the buffer is filled, or the file is
   1752      being closed. */
   1753 
   1754   /* NOTE: We could consider adding a comment field to the "din" file
   1755      produced using type 3 markers (unknown access). This would then
   1756      allow information about the program that the "din" is for, and
   1757      the MIPs world that was being simulated, to be placed into the
   1758      trace file. */
   1759 
   1760   return;
   1761 }
   1762 #endif /* TRACE */
   1763 
   1764 /*---------------------------------------------------------------------------*/
   1765 /*-- simulator engine -------------------------------------------------------*/
   1766 /*---------------------------------------------------------------------------*/
   1767 
   1768 static void
   1769 ColdReset (SIM_DESC sd)
   1770 {
   1771   int cpu_nr;
   1772   for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
   1773     {
   1774       sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
   1775       /* RESET: Fixed PC address: */
   1776       PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
   1777       /* The reset vector address is in the unmapped, uncached memory space. */
   1778 
   1779       SR &= ~(status_SR | status_TS | status_RP);
   1780       SR |= (status_ERL | status_BEV);
   1781 
   1782       /* Cheat and allow access to the complete register set immediately */
   1783       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
   1784 	  && WITH_TARGET_WORD_BITSIZE == 64)
   1785 	SR |= status_FR; /* 64bit registers */
   1786 
   1787       /* Ensure that any instructions with pending register updates are
   1788 	 cleared: */
   1789       PENDING_INVALIDATE();
   1790 
   1791       /* Initialise the FPU registers to the unknown state */
   1792       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   1793 	{
   1794 	  int rn;
   1795 	  for (rn = 0; (rn < 32); rn++)
   1796 	    FPR_STATE[rn] = fmt_uninterpreted;
   1797 	}
   1798 
   1799       /* Initialise the Config0 register. */
   1800       C0_CONFIG = 0x80000000 		/* Config1 present */
   1801 	| 2;				/* KSEG0 uncached */
   1802       if (WITH_TARGET_WORD_BITSIZE == 64)
   1803 	{
   1804 	  /* FIXME Currently mips/sim-main.c:address_translation()
   1805 	     truncates all addresses to 32-bits. */
   1806 	  if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64)
   1807 	    C0_CONFIG |= (2 << 13);	/* MIPS64, 64-bit addresses */
   1808 	  else
   1809 	    C0_CONFIG |= (1 << 13);	/* MIPS64, 32-bit addresses */
   1810 	}
   1811       if (BigEndianMem)
   1812 	C0_CONFIG |= 0x00008000;	/* Big Endian */
   1813     }
   1814 }
   1815 
   1816 
   1817 
   1818 
   1819 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
   1820 /* Signal an exception condition. This will result in an exception
   1821    that aborts the instruction. The instruction operation pseudocode
   1822    will never see a return from this function call. */
   1823 
   1824 void
   1825 signal_exception (SIM_DESC sd,
   1826 		  sim_cpu *cpu,
   1827 		  address_word cia,
   1828 		  int exception,...)
   1829 {
   1830   /* int vector; */
   1831 
   1832 #ifdef DEBUG
   1833   sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
   1834 #endif /* DEBUG */
   1835 
   1836   /* Ensure that any active atomic read/modify/write operation will fail: */
   1837   LLBIT = 0;
   1838 
   1839   /* Save registers before interrupt dispatching */
   1840 #ifdef SIM_CPU_EXCEPTION_TRIGGER
   1841   SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
   1842 #endif
   1843 
   1844   switch (exception) {
   1845 
   1846     case DebugBreakPoint:
   1847       if (! (Debug & Debug_DM))
   1848         {
   1849           if (INDELAYSLOT())
   1850             {
   1851               CANCELDELAYSLOT();
   1852 
   1853               Debug |= Debug_DBD;  /* signaled from within in delay slot */
   1854               DEPC = cia - 4;      /* reference the branch instruction */
   1855             }
   1856           else
   1857             {
   1858               Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
   1859               DEPC = cia;
   1860             }
   1861 
   1862           Debug |= Debug_DM;            /* in debugging mode */
   1863           Debug |= Debug_DBp;           /* raising a DBp exception */
   1864           PC = 0xBFC00200;
   1865           sim_engine_restart (SD, CPU, NULL, NULL_CIA);
   1866         }
   1867       break;
   1868 
   1869     case ReservedInstruction:
   1870      {
   1871        va_list ap;
   1872        unsigned int instruction;
   1873        va_start(ap,exception);
   1874        instruction = va_arg(ap,unsigned int);
   1875        va_end(ap);
   1876        /* Provide simple monitor support using ReservedInstruction
   1877           exceptions. The following code simulates the fixed vector
   1878           entry points into the IDT monitor by causing a simulator
   1879           trap, performing the monitor operation, and returning to
   1880           the address held in the $ra register (standard PCS return
   1881           address). This means we only need to pre-load the vector
   1882           space with suitable instruction values. For systems were
   1883           actual trap instructions are used, we would not need to
   1884           perform this magic. */
   1885        if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
   1886 	 {
   1887 	   int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;
   1888 	   if (!sim_monitor (SD, CPU, cia, reason))
   1889 	     sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));
   1890 
   1891 	   /* NOTE: This assumes that a branch-and-link style
   1892 	      instruction was used to enter the vector (which is the
   1893 	      case with the current IDT monitor). */
   1894 	   sim_engine_restart (SD, CPU, NULL, RA);
   1895 	 }
   1896        /* Look for the mips16 entry and exit instructions, and
   1897           simulate a handler for them.  */
   1898        else if ((cia & 1) != 0
   1899 		&& (instruction & 0xf81f) == 0xe809
   1900 		&& (instruction & 0x0c0) != 0x0c0)
   1901 	 {
   1902 	   mips16_entry (SD, CPU, cia, instruction);
   1903 	   sim_engine_restart (sd, NULL, NULL, NULL_CIA);
   1904 	 }
   1905        /* else fall through to normal exception processing */
   1906        sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
   1907      }
   1908 
   1909     default:
   1910      /* Store exception code into current exception id variable (used
   1911         by exit code): */
   1912 
   1913      /* TODO: If not simulating exceptions then stop the simulator
   1914         execution. At the moment we always stop the simulation. */
   1915 
   1916 #ifdef SUBTARGET_R3900
   1917       /* update interrupt-related registers */
   1918 
   1919       /* insert exception code in bits 6:2 */
   1920       CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
   1921       /* shift IE/KU history bits left */
   1922       SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
   1923 
   1924       if (STATE & simDELAYSLOT)
   1925 	{
   1926 	  STATE &= ~simDELAYSLOT;
   1927 	  CAUSE |= cause_BD;
   1928 	  EPC = (cia - 4); /* reference the branch instruction */
   1929 	}
   1930       else
   1931 	EPC = cia;
   1932 
   1933      if (SR & status_BEV)
   1934        PC = (signed)0xBFC00000 + 0x180;
   1935      else
   1936        PC = (signed)0x80000000 + 0x080;
   1937 #else
   1938      /* See figure 5-17 for an outline of the code below */
   1939      if (! (SR & status_EXL))
   1940        {
   1941 	 CAUSE = (exception << 2);
   1942 	 if (STATE & simDELAYSLOT)
   1943 	   {
   1944 	     STATE &= ~simDELAYSLOT;
   1945 	     CAUSE |= cause_BD;
   1946 	     EPC = (cia - 4); /* reference the branch instruction */
   1947 	   }
   1948 	 else
   1949 	   EPC = cia;
   1950 	 /* FIXME: TLB et.al. */
   1951 	 /* vector = 0x180; */
   1952        }
   1953      else
   1954        {
   1955 	 CAUSE = (exception << 2);
   1956 	 /* vector = 0x180; */
   1957        }
   1958      SR |= status_EXL;
   1959      /* Store exception code into current exception id variable (used
   1960         by exit code): */
   1961 
   1962      if (SR & status_BEV)
   1963        PC = (signed)0xBFC00200 + 0x180;
   1964      else
   1965        PC = (signed)0x80000000 + 0x180;
   1966 #endif
   1967 
   1968      switch ((CAUSE >> 2) & 0x1F)
   1969        {
   1970        case Interrupt:
   1971 	 /* Interrupts arrive during event processing, no need to
   1972             restart */
   1973 	 return;
   1974 
   1975        case NMIReset:
   1976 	 /* Ditto */
   1977 #ifdef SUBTARGET_3900
   1978 	 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000  */
   1979 	 PC = (signed)0xBFC00000;
   1980 #endif /* SUBTARGET_3900 */
   1981 	 return;
   1982 
   1983        case TLBModification:
   1984        case TLBLoad:
   1985        case TLBStore:
   1986        case AddressLoad:
   1987        case AddressStore:
   1988        case InstructionFetch:
   1989        case DataReference:
   1990 	 /* The following is so that the simulator will continue from the
   1991 	    exception handler address. */
   1992 	 sim_engine_halt (SD, CPU, NULL, PC,
   1993 			  sim_stopped, SIM_SIGBUS);
   1994 
   1995        case ReservedInstruction:
   1996        case CoProcessorUnusable:
   1997 	 PC = EPC;
   1998 	 sim_engine_halt (SD, CPU, NULL, PC,
   1999 			  sim_stopped, SIM_SIGILL);
   2000 
   2001        case IntegerOverflow:
   2002        case FPE:
   2003 	 sim_engine_halt (SD, CPU, NULL, PC,
   2004 			  sim_stopped, SIM_SIGFPE);
   2005 
   2006        case BreakPoint:
   2007 	 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
   2008 	 break;
   2009 
   2010        case SystemCall:
   2011        case Trap:
   2012 	 sim_engine_restart (SD, CPU, NULL, PC);
   2013 	 break;
   2014 
   2015        case Watch:
   2016 	 PC = EPC;
   2017 	 sim_engine_halt (SD, CPU, NULL, PC,
   2018 			  sim_stopped, SIM_SIGTRAP);
   2019 
   2020        default: /* Unknown internal exception */
   2021 	 PC = EPC;
   2022 	 sim_engine_halt (SD, CPU, NULL, PC,
   2023 			  sim_stopped, SIM_SIGABRT);
   2024 
   2025        }
   2026 
   2027     case SimulatorFault:
   2028      {
   2029        va_list ap;
   2030        char *msg;
   2031        va_start(ap,exception);
   2032        msg = va_arg(ap,char *);
   2033        va_end(ap);
   2034        sim_engine_abort (SD, CPU, NULL_CIA,
   2035 			 "FATAL: Simulator error \"%s\"\n",msg);
   2036      }
   2037    }
   2038 
   2039   return;
   2040 }
   2041 
   2042 
   2043 
   2044 /* This function implements what the MIPS32 and MIPS64 ISAs define as
   2045    "UNPREDICTABLE" behaviour.
   2046 
   2047    About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
   2048    may vary from processor implementation to processor implementation,
   2049    instruction to instruction, or as a function of time on the same
   2050    implementation or instruction.  Software can never depend on results
   2051    that are UNPREDICTABLE. ..."  (MIPS64 Architecture for Programmers
   2052    Volume II, The MIPS64 Instruction Set.  MIPS Document MD00087 revision
   2053    0.95, page 2.)
   2054 
   2055    For UNPREDICTABLE behaviour, we print a message, if possible print
   2056    the offending instructions mips.igen instruction name (provided by
   2057    the caller), and stop the simulator.
   2058 
   2059    XXX FIXME: eventually, stopping the simulator should be made conditional
   2060    on a command-line option.  */
   2061 void
   2062 unpredictable_action(sim_cpu *cpu, address_word cia)
   2063 {
   2064   SIM_DESC sd = CPU_STATE(cpu);
   2065 
   2066   sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
   2067   sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
   2068 }
   2069 
   2070 
   2071 /*-- co-processor support routines ------------------------------------------*/
   2072 
   2073 static int UNUSED
   2074 CoProcPresent(unsigned int coproc_number)
   2075 {
   2076   /* Return TRUE if simulator provides a model for the given co-processor number */
   2077   return(0);
   2078 }
   2079 
   2080 void
   2081 cop_lw (SIM_DESC sd,
   2082 	sim_cpu *cpu,
   2083 	address_word cia,
   2084 	int coproc_num,
   2085 	int coproc_reg,
   2086 	unsigned int memword)
   2087 {
   2088   switch (coproc_num)
   2089     {
   2090     case 1:
   2091       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   2092 	{
   2093 #ifdef DEBUG
   2094 	  printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
   2095 #endif
   2096 	  StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
   2097 	  break;
   2098 	}
   2099 
   2100     default:
   2101 #if 0 /* this should be controlled by a configuration option */
   2102       sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
   2103 #endif
   2104       break;
   2105     }
   2106 
   2107   return;
   2108 }
   2109 
   2110 void
   2111 cop_ld (SIM_DESC sd,
   2112 	sim_cpu *cpu,
   2113 	address_word cia,
   2114 	int coproc_num,
   2115 	int coproc_reg,
   2116 	uword64 memword)
   2117 {
   2118 
   2119 #ifdef DEBUG
   2120   printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia) );
   2121 #endif
   2122 
   2123   switch (coproc_num) {
   2124     case 1:
   2125       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   2126 	{
   2127 	  StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
   2128 	  break;
   2129 	}
   2130 
   2131     default:
   2132 #if 0 /* this message should be controlled by a configuration option */
   2133      sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
   2134 #endif
   2135      break;
   2136   }
   2137 
   2138   return;
   2139 }
   2140 
   2141 
   2142 
   2143 
   2144 unsigned int
   2145 cop_sw (SIM_DESC sd,
   2146 	sim_cpu *cpu,
   2147 	address_word cia,
   2148 	int coproc_num,
   2149 	int coproc_reg)
   2150 {
   2151   unsigned int value = 0;
   2152 
   2153   switch (coproc_num)
   2154     {
   2155     case 1:
   2156       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   2157 	{
   2158 	  value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
   2159 	  break;
   2160 	}
   2161 
   2162     default:
   2163 #if 0 /* should be controlled by configuration option */
   2164       sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
   2165 #endif
   2166       break;
   2167     }
   2168 
   2169   return(value);
   2170 }
   2171 
   2172 uword64
   2173 cop_sd (SIM_DESC sd,
   2174 	sim_cpu *cpu,
   2175 	address_word cia,
   2176 	int coproc_num,
   2177 	int coproc_reg)
   2178 {
   2179   uword64 value = 0;
   2180   switch (coproc_num)
   2181     {
   2182     case 1:
   2183       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   2184 	{
   2185 	  value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
   2186 	  break;
   2187 	}
   2188 
   2189     default:
   2190 #if 0 /* should be controlled by configuration option */
   2191       sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
   2192 #endif
   2193       break;
   2194     }
   2195 
   2196   return(value);
   2197 }
   2198 
   2199 
   2200 
   2201 
   2202 void
   2203 decode_coproc (SIM_DESC sd,
   2204 	       sim_cpu *cpu,
   2205 	       address_word cia,
   2206 	       unsigned int instruction)
   2207 {
   2208   int coprocnum = ((instruction >> 26) & 3);
   2209 
   2210   switch (coprocnum)
   2211     {
   2212     case 0: /* standard CPU control and cache registers */
   2213       {
   2214         int code = ((instruction >> 21) & 0x1F);
   2215 	int rt = ((instruction >> 16) & 0x1F);
   2216 	int rd = ((instruction >> 11) & 0x1F);
   2217 	int tail = instruction & 0x3ff;
   2218         /* R4000 Users Manual (second edition) lists the following CP0
   2219            instructions:
   2220 	                                                           CODE><-RT><RD-><--TAIL--->
   2221 	   DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
   2222 	   DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
   2223 	   MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
   2224 	   MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
   2225 	   TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
   2226 	   TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
   2227 	   TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
   2228 	   TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
   2229 	   CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
   2230 	   ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
   2231 	   */
   2232         if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */
   2233 	     || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */
   2234 	    && tail == 0)
   2235 	  {
   2236 	    /* Clear double/single coprocessor move bit. */
   2237 	    code &= ~1;
   2238 
   2239 	    /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
   2240 
   2241 	    switch (rd)  /* NOTEs: Standard CP0 registers */
   2242 	      {
   2243 		/* 0 = Index               R4000   VR4100  VR4300 */
   2244 		/* 1 = Random              R4000   VR4100  VR4300 */
   2245 		/* 2 = EntryLo0            R4000   VR4100  VR4300 */
   2246 		/* 3 = EntryLo1            R4000   VR4100  VR4300 */
   2247 		/* 4 = Context             R4000   VR4100  VR4300 */
   2248 		/* 5 = PageMask            R4000   VR4100  VR4300 */
   2249 		/* 6 = Wired               R4000   VR4100  VR4300 */
   2250 		/* 8 = BadVAddr            R4000   VR4100  VR4300 */
   2251 		/* 9 = Count               R4000   VR4100  VR4300 */
   2252 		/* 10 = EntryHi            R4000   VR4100  VR4300 */
   2253 		/* 11 = Compare            R4000   VR4100  VR4300 */
   2254 		/* 12 = SR                 R4000   VR4100  VR4300 */
   2255 #ifdef SUBTARGET_R3900
   2256 	      case 3:
   2257 		/* 3 = Config              R3900                  */
   2258 	      case 7:
   2259 		/* 7 = Cache               R3900                  */
   2260 	      case 15:
   2261 		/* 15 = PRID               R3900                  */
   2262 
   2263 		/* ignore */
   2264 		break;
   2265 
   2266 	      case 8:
   2267 		/* 8 = BadVAddr            R4000   VR4100  VR4300 */
   2268 		if (code == 0x00)
   2269 		  GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
   2270 		else
   2271 		  COP0_BADVADDR = GPR[rt];
   2272 		break;
   2273 
   2274 #endif /* SUBTARGET_R3900 */
   2275 	      case 12:
   2276 		if (code == 0x00)
   2277 		  GPR[rt] = SR;
   2278 		else
   2279 		  SR = GPR[rt];
   2280 		break;
   2281 		/* 13 = Cause              R4000   VR4100  VR4300 */
   2282 	      case 13:
   2283 		if (code == 0x00)
   2284 		  GPR[rt] = CAUSE;
   2285 		else
   2286 		  CAUSE = GPR[rt];
   2287 		break;
   2288 		/* 14 = EPC                R4000   VR4100  VR4300 */
   2289 	      case 14:
   2290 		if (code == 0x00)
   2291 		  GPR[rt] = (signed_word) (signed_address) EPC;
   2292 		else
   2293 		  EPC = GPR[rt];
   2294 		break;
   2295 		/* 15 = PRId               R4000   VR4100  VR4300 */
   2296 #ifdef SUBTARGET_R3900
   2297                 /* 16 = Debug */
   2298               case 16:
   2299                 if (code == 0x00)
   2300                   GPR[rt] = Debug;
   2301                 else
   2302                   Debug = GPR[rt];
   2303                 break;
   2304 #else
   2305 		/* 16 = Config             R4000   VR4100  VR4300 */
   2306               case 16:
   2307 		if (code == 0x00)
   2308 		  GPR[rt] = C0_CONFIG;
   2309 		else
   2310 		  /* only bottom three bits are writable */
   2311 		  C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
   2312                 break;
   2313 #endif
   2314 #ifdef SUBTARGET_R3900
   2315                 /* 17 = Debug */
   2316               case 17:
   2317                 if (code == 0x00)
   2318                   GPR[rt] = DEPC;
   2319                 else
   2320                   DEPC = GPR[rt];
   2321                 break;
   2322 #else
   2323 		/* 17 = LLAddr             R4000   VR4100  VR4300 */
   2324 #endif
   2325 		/* 18 = WatchLo            R4000   VR4100  VR4300 */
   2326 		/* 19 = WatchHi            R4000   VR4100  VR4300 */
   2327 		/* 20 = XContext           R4000   VR4100  VR4300 */
   2328 		/* 26 = PErr or ECC        R4000   VR4100  VR4300 */
   2329 		/* 27 = CacheErr           R4000   VR4100 */
   2330 		/* 28 = TagLo              R4000   VR4100  VR4300 */
   2331 		/* 29 = TagHi              R4000   VR4100  VR4300 */
   2332 		/* 30 = ErrorEPC           R4000   VR4100  VR4300 */
   2333 		if (STATE_VERBOSE_P(SD))
   2334 		  sim_io_eprintf (SD,
   2335 				  "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
   2336 				  (unsigned long)cia);
   2337 		GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
   2338 		/* CPR[0,rd] = GPR[rt]; */
   2339 	      default:
   2340 		if (code == 0x00)
   2341 		  GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
   2342 		else
   2343 		  COP0_GPR[rd] = GPR[rt];
   2344 #if 0
   2345 		if (code == 0x00)
   2346 		  sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
   2347 		else
   2348 		  sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
   2349 #endif
   2350 	      }
   2351 	  }
   2352 	else if ((code == 0x00 || code == 0x01)
   2353 		 && rd == 16)
   2354 	  {
   2355 	    /* [D]MFC0 RT,C0_CONFIG,SEL */
   2356 	    signed32 cfg = 0;
   2357 	    switch (tail & 0x07)
   2358 	      {
   2359 	      case 0:
   2360 		cfg = C0_CONFIG;
   2361 		break;
   2362 	      case 1:
   2363 		/* MIPS32 r/o Config1:
   2364 		   Config2 present */
   2365 		cfg = 0x80000000;
   2366 		/* MIPS16 implemented.
   2367 		   XXX How to check configuration? */
   2368 		cfg |= 0x0000004;
   2369 		if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
   2370 		  /* MDMX & FPU implemented */
   2371 		  cfg |= 0x00000021;
   2372 		break;
   2373 	      case 2:
   2374 		/* MIPS32 r/o Config2:
   2375 		   Config3 present. */
   2376 		cfg = 0x80000000;
   2377 		break;
   2378 	      case 3:
   2379 		/* MIPS32 r/o Config3:
   2380 		   SmartMIPS implemented. */
   2381 		cfg = 0x00000002;
   2382 		break;
   2383 	      }
   2384 	    GPR[rt] = cfg;
   2385 	  }
   2386 	else if (code == 0x10 && (tail & 0x3f) == 0x18)
   2387 	  {
   2388 	    /* ERET */
   2389 	    if (SR & status_ERL)
   2390 	      {
   2391 		/* Oops, not yet available */
   2392 		sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
   2393 		PC = EPC;
   2394 		SR &= ~status_ERL;
   2395 	      }
   2396 	    else
   2397 	      {
   2398 		PC = EPC;
   2399 		SR &= ~status_EXL;
   2400 	      }
   2401 	  }
   2402         else if (code == 0x10 && (tail & 0x3f) == 0x10)
   2403           {
   2404             /* RFE */
   2405 #ifdef SUBTARGET_R3900
   2406 	    /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
   2407 
   2408 	    /* shift IE/KU history bits right */
   2409 	    SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
   2410 
   2411 	    /* TODO: CACHE register */
   2412 #endif /* SUBTARGET_R3900 */
   2413           }
   2414         else if (code == 0x10 && (tail & 0x3f) == 0x1F)
   2415           {
   2416             /* DERET */
   2417             Debug &= ~Debug_DM;
   2418             DELAYSLOT();
   2419             DSPC = DEPC;
   2420           }
   2421 	else
   2422 	  sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
   2423         /* TODO: When executing an ERET or RFE instruction we should
   2424            clear LLBIT, to ensure that any out-standing atomic
   2425            read/modify/write sequence fails. */
   2426       }
   2427     break;
   2428 
   2429     case 2: /* co-processor 2 */
   2430       {
   2431 	int handle = 0;
   2432 
   2433 
   2434 	if(! handle)
   2435 	  {
   2436 	    sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
   2437 			   instruction,pr_addr(cia));
   2438 	  }
   2439       }
   2440     break;
   2441 
   2442     case 1: /* should not occur (FPU co-processor) */
   2443     case 3: /* should not occur (FPU co-processor) */
   2444       SignalException(ReservedInstruction,instruction);
   2445       break;
   2446     }
   2447 
   2448   return;
   2449 }
   2450 
   2451 
   2452 /* This code copied from gdb's utils.c.  Would like to share this code,
   2453    but don't know of a common place where both could get to it. */
   2454 
   2455 /* Temporary storage using circular buffer */
   2456 #define NUMCELLS 16
   2457 #define CELLSIZE 32
   2458 static char*
   2459 get_cell (void)
   2460 {
   2461   static char buf[NUMCELLS][CELLSIZE];
   2462   static int cell=0;
   2463   if (++cell>=NUMCELLS) cell=0;
   2464   return buf[cell];
   2465 }
   2466 
   2467 /* Print routines to handle variable size regs, etc */
   2468 
   2469 /* Eliminate warning from compiler on 32-bit systems */
   2470 static int thirty_two = 32;
   2471 
   2472 char*
   2473 pr_addr(addr)
   2474   SIM_ADDR addr;
   2475 {
   2476   char *paddr_str=get_cell();
   2477   switch (sizeof(addr))
   2478     {
   2479       case 8:
   2480         sprintf(paddr_str,"%08lx%08lx",
   2481 		(unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
   2482 	break;
   2483       case 4:
   2484         sprintf(paddr_str,"%08lx",(unsigned long)addr);
   2485 	break;
   2486       case 2:
   2487         sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
   2488 	break;
   2489       default:
   2490         sprintf(paddr_str,"%x",addr);
   2491     }
   2492   return paddr_str;
   2493 }
   2494 
   2495 char*
   2496 pr_uword64(addr)
   2497   uword64 addr;
   2498 {
   2499   char *paddr_str=get_cell();
   2500   sprintf(paddr_str,"%08lx%08lx",
   2501           (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
   2502   return paddr_str;
   2503 }
   2504 
   2505 
   2506 void
   2507 mips_core_signal (SIM_DESC sd,
   2508                  sim_cpu *cpu,
   2509                  sim_cia cia,
   2510                  unsigned map,
   2511                  int nr_bytes,
   2512                  address_word addr,
   2513                  transfer_type transfer,
   2514                  sim_core_signals sig)
   2515 {
   2516   const char *copy = (transfer == read_transfer ? "read" : "write");
   2517   address_word ip = CIA_ADDR (cia);
   2518 
   2519   switch (sig)
   2520     {
   2521     case sim_core_unmapped_signal:
   2522       sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
   2523                       nr_bytes, copy,
   2524 		      (unsigned long) addr, (unsigned long) ip);
   2525       COP0_BADVADDR = addr;
   2526       SignalExceptionDataReference();
   2527       break;
   2528 
   2529     case sim_core_unaligned_signal:
   2530       sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
   2531                       nr_bytes, copy,
   2532 		      (unsigned long) addr, (unsigned long) ip);
   2533       COP0_BADVADDR = addr;
   2534       if(transfer == read_transfer)
   2535 	SignalExceptionAddressLoad();
   2536       else
   2537 	SignalExceptionAddressStore();
   2538       break;
   2539 
   2540     default:
   2541       sim_engine_abort (sd, cpu, cia,
   2542                         "mips_core_signal - internal error - bad switch");
   2543     }
   2544 }
   2545 
   2546 
   2547 void
   2548 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
   2549 {
   2550   ASSERT(cpu != NULL);
   2551 
   2552   if(cpu->exc_suspended > 0)
   2553     sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
   2554 
   2555   PC = cia;
   2556   memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
   2557   cpu->exc_suspended = 0;
   2558 }
   2559 
   2560 void
   2561 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
   2562 {
   2563   ASSERT(cpu != NULL);
   2564 
   2565   if(cpu->exc_suspended > 0)
   2566     sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
   2567 		   cpu->exc_suspended, exception);
   2568 
   2569   memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
   2570   memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
   2571   cpu->exc_suspended = exception;
   2572 }
   2573 
   2574 void
   2575 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
   2576 {
   2577   ASSERT(cpu != NULL);
   2578 
   2579   if(exception == 0 && cpu->exc_suspended > 0)
   2580     {
   2581       /* warn not for breakpoints */
   2582       if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
   2583 	sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
   2584 		       cpu->exc_suspended);
   2585     }
   2586   else if(exception != 0 && cpu->exc_suspended > 0)
   2587     {
   2588       if(exception != cpu->exc_suspended)
   2589 	sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
   2590 		       cpu->exc_suspended, exception);
   2591 
   2592       memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
   2593     }
   2594   else if(exception != 0 && cpu->exc_suspended == 0)
   2595     {
   2596       sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
   2597     }
   2598   cpu->exc_suspended = 0;
   2599 }
   2600 
   2601 
   2602 /*---------------------------------------------------------------------------*/
   2603 /*> EOF interp.c <*/
   2604