sim: arm/d10v/h8300/m68hc11/microblaze/mips/mn10300/moxie/sh/v850: convert to common...
[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, struct bfd *abfd, char **argv)
350 {
351   int i;
352   SIM_DESC sd = sim_state_alloc (kind, cb);
353   sim_cpu *cpu;
354
355   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
356
357   /* The cpu data is kept in a separately allocated chunk of memory.  */
358   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
359     return 0;
360
361   cpu = STATE_CPU (sd, 0); /* FIXME */
362
363   /* FIXME: watchpoints code shouldn't need this */
364   STATE_WATCHPOINTS (sd)->pc = &(PC);
365   STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
366   STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
367
368   /* Initialize the mechanism for doing insn profiling.  */
369   CPU_INSN_NAME (cpu) = get_insn_name;
370   CPU_MAX_INSNS (cpu) = nr_itable_entries;
371
372   STATE = 0;
373   
374   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
375     return 0;
376   sim_add_option_table (sd, NULL, mips_options);
377
378
379   /* getopt will print the error message so we just have to exit if this fails.
380      FIXME: Hmmm...  in the case of gdb we need getopt to call
381      print_filtered.  */
382   if (sim_parse_args (sd, argv) != SIM_RC_OK)
383     {
384       /* Uninstall the modules to avoid memory leaks,
385          file descriptor leaks, etc.  */
386       sim_module_uninstall (sd);
387       return 0;
388     }
389
390   /* handle board-specific memory maps */
391   if (board == NULL)
392     {
393       /* Allocate core managed memory */
394       sim_memopt *entry, *match = NULL;
395       address_word mem_size = 0;
396       int mapped = 0;
397
398       /* For compatibility with the old code - under this (at level one)
399          are the kernel spaces K0 & K1.  Both of these map to a single
400          smaller sub region */
401       sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
402
403       /* Look for largest memory region defined on command-line at
404          phys address 0. */
405       for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
406         {
407           /* If we find an entry at address 0, then we will end up
408              allocating a new buffer in the "memory alias" command
409              below. The region at address 0 will be deleted. */
410           address_word size = (entry->modulo != 0
411                                ? entry->modulo : entry->nr_bytes);
412           if (entry->addr == 0
413               && (!match || entry->level < match->level))
414             match = entry;
415           else if (entry->addr == K0BASE || entry->addr == K1BASE)
416             mapped = 1;
417           else
418             {
419               sim_memopt *alias;
420               for (alias = entry->alias; alias != NULL; alias = alias->next)
421                 {
422                   if (alias->addr == 0
423                       && (!match || entry->level < match->level))
424                     match = entry;
425                   else if (alias->addr == K0BASE || alias->addr == K1BASE)
426                     mapped = 1;
427                 }
428             }
429         }
430
431       if (!mapped)
432         {
433           if (match)
434             {
435               /* Get existing memory region size. */
436               mem_size = (match->modulo != 0
437                           ? match->modulo : match->nr_bytes);
438               /* Delete old region. */
439               sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
440                                match->space, match->addr, match->level);
441             }         
442           else if (mem_size == 0)
443             mem_size = MEM_SIZE;
444           /* Limit to KSEG1 size (512MB) */
445           if (mem_size > K1SIZE)
446             mem_size = K1SIZE;
447           /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
448           sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
449                            K1BASE, K1SIZE, (long)mem_size, K0BASE);
450         }
451
452       device_init(sd);
453     }
454   else if (board != NULL
455            && (strcmp(board, BOARD_BSP) == 0))
456     {
457       int i;
458
459       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
460
461       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
462       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
463                        0x9FC00000, 
464                        4 * 1024 * 1024, /* 4 MB */
465                        0xBFC00000);
466
467       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
468       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
469                        0x80000000, 
470                        4 * 1024 * 1024, /* 4 MB */
471                        0xA0000000);
472
473       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
474       for (i=0; i<8; i++) /* 32 MB total */
475         {
476           unsigned size = 4 * 1024 * 1024;  /* 4 MB */
477           sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
478                            0x88000000 + (i * size), 
479                            size, 
480                            0xA8000000 + (i * size));
481         }
482     }
483 #if (WITH_HW)
484   else if (board != NULL
485            && (strcmp(board, BOARD_JMR3904) == 0 ||
486                strcmp(board, BOARD_JMR3904_PAL) == 0 ||
487                strcmp(board, BOARD_JMR3904_DEBUG) == 0))
488     {
489       /* match VIRTUAL memory layout of JMR-TX3904 board */
490       int i;
491
492       /* --- disable monitor unless forced on by user --- */
493
494       if (! firmware_option_p)
495         {
496           idt_monitor_base = 0;
497           pmon_monitor_base = 0;
498           lsipmon_monitor_base = 0;
499         }
500
501       /* --- environment --- */
502
503       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
504
505       /* --- memory --- */
506
507       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
508       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
509                        0x9FC00000, 
510                        4 * 1024 * 1024, /* 4 MB */
511                        0xBFC00000);
512
513       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
514       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
515                        0x80000000, 
516                        4 * 1024 * 1024, /* 4 MB */
517                        0xA0000000);
518
519       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
520       for (i=0; i<8; i++) /* 32 MB total */
521         {
522           unsigned size = 4 * 1024 * 1024;  /* 4 MB */
523           sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
524                            0x88000000 + (i * size), 
525                            size, 
526                            0xA8000000 + (i * size));
527         }
528
529       /* Dummy memory regions for unsimulated devices - sorted by address */
530
531       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
532       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
533       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
534       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
535       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
536       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
537       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
538       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
539       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
540
541
542       /* --- simulated devices --- */
543       sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
544       sim_hw_parse (sd, "/tx3904cpu");
545       sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
546       sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
547       sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
548       sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
549       {
550         /* FIXME: poking at dv-sockser internals, use tcp backend if
551          --sockser_addr option was given.*/
552         extern char* sockser_addr;
553         if(sockser_addr == NULL)
554           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
555         else
556           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
557       }
558       sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
559       sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
560
561       /* -- device connections --- */
562       sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
563       sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
564       sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
565       sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
566       sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
567       sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
568
569       /* add PAL timer & I/O module */
570       if(! strcmp(board, BOARD_JMR3904_PAL))
571         {
572          /* the device */
573          sim_hw_parse (sd, "/pal@0xffff0000");
574          sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
575
576          /* wire up interrupt ports to irc */
577          sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
578          sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
579          sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
580         }
581
582       if(! strcmp(board, BOARD_JMR3904_DEBUG))
583         {
584           /* -- DEBUG: glue interrupt generators --- */
585           sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
586           sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
587           sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
588           sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
589           sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
590           sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
591           sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
592           sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
593           sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
594           sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
595           sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
596           sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
597           sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
598           sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
599           sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
600           sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
601           sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
602           sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
603           sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
604         }
605
606       device_init(sd);
607     }
608 #endif
609
610   if (display_mem_info)
611     {
612       struct option_list * ol;
613       struct option_list * prev;
614
615       /* This is a hack.  We want to execute the real --memory-info command
616          line switch which is handled in common/sim-memopts.c, not the
617          override we have defined in this file.  So we remove the
618          mips_options array from the state options list.  This is safe
619          because we have now processed all of the command line.  */
620       for (ol = STATE_OPTIONS (sd), prev = NULL;
621            ol != NULL;
622            prev = ol, ol = ol->next)
623         if (ol->options == mips_options)
624           break;
625
626       SIM_ASSERT (ol != NULL);
627
628       if (prev == NULL)
629         STATE_OPTIONS (sd) = ol->next;
630       else
631         prev->next = ol->next;
632
633       sim_do_commandf (sd, "memory-info");
634     }
635
636   /* check for/establish the a reference program image */
637   if (sim_analyze_program (sd,
638                            (STATE_PROG_ARGV (sd) != NULL
639                             ? *STATE_PROG_ARGV (sd)
640                             : NULL),
641                            abfd) != SIM_RC_OK)
642     {
643       sim_module_uninstall (sd);
644       return 0;
645     }
646
647   /* Configure/verify the target byte order and other runtime
648      configuration options */
649   if (sim_config (sd) != SIM_RC_OK)
650     {
651       sim_module_uninstall (sd);
652       return 0;
653     }
654
655   if (sim_post_argv_init (sd) != SIM_RC_OK)
656     {
657       /* Uninstall the modules to avoid memory leaks,
658          file descriptor leaks, etc.  */
659       sim_module_uninstall (sd);
660       return 0;
661     }
662
663   /* verify assumptions the simulator made about the host type system.
664      This macro does not return if there is a problem */
665   SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
666   SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
667
668   /* This is NASTY, in that we are assuming the size of specific
669      registers: */
670   {
671     int rn;
672     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
673       {
674         if (rn < 32)
675           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
676         else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
677           cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
678         else if ((rn >= 33) && (rn <= 37))
679           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
680         else if ((rn == SRIDX)
681                  || (rn == FCR0IDX)
682                  || (rn == FCR31IDX)
683                  || ((rn >= 72) && (rn <= 89)))
684           cpu->register_widths[rn] = 32;
685         else
686           cpu->register_widths[rn] = 0;
687       }
688
689
690   }
691
692   if (STATE & simTRACE)
693     open_trace(sd);
694
695   /*
696   sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", 
697                   idt_monitor_base,
698                   pmon_monitor_base, 
699                   lsipmon_monitor_base);
700   */
701
702   /* Write the monitor trap address handlers into the monitor (eeprom)
703      address space.  This can only be done once the target endianness
704      has been determined. */
705   if (idt_monitor_base != 0)
706     {
707       unsigned loop;
708       unsigned idt_monitor_size = 1 << 11;
709
710       /* the default monitor region */
711       sim_do_commandf (sd, "memory region 0x%x,0x%x",
712                        idt_monitor_base, idt_monitor_size);
713
714       /* Entry into the IDT monitor is via fixed address vectors, and
715          not using machine instructions. To avoid clashing with use of
716          the MIPS TRAP system, we place our own (simulator specific)
717          "undefined" instructions into the relevant vector slots. */
718       for (loop = 0; (loop < idt_monitor_size); loop += 4)
719         {
720           address_word vaddr = (idt_monitor_base + loop);
721           unsigned32 insn = (RSVD_INSTRUCTION |
722                              (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
723                               << RSVD_INSTRUCTION_ARG_SHIFT));
724           H2T (insn);
725           sim_write (sd, vaddr, (unsigned char *)&insn, sizeof (insn));
726         }
727     }
728
729   if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
730     {
731     /* The PMON monitor uses the same address space, but rather than
732        branching into it the address of a routine is loaded. We can
733        cheat for the moment, and direct the PMON routine to IDT style
734        instructions within the monitor space. This relies on the IDT
735        monitor not using the locations from 0xBFC00500 onwards as its
736        entry points.*/
737       unsigned loop;
738       for (loop = 0; (loop < 24); loop++)
739         {
740           unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
741           switch (loop)
742             {
743             case 0: /* read */
744               value = 7;
745               break;
746             case 1: /* write */
747               value = 8;
748               break;
749             case 2: /* open */
750               value = 6;
751               break;
752             case 3: /* close */
753               value = 10;
754               break;
755             case 5: /* printf */
756               value = ((0x500 - 16) / 8); /* not an IDT reason code */
757               break;
758             case 8: /* cliexit */
759               value = 17;
760               break;
761             case 11: /* flush_cache */
762               value = 28;
763               break;
764           }
765
766         SIM_ASSERT (idt_monitor_base != 0);
767         value = ((unsigned int) idt_monitor_base + (value * 8));
768         H2T (value);
769
770         if (pmon_monitor_base != 0)
771           {
772             address_word vaddr = (pmon_monitor_base + (loop * 4));
773             sim_write (sd, vaddr, (unsigned char *)&value, sizeof (value));
774           }
775
776         if (lsipmon_monitor_base != 0)
777           {
778             address_word vaddr = (lsipmon_monitor_base + (loop * 4));
779             sim_write (sd, vaddr, (unsigned char *)&value, sizeof (value));
780           }
781       }
782
783   /* Write an abort sequence into the TRAP (common) exception vector
784      addresses.  This is to catch code executing a TRAP (et.al.)
785      instruction without installing a trap handler. */
786   if ((idt_monitor_base != 0) || 
787       (pmon_monitor_base != 0) || 
788       (lsipmon_monitor_base != 0))
789     {
790       unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
791                              HALT_INSTRUCTION /* BREAK */ };
792       H2T (halt[0]);
793       H2T (halt[1]);
794       sim_write (sd, 0x80000000, (unsigned char *) halt, sizeof (halt));
795       sim_write (sd, 0x80000180, (unsigned char *) halt, sizeof (halt));
796       sim_write (sd, 0x80000200, (unsigned char *) halt, sizeof (halt));
797       /* XXX: Write here unconditionally? */
798       sim_write (sd, 0xBFC00200, (unsigned char *) halt, sizeof (halt));
799       sim_write (sd, 0xBFC00380, (unsigned char *) halt, sizeof (halt));
800       sim_write (sd, 0xBFC00400, (unsigned char *) halt, sizeof (halt));
801     }
802   }
803
804   /* CPU specific initialization.  */
805   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
806     {
807       SIM_CPU *cpu = STATE_CPU (sd, i);
808
809       CPU_REG_FETCH (cpu) = mips_reg_fetch;
810       CPU_REG_STORE (cpu) = mips_reg_store;
811       CPU_PC_FETCH (cpu) = mips_pc_get;
812       CPU_PC_STORE (cpu) = mips_pc_set;
813     }
814
815   return sd;
816 }
817
818 #if WITH_TRACE_ANY_P
819 static void
820 open_trace (SIM_DESC sd)
821 {
822   tracefh = fopen(tracefile,"wb+");
823   if (tracefh == NULL)
824     {
825       sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
826       tracefh = stderr;
827   }
828 }
829 #endif
830
831 /* Return name of an insn, used by insn profiling.  */
832 static const char *
833 get_insn_name (sim_cpu *cpu, int i)
834 {
835   return itable[i].name;
836 }
837
838 void
839 mips_sim_close (SIM_DESC sd, int quitting)
840 {
841 #if WITH_TRACE_ANY_P
842   if (tracefh != NULL && tracefh != stderr)
843    fclose(tracefh);
844   tracefh = NULL;
845 #endif
846 }
847
848 static int
849 mips_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
850 {
851   /* NOTE: gdb (the client) stores registers in target byte order
852      while the simulator uses host byte order */
853
854   /* Unfortunately this suffers from the same problem as the register
855      numbering one. We need to know what the width of each logical
856      register number is for the architecture being simulated. */
857
858   if (cpu->register_widths[rn] == 0)
859     {
860       sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
861       return 0;
862     }
863
864   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
865     {
866       cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
867       if (cpu->register_widths[rn] == 32)
868         {
869           if (length == 8)
870             {
871               cpu->fgr[rn - FGR_BASE] = 
872                 (unsigned32) T2H_8 (*(unsigned64*)memory);
873               return 8;
874             }
875           else
876             {
877               cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
878               return 4;
879             }
880         }
881       else
882         {
883           if (length == 8)
884             {
885               cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
886               return 8;
887             }
888           else
889             {
890               cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
891               return 4;
892             }
893         }
894     }
895
896   if (cpu->register_widths[rn] == 32)
897     {
898       if (length == 8)
899         {
900           cpu->registers[rn] =
901             (unsigned32) T2H_8 (*(unsigned64*)memory);
902           return 8;
903         }
904       else
905         {
906           cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
907           return 4;
908         }
909     }
910   else
911     {
912       if (length == 8)
913         {
914           cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
915           return 8;
916         }
917       else
918         {
919           cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
920           return 4;
921         }
922     }
923
924   return 0;
925 }
926
927 static int
928 mips_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
929 {
930   /* NOTE: gdb (the client) stores registers in target byte order
931      while the simulator uses host byte order */
932
933   if (cpu->register_widths[rn] == 0)
934     {
935       sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
936       return 0;
937     }
938
939   /* Any floating point register */
940   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
941     {
942       if (cpu->register_widths[rn] == 32)
943         {
944           if (length == 8)
945             {
946               *(unsigned64*)memory =
947                 H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE]));
948               return 8;
949             }
950           else
951             {
952               *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
953               return 4;
954             }
955         }
956       else
957         {
958           if (length == 8)
959             {
960               *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
961               return 8;
962             }
963           else
964             {
965               *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
966               return 4;
967             }
968         }
969     }
970
971   if (cpu->register_widths[rn] == 32)
972     {
973       if (length == 8)
974         {
975           *(unsigned64*)memory =
976             H2T_8 ((unsigned32) (cpu->registers[rn]));
977           return 8;
978         }
979       else
980         {
981           *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
982           return 4;
983         }
984     }
985   else
986     {
987       if (length == 8)
988         {
989           *(unsigned64*)memory =
990             H2T_8 ((unsigned64) (cpu->registers[rn]));
991           return 8;
992         }
993       else
994         {
995           *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
996           return 4;
997         }
998     }
999
1000   return 0;
1001 }
1002
1003 SIM_RC
1004 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **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 <*/