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