xref: /netbsd-src/external/gpl3/gdb/dist/sim/mips/interp.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
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