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