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