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