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