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