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