OSDN Git Service

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