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