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