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