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