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