* simplify eCos testing
[platform/upstream/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    $Revision$
17    $Date$             
18
19 NOTEs:
20
21 The IDT monitor (found on the VR4300 board), seems to lie about
22 register contents. It seems to treat the registers as sign-extended
23 32-bit values. This cause *REAL* problems when single-stepping 64-bit
24 code on the hardware.
25
26 */
27
28 /* The TRACE manifests enable the provision of extra features. If they
29    are not defined then a simpler (quicker) simulator is constructed
30    without the required run-time checks, etc. */
31 #if 1 /* 0 to allow user build selection, 1 to force inclusion */
32 #define TRACE (1)
33 #endif
34
35 #include "bfd.h"
36 #include "sim-main.h"
37 #include "sim-utils.h"
38 #include "sim-options.h"
39 #include "sim-assert.h"
40 #include "sim-hw.h"
41
42 #include "itable.h"
43
44
45 #include "config.h"
46
47 #include <stdio.h>
48 #include <stdarg.h>
49 #include <ansidecl.h>
50 #include <ctype.h>
51 #include <limits.h>
52 #include <math.h>
53 #ifdef HAVE_STDLIB_H
54 #include <stdlib.h>
55 #endif
56 #ifdef HAVE_STRING_H
57 #include <string.h>
58 #else
59 #ifdef HAVE_STRINGS_H
60 #include <strings.h>
61 #endif
62 #endif
63
64 #include "getopt.h"
65 #include "libiberty.h"
66 #include "bfd.h"
67 #include "callback.h"   /* GDB simulator callback interface */
68 #include "remote-sim.h" /* GDB simulator interface */
69
70 #include "sysdep.h"
71
72 #ifndef PARAMS
73 #define PARAMS(x) 
74 #endif
75
76 char* pr_addr PARAMS ((SIM_ADDR addr));
77 char* pr_uword64 PARAMS ((uword64 addr));
78
79
80 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
81 #define CPU cpu
82 #define SD sd
83
84
85 /* The following reserved instruction value is used when a simulator
86    trap is required. NOTE: Care must be taken, since this value may be
87    used in later revisions of the MIPS ISA. */
88
89 #define RSVD_INSTRUCTION           (0x00000005)
90 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
91
92 #define RSVD_INSTRUCTION_ARG_SHIFT 6
93 #define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
94
95
96 /* Bits in the Debug register */
97 #define Debug_DBD 0x80000000   /* Debug Branch Delay */
98 #define Debug_DM  0x40000000   /* Debug Mode         */
99 #define Debug_DBp 0x00000002   /* Debug Breakpoint indicator */
100
101 /*---------------------------------------------------------------------------*/
102 /*-- GDB simulator interface ------------------------------------------------*/
103 /*---------------------------------------------------------------------------*/
104
105 static void ColdReset PARAMS((SIM_DESC sd));
106
107 /*---------------------------------------------------------------------------*/
108
109
110
111 #define DELAYSLOT()     {\
112                           if (STATE & simDELAYSLOT)\
113                             sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
114                           STATE |= simDELAYSLOT;\
115                         }
116
117 #define JALDELAYSLOT()  {\
118                           DELAYSLOT ();\
119                           STATE |= simJALDELAYSLOT;\
120                         }
121
122 #define NULLIFY()       {\
123                           STATE &= ~simDELAYSLOT;\
124                           STATE |= simSKIPNEXT;\
125                         }
126
127 #define CANCELDELAYSLOT() {\
128                             DSSTATE = 0;\
129                             STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
130                           }
131
132 #define INDELAYSLOT()   ((STATE & simDELAYSLOT) != 0)
133 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
134
135 /* Note that the monitor code essentially assumes this layout of memory.
136    If you change these, change the monitor code, too.  */
137 #define K0BASE  (0x80000000)
138 #define K0SIZE  (0x20000000)
139 #define K1BASE  (0xA0000000)
140 #define K1SIZE  (0x20000000)
141
142 /* Simple run-time monitor support.
143    
144    We emulate the monitor by placing magic reserved instructions at
145    the monitor's entry points; when we hit these instructions, instead
146    of raising an exception (as we would normally), we look at the
147    instruction and perform the appropriate monitory operation.
148    
149    `*_monitor_base' are the physical addresses at which the corresponding 
150         monitor vectors are located.  `0' means none.  By default,
151         install all three.
152     The RSVD_INSTRUCTION... macros specify the magic instructions we
153     use at the monitor entry points.  */
154 static int firmware_option_p = 0;
155 static SIM_ADDR idt_monitor_base =     0xBFC00000;
156 static SIM_ADDR pmon_monitor_base =    0xBFC00500;
157 static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
158
159 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
160
161
162 #define MEM_SIZE (2 << 20)
163
164
165 #if defined(TRACE)
166 static char *tracefile = "trace.din"; /* default filename for trace log */
167 FILE *tracefh = NULL;
168 static void open_trace PARAMS((SIM_DESC sd));
169 #endif /* TRACE */
170
171 static const char * get_insn_name (sim_cpu *, int);
172
173 /* simulation target board.  NULL=canonical */
174 static char* board = NULL;
175
176
177 static DECLARE_OPTION_HANDLER (mips_option_handler);
178
179 enum {
180   OPTION_DINERO_TRACE = OPTION_START,
181   OPTION_DINERO_FILE,
182   OPTION_FIRMWARE,
183   OPTION_BOARD
184 };
185
186
187 static SIM_RC
188 mips_option_handler (sd, cpu, opt, arg, is_command)
189      SIM_DESC sd;
190      sim_cpu *cpu;
191      int opt;
192      char *arg;
193      int is_command;
194 {
195   int cpu_nr;
196   switch (opt)
197     {
198     case OPTION_DINERO_TRACE: /* ??? */
199 #if defined(TRACE)
200       /* Eventually the simTRACE flag could be treated as a toggle, to
201          allow external control of the program points being traced
202          (i.e. only from main onwards, excluding the run-time setup,
203          etc.). */
204       for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
205         {
206           sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
207           if (arg == NULL)
208             STATE |= simTRACE;
209           else if (strcmp (arg, "yes") == 0)
210             STATE |= simTRACE;
211           else if (strcmp (arg, "no") == 0)
212             STATE &= ~simTRACE;
213           else if (strcmp (arg, "on") == 0)
214             STATE |= simTRACE;
215           else if (strcmp (arg, "off") == 0)
216             STATE &= ~simTRACE;
217           else
218             {
219               fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
220               return SIM_RC_FAIL;
221             }
222         }
223       return SIM_RC_OK;
224 #else /* !TRACE */
225       fprintf(stderr,"\
226 Simulator constructed without dinero tracing support (for performance).\n\
227 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
228       return SIM_RC_FAIL;
229 #endif /* !TRACE */
230
231     case OPTION_DINERO_FILE:
232 #if defined(TRACE)
233       if (optarg != NULL) {
234         char *tmp;
235         tmp = (char *)malloc(strlen(optarg) + 1);
236         if (tmp == NULL)
237           {
238             sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
239             return SIM_RC_FAIL;
240           }
241         else {
242           strcpy(tmp,optarg);
243           tracefile = tmp;
244           sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
245         }
246       }
247 #endif /* TRACE */
248       return SIM_RC_OK;
249
250     case OPTION_FIRMWARE:
251       return sim_firmware_command (sd, arg);
252
253     case OPTION_BOARD:
254       {
255         if (arg)
256           {
257             board = zalloc(strlen(arg) + 1);
258             strcpy(board, arg);
259           }
260         return SIM_RC_OK;
261       }
262     }
263   
264   return SIM_RC_OK;
265 }
266
267
268 static const OPTION mips_options[] =
269 {
270   { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
271       '\0', "on|off", "Enable dinero tracing",
272       mips_option_handler },
273   { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
274       '\0', "FILE", "Write dinero trace to FILE",
275       mips_option_handler },
276   { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
277     '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
278     mips_option_handler },
279   { {"board", required_argument, NULL, OPTION_BOARD},
280      '\0', "none" /* rely on compile-time string concatenation for other options */
281
282 #define BOARD_JMR3904 "jmr3904"
283            "|" BOARD_JMR3904
284 #define BOARD_JMR3904_PAL "jmr3904pal"
285            "|" BOARD_JMR3904_PAL
286 #define BOARD_JMR3904_DEBUG "jmr3904debug"
287            "|" BOARD_JMR3904_DEBUG
288 #define BOARD_BSP "bsp"
289            "|" BOARD_BSP
290
291     , "Customize simulation for a particular board.", mips_option_handler },
292
293   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
294 };
295
296
297 int interrupt_pending;
298
299 void
300 interrupt_event (SIM_DESC sd, void *data)
301 {
302   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
303   address_word cia = CIA_GET (cpu);
304   if (SR & status_IE)
305     {
306       interrupt_pending = 0;
307       SignalExceptionInterrupt (1); /* interrupt "1" */
308     }
309   else if (!interrupt_pending)
310     sim_events_schedule (sd, 1, interrupt_event, data);
311 }
312
313
314 /*---------------------------------------------------------------------------*/
315 /*-- Device registration hook -----------------------------------------------*/
316 /*---------------------------------------------------------------------------*/
317 static void device_init(SIM_DESC sd) {
318 #ifdef DEVICE_INIT
319   extern void register_devices(SIM_DESC);
320   register_devices(sd);
321 #endif
322 }
323
324 /*---------------------------------------------------------------------------*/
325 /*-- GDB simulator interface ------------------------------------------------*/
326 /*---------------------------------------------------------------------------*/
327
328 SIM_DESC
329 sim_open (kind, cb, abfd, argv)
330      SIM_OPEN_KIND kind;
331      host_callback *cb;
332      struct _bfd *abfd;
333      char **argv;
334 {
335   SIM_DESC sd = sim_state_alloc (kind, cb);
336   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
337
338   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
339
340   /* FIXME: watchpoints code shouldn't need this */
341   STATE_WATCHPOINTS (sd)->pc = &(PC);
342   STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
343   STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
344
345   /* Initialize the mechanism for doing insn profiling.  */
346   CPU_INSN_NAME (cpu) = get_insn_name;
347   CPU_MAX_INSNS (cpu) = nr_itable_entries;
348
349   STATE = 0;
350   
351   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
352     return 0;
353   sim_add_option_table (sd, NULL, mips_options);
354
355
356   /* getopt will print the error message so we just have to exit if this fails.
357      FIXME: Hmmm...  in the case of gdb we need getopt to call
358      print_filtered.  */
359   if (sim_parse_args (sd, argv) != SIM_RC_OK)
360     {
361       /* Uninstall the modules to avoid memory leaks,
362          file descriptor leaks, etc.  */
363       sim_module_uninstall (sd);
364       return 0;
365     }
366
367   /* handle board-specific memory maps */
368   if (board == NULL)
369     {
370       /* Allocate core managed memory */
371       
372
373       /* For compatibility with the old code - under this (at level one)
374          are the kernel spaces K0 & K1.  Both of these map to a single
375          smaller sub region */
376       sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
377       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
378                        K1BASE, K0SIZE,
379                        MEM_SIZE, /* actual size */
380                        K0BASE);
381       
382       device_init(sd);
383     }
384   else if (board != NULL
385            && (strcmp(board, BOARD_BSP) == 0))
386     {
387       int i;
388
389       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
390
391       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
392       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
393                        0x9FC00000, 
394                        4 * 1024 * 1024, /* 4 MB */
395                        0xBFC00000);
396
397       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
398       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
399                        0x80000000, 
400                        4 * 1024 * 1024, /* 4 MB */
401                        0xA0000000);
402
403       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
404       for (i=0; i<8; i++) /* 32 MB total */
405         {
406           unsigned size = 4 * 1024 * 1024;  /* 4 MB */
407           sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
408                            0x88000000 + (i * size), 
409                            size, 
410                            0xA8000000 + (i * size));
411         }
412     }
413 #if (WITH_HW)
414   else if (board != NULL
415            && (strcmp(board, BOARD_JMR3904) == 0 ||
416                strcmp(board, BOARD_JMR3904_PAL) == 0 ||
417                strcmp(board, BOARD_JMR3904_DEBUG) == 0))
418     {
419       /* match VIRTUAL memory layout of JMR-TX3904 board */
420       int i;
421
422       /* --- disable monitor unless forced on by user --- */
423
424       if (! firmware_option_p)
425         {
426           idt_monitor_base = 0;
427           pmon_monitor_base = 0;
428           lsipmon_monitor_base = 0;
429         }
430
431       /* --- environment --- */
432
433       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
434
435       /* --- memory --- */
436
437       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
438       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
439                        0x9FC00000, 
440                        4 * 1024 * 1024, /* 4 MB */
441                        0xBFC00000);
442
443       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
444       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
445                        0x80000000, 
446                        4 * 1024 * 1024, /* 4 MB */
447                        0xA0000000);
448
449       /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
450       for (i=0; i<8; i++) /* 32 MB total */
451         {
452           unsigned size = 4 * 1024 * 1024;  /* 4 MB */
453           sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
454                            0x88000000 + (i * size), 
455                            size, 
456                            0xA8000000 + (i * size));
457         }
458
459       /* Dummy memory regions for unsimulated devices - sorted by address */
460
461       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
462       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
463       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
464       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
465       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
466       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
467       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
468       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
469       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
470
471
472       /* --- simulated devices --- */
473       sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
474       sim_hw_parse (sd, "/tx3904cpu");
475       sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
476       sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
477       sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
478       sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
479       {
480         /* FIXME: poking at dv-sockser internals, use tcp backend if
481          --sockser_addr option was given.*/
482         extern char* sockser_addr;
483         if(sockser_addr == NULL)
484           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
485         else
486           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
487       }
488       sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
489       sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
490
491       /* -- device connections --- */
492       sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
493       sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
494       sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
495       sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
496       sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
497       sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
498
499       /* add PAL timer & I/O module */
500       if(! strcmp(board, BOARD_JMR3904_PAL))
501         {
502          /* the device */
503          sim_hw_parse (sd, "/pal@0xffff0000");
504          sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
505
506          /* wire up interrupt ports to irc */
507          sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
508          sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
509          sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
510         }
511
512       if(! strcmp(board, BOARD_JMR3904_DEBUG))
513         {
514           /* -- DEBUG: glue interrupt generators --- */
515           sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
516           sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
517           sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
518           sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
519           sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
520           sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
521           sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
522           sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
523           sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
524           sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
525           sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
526           sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
527           sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
528           sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
529           sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
530           sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
531           sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
532           sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
533           sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
534         }
535
536       device_init(sd);
537     }
538 #endif
539
540
541   /* check for/establish the a reference program image */
542   if (sim_analyze_program (sd,
543                            (STATE_PROG_ARGV (sd) != NULL
544                             ? *STATE_PROG_ARGV (sd)
545                             : NULL),
546                            abfd) != SIM_RC_OK)
547     {
548       sim_module_uninstall (sd);
549       return 0;
550     }
551
552   /* Configure/verify the target byte order and other runtime
553      configuration options */
554   if (sim_config (sd) != SIM_RC_OK)
555     {
556       sim_module_uninstall (sd);
557       return 0;
558     }
559
560   if (sim_post_argv_init (sd) != SIM_RC_OK)
561     {
562       /* Uninstall the modules to avoid memory leaks,
563          file descriptor leaks, etc.  */
564       sim_module_uninstall (sd);
565       return 0;
566     }
567
568   /* verify assumptions the simulator made about the host type system.
569      This macro does not return if there is a problem */
570   SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
571   SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
572
573   /* This is NASTY, in that we are assuming the size of specific
574      registers: */
575   {
576     int rn;
577     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
578       {
579         if (rn < 32)
580           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
581         else if ((rn >= FGRIDX) && (rn < (FGRIDX + NR_FGR)))
582           cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
583         else if ((rn >= 33) && (rn <= 37))
584           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
585         else if ((rn == SRIDX)
586                  || (rn == FCR0IDX)
587                  || (rn == FCR31IDX)
588                  || ((rn >= 72) && (rn <= 89)))
589           cpu->register_widths[rn] = 32;
590         else
591           cpu->register_widths[rn] = 0;
592       }
593
594
595   }
596
597 #if defined(TRACE)
598   if (STATE & simTRACE)
599     open_trace(sd);
600 #endif /* TRACE */
601
602   /*
603   sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", 
604                   idt_monitor_base,
605                   pmon_monitor_base, 
606                   lsipmon_monitor_base);
607   */
608
609   /* Write the monitor trap address handlers into the monitor (eeprom)
610      address space.  This can only be done once the target endianness
611      has been determined. */
612   if (idt_monitor_base != 0)
613     {
614       unsigned loop;
615       unsigned idt_monitor_size = 1 << 11;
616
617       /* the default monitor region */
618       sim_do_commandf (sd, "memory region 0x%x,0x%x",
619                        idt_monitor_base, idt_monitor_size);
620
621       /* Entry into the IDT monitor is via fixed address vectors, and
622          not using machine instructions. To avoid clashing with use of
623          the MIPS TRAP system, we place our own (simulator specific)
624          "undefined" instructions into the relevant vector slots. */
625       for (loop = 0; (loop < idt_monitor_size); loop += 4)
626         {
627           address_word vaddr = (idt_monitor_base + loop);
628           unsigned32 insn = (RSVD_INSTRUCTION |
629                              (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
630                               << RSVD_INSTRUCTION_ARG_SHIFT));
631           H2T (insn);
632           sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
633         }
634     }
635
636   if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
637     {
638     /* The PMON monitor uses the same address space, but rather than
639        branching into it the address of a routine is loaded. We can
640        cheat for the moment, and direct the PMON routine to IDT style
641        instructions within the monitor space. This relies on the IDT
642        monitor not using the locations from 0xBFC00500 onwards as its
643        entry points.*/
644       unsigned loop;
645       for (loop = 0; (loop < 24); loop++)
646         {
647           unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
648           switch (loop)
649             {
650             case 0: /* read */
651               value = 7;
652               break;
653             case 1: /* write */
654               value = 8;
655               break;
656             case 2: /* open */
657               value = 6;
658               break;
659             case 3: /* close */
660               value = 10;
661               break;
662             case 5: /* printf */
663               value = ((0x500 - 16) / 8); /* not an IDT reason code */
664               break;
665             case 8: /* cliexit */
666               value = 17;
667               break;
668             case 11: /* flush_cache */
669               value = 28;
670               break;
671           }
672
673         SIM_ASSERT (idt_monitor_base != 0);
674         value = ((unsigned int) idt_monitor_base + (value * 8));
675         H2T (value);
676
677         if (pmon_monitor_base != 0)
678           {
679             address_word vaddr = (pmon_monitor_base + (loop * 4));
680             sim_write (sd, vaddr, (char *)&value, sizeof (value));
681           }
682
683         if (lsipmon_monitor_base != 0)
684           {
685             address_word vaddr = (lsipmon_monitor_base + (loop * 4));
686             sim_write (sd, vaddr, (char *)&value, sizeof (value));
687           }
688       }
689
690   /* Write an abort sequence into the TRAP (common) exception vector
691      addresses.  This is to catch code executing a TRAP (et.al.)
692      instruction without installing a trap handler. */
693   if ((idt_monitor_base != 0) || 
694       (pmon_monitor_base != 0) || 
695       (lsipmon_monitor_base != 0))
696     {
697       unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
698                              HALT_INSTRUCTION /* BREAK */ };
699       H2T (halt[0]);
700       H2T (halt[1]);
701       sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
702       sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
703       sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
704       /* XXX: Write here unconditionally? */
705       sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
706       sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
707       sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
708     }
709   }
710
711
712
713   return sd;
714 }
715
716 #if defined(TRACE)
717 static void
718 open_trace(sd)
719      SIM_DESC sd;
720 {
721   tracefh = fopen(tracefile,"wb+");
722   if (tracefh == NULL)
723     {
724       sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
725       tracefh = stderr;
726   }
727 }
728 #endif /* TRACE */
729
730 /* Return name of an insn, used by insn profiling.  */
731 static const char *
732 get_insn_name (sim_cpu *cpu, int i)
733 {
734   return itable[i].name;
735 }
736
737 void
738 sim_close (sd, quitting)
739      SIM_DESC sd;
740      int quitting;
741 {
742 #ifdef DEBUG
743   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
744 #endif
745
746
747   /* "quitting" is non-zero if we cannot hang on errors */
748
749   /* shut down modules */
750   sim_module_uninstall (sd);
751
752   /* Ensure that any resources allocated through the callback
753      mechanism are released: */
754   sim_io_shutdown (sd);
755
756 #if defined(TRACE)
757   if (tracefh != NULL && tracefh != stderr)
758    fclose(tracefh);
759   tracefh = NULL;
760 #endif /* TRACE */
761
762   /* FIXME - free SD */
763
764   return;
765 }
766
767
768 int
769 sim_write (sd,addr,buffer,size)
770      SIM_DESC sd;
771      SIM_ADDR addr;
772      unsigned char *buffer;
773      int size;
774 {
775   int index;
776   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
777
778   /* Return the number of bytes written, or zero if error. */
779 #ifdef DEBUG
780   sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
781 #endif
782
783   /* We use raw read and write routines, since we do not want to count
784      the GDB memory accesses in our statistics gathering. */
785
786   for (index = 0; index < size; index++)
787     {
788       address_word vaddr = (address_word)addr + index;
789       address_word paddr;
790       int cca;
791       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
792         break;
793       if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
794         break;
795     }
796
797   return(index);
798 }
799
800 int
801 sim_read (sd,addr,buffer,size)
802      SIM_DESC sd;
803      SIM_ADDR addr;
804      unsigned char *buffer;
805      int size;
806 {
807   int index;
808   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
809
810   /* Return the number of bytes read, or zero if error. */
811 #ifdef DEBUG
812   sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
813 #endif /* DEBUG */
814
815   for (index = 0; (index < size); index++)
816     {
817       address_word vaddr = (address_word)addr + index;
818       address_word paddr;
819       int cca;
820       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
821         break;
822       if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
823         break;
824     }
825
826   return(index);
827 }
828
829 int
830 sim_store_register (sd,rn,memory,length)
831      SIM_DESC sd;
832      int rn;
833      unsigned char *memory;
834      int length;
835 {
836   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
837   /* NOTE: gdb (the client) stores registers in target byte order
838      while the simulator uses host byte order */
839 #ifdef DEBUG
840   sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
841 #endif /* DEBUG */
842
843   /* Unfortunately this suffers from the same problem as the register
844      numbering one. We need to know what the width of each logical
845      register number is for the architecture being simulated. */
846
847   if (cpu->register_widths[rn] == 0)
848     {
849       sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
850       return 0;
851     }
852
853
854
855   if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
856     {
857       cpu->fpr_state[rn - FGRIDX] = fmt_uninterpreted;
858       if (cpu->register_widths[rn] == 32)
859         {
860           if (length == 8)
861             {
862               cpu->fgr[rn - FGRIDX] = 
863                 (unsigned32) T2H_8 (*(unsigned64*)memory);
864               return 8;
865             }
866           else
867             {
868               cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
869               return 4;
870             }
871         }
872       else
873         {
874           cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
875           return 8;
876         }
877     }
878
879   if (cpu->register_widths[rn] == 32)
880     {
881       if (length == 8)
882         {
883           cpu->registers[rn] =
884             (unsigned32) T2H_8 (*(unsigned64*)memory);
885           return 8;
886         }
887       else
888         {
889           cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
890           return 4;
891         }
892     }
893   else
894     {
895       cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
896       return 8;
897     }
898
899   return 0;
900 }
901
902 int
903 sim_fetch_register (sd,rn,memory,length)
904      SIM_DESC sd;
905      int rn;
906      unsigned char *memory;
907      int length;
908 {
909   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
910   /* NOTE: gdb (the client) stores registers in target byte order
911      while the simulator uses host byte order */
912 #ifdef DEBUG
913 #if 0  /* FIXME: doesn't compile */
914   sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
915 #endif
916 #endif /* DEBUG */
917
918   if (cpu->register_widths[rn] == 0)
919     {
920       sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
921       return 0;
922     }
923
924
925
926   /* Any floating point register */
927   if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
928     {
929       if (cpu->register_widths[rn] == 32)
930         {
931           if (length == 8)
932             {
933               *(unsigned64*)memory =
934                 H2T_8 ((unsigned32) (cpu->fgr[rn - FGRIDX]));
935               return 8;
936             }
937           else
938             {
939               *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
940               return 4;
941             }
942         }
943       else
944         {
945           *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
946           return 8;
947         }
948     }
949
950   if (cpu->register_widths[rn] == 32)
951     {
952       if (length == 8)
953         {
954           *(unsigned64*)memory =
955             H2T_8 ((unsigned32) (cpu->registers[rn]));
956           return 8;
957         }
958       else
959         {
960           *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
961           return 4;
962         }
963     }
964   else
965     {
966       *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
967       return 8;
968     }
969
970   return 0;
971 }
972
973
974 SIM_RC
975 sim_create_inferior (sd, abfd, argv,env)
976      SIM_DESC sd;
977      struct _bfd *abfd;
978      char **argv;
979      char **env;
980 {
981
982 #ifdef DEBUG
983 #if 0 /* FIXME: doesn't compile */
984   printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
985          pr_addr(PC));
986 #endif
987 #endif /* DEBUG */
988
989   ColdReset(sd);
990
991   if (abfd != NULL)
992     {
993       /* override PC value set by ColdReset () */
994       int cpu_nr;
995       for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
996         {
997           sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
998           CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
999         }
1000     }
1001
1002 #if 0 /* def DEBUG */
1003   if (argv || env)
1004     {
1005       /* We should really place the argv slot values into the argument
1006          registers, and onto the stack as required. However, this
1007          assumes that we have a stack defined, which is not
1008          necessarily true at the moment. */
1009       char **cptr;
1010       sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1011       for (cptr = argv; (cptr && *cptr); cptr++)
1012         printf("DBG: arg \"%s\"\n",*cptr);
1013     }
1014 #endif /* DEBUG */
1015
1016   return SIM_RC_OK;
1017 }
1018
1019 void
1020 sim_do_command (sd,cmd)
1021      SIM_DESC sd;
1022      char *cmd;
1023 {
1024   if (sim_args_command (sd, cmd) != SIM_RC_OK)
1025     sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1026                    cmd);
1027 }
1028
1029 /*---------------------------------------------------------------------------*/
1030 /*-- Private simulator support interface ------------------------------------*/
1031 /*---------------------------------------------------------------------------*/
1032
1033 /* Read a null terminated string from memory, return in a buffer */
1034 static char *
1035 fetch_str (SIM_DESC sd,
1036            address_word addr)
1037 {
1038   char *buf;
1039   int nr = 0;
1040   char null;
1041   while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1042     nr++;
1043   buf = NZALLOC (char, nr + 1);
1044   sim_read (sd, addr, buf, nr);
1045   return buf;
1046 }
1047
1048
1049 /* Implements the "sim firmware" command:
1050         sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1051                 NAME can be idt, pmon, or lsipmon.  If omitted, ADDRESS
1052                 defaults to the normal address for that monitor.
1053         sim firmware none --- don't emulate any ROM monitor.  Useful
1054                 if you need a clean address space.  */
1055 static SIM_RC
1056 sim_firmware_command (SIM_DESC sd, char *arg)
1057 {
1058   int address_present = 0;
1059   SIM_ADDR address;
1060
1061   /* Signal occurrence of this option. */
1062   firmware_option_p = 1;
1063
1064   /* Parse out the address, if present.  */
1065   {
1066     char *p = strchr (arg, '@');
1067     if (p)
1068       {
1069         char *q;
1070         address_present = 1;
1071         p ++; /* skip over @ */
1072
1073         address = strtoul (p, &q, 0);
1074         if (*q != '\0') 
1075           {
1076             sim_io_printf (sd, "Invalid address given to the"
1077                            "`sim firmware NAME@ADDRESS' command: %s\n",
1078                            p);
1079             return SIM_RC_FAIL;
1080           }
1081       }
1082     else
1083       address_present = 0;
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 void
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() depreciated\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       sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1365                     reason, pr_addr(cia));
1366       break;
1367   }
1368   return;
1369 }
1370
1371 /* Store a word into memory.  */
1372
1373 static void
1374 store_word (SIM_DESC sd,
1375             sim_cpu *cpu,
1376             address_word cia,
1377             uword64 vaddr,
1378             signed_word val)
1379 {
1380   address_word paddr;
1381   int uncached;
1382
1383   if ((vaddr & 3) != 0)
1384     SignalExceptionAddressStore ();
1385   else
1386     {
1387       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1388                               isTARGET, isREAL))
1389         {
1390           const uword64 mask = 7;
1391           uword64 memval;
1392           unsigned int byte;
1393
1394           paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1395           byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1396           memval = ((uword64) val) << (8 * byte);
1397           StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1398                        isREAL);
1399         }
1400     }
1401 }
1402
1403 /* Load a word from memory.  */
1404
1405 static signed_word
1406 load_word (SIM_DESC sd,
1407            sim_cpu *cpu,
1408            address_word cia,
1409            uword64 vaddr)
1410 {
1411   if ((vaddr & 3) != 0)
1412     {
1413       SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1414     }
1415   else
1416     {
1417       address_word paddr;
1418       int uncached;
1419
1420       if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1421                               isTARGET, isREAL))
1422         {
1423           const uword64 mask = 0x7;
1424           const unsigned int reverse = ReverseEndian ? 1 : 0;
1425           const unsigned int bigend = BigEndianCPU ? 1 : 0;
1426           uword64 memval;
1427           unsigned int byte;
1428
1429           paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1430           LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1431                                isDATA, isREAL);
1432           byte = (vaddr & mask) ^ (bigend << 2);
1433           return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
1434         }
1435     }
1436
1437   return 0;
1438 }
1439
1440 /* Simulate the mips16 entry and exit pseudo-instructions.  These
1441    would normally be handled by the reserved instruction exception
1442    code, but for ease of simulation we just handle them directly.  */
1443
1444 static void
1445 mips16_entry (SIM_DESC sd,
1446               sim_cpu *cpu,
1447               address_word cia,
1448               unsigned int insn)
1449 {
1450   int aregs, sregs, rreg;
1451
1452 #ifdef DEBUG
1453   printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1454 #endif /* DEBUG */
1455
1456   aregs = (insn & 0x700) >> 8;
1457   sregs = (insn & 0x0c0) >> 6;
1458   rreg =  (insn & 0x020) >> 5;
1459
1460   /* This should be checked by the caller.  */
1461   if (sregs == 3)
1462     abort ();
1463
1464   if (aregs < 5)
1465     {
1466       int i;
1467       signed_word tsp;
1468
1469       /* This is the entry pseudo-instruction.  */
1470
1471       for (i = 0; i < aregs; i++)
1472         store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1473
1474       tsp = SP;
1475       SP -= 32;
1476
1477       if (rreg)
1478         {
1479           tsp -= 4;
1480           store_word (SD, CPU, cia, (uword64) tsp, RA);
1481         }
1482
1483       for (i = 0; i < sregs; i++)
1484         {
1485           tsp -= 4;
1486           store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1487         }
1488     }
1489   else
1490     {
1491       int i;
1492       signed_word tsp;
1493
1494       /* This is the exit pseudo-instruction.  */
1495
1496       tsp = SP + 32;
1497
1498       if (rreg)
1499         {
1500           tsp -= 4;
1501           RA = load_word (SD, CPU, cia, (uword64) tsp);
1502         }
1503
1504       for (i = 0; i < sregs; i++)
1505         {
1506           tsp -= 4;
1507           GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1508         }
1509
1510       SP += 32;
1511
1512       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1513         {
1514           if (aregs == 5)
1515             {
1516               FGR[0] = WORD64LO (GPR[4]);
1517               FPR_STATE[0] = fmt_uninterpreted;
1518             }
1519           else if (aregs == 6)
1520             {
1521               FGR[0] = WORD64LO (GPR[5]);
1522               FGR[1] = WORD64LO (GPR[4]);
1523               FPR_STATE[0] = fmt_uninterpreted;
1524               FPR_STATE[1] = fmt_uninterpreted;
1525             }
1526         }         
1527
1528       PC = RA;
1529     }
1530   
1531 }
1532
1533 /*-- trace support ----------------------------------------------------------*/
1534
1535 /* The TRACE support is provided (if required) in the memory accessing
1536    routines. Since we are also providing the architecture specific
1537    features, the architecture simulation code can also deal with
1538    notifying the TRACE world of cache flushes, etc. Similarly we do
1539    not need to provide profiling support in the simulator engine,
1540    since we can sample in the instruction fetch control loop. By
1541    defining the TRACE manifest, we add tracing as a run-time
1542    option. */
1543
1544 #if defined(TRACE)
1545 /* Tracing by default produces "din" format (as required by
1546    dineroIII). Each line of such a trace file *MUST* have a din label
1547    and address field. The rest of the line is ignored, so comments can
1548    be included if desired. The first field is the label which must be
1549    one of the following values:
1550
1551         0       read data
1552         1       write data
1553         2       instruction fetch
1554         3       escape record (treated as unknown access type)
1555         4       escape record (causes cache flush)
1556
1557    The address field is a 32bit (lower-case) hexadecimal address
1558    value. The address should *NOT* be preceded by "0x".
1559
1560    The size of the memory transfer is not important when dealing with
1561    cache lines (as long as no more than a cache line can be
1562    transferred in a single operation :-), however more information
1563    could be given following the dineroIII requirement to allow more
1564    complete memory and cache simulators to provide better
1565    results. i.e. the University of Pisa has a cache simulator that can
1566    also take bus size and speed as (variable) inputs to calculate
1567    complete system performance (a much more useful ability when trying
1568    to construct an end product, rather than a processor). They
1569    currently have an ARM version of their tool called ChARM. */
1570
1571
1572 void
1573 dotrace (SIM_DESC sd,
1574          sim_cpu *cpu,
1575          FILE *tracefh,
1576          int type,
1577          SIM_ADDR address,
1578          int width,
1579          char *comment,...)
1580 {
1581   if (STATE & simTRACE) {
1582     va_list ap;
1583     fprintf(tracefh,"%d %s ; width %d ; ", 
1584                 type,
1585                 pr_addr(address),
1586                 width);
1587     va_start(ap,comment);
1588     vfprintf(tracefh,comment,ap);
1589     va_end(ap);
1590     fprintf(tracefh,"\n");
1591   }
1592   /* NOTE: Since the "din" format will only accept 32bit addresses, and
1593      we may be generating 64bit ones, we should put the hi-32bits of the
1594      address into the comment field. */
1595
1596   /* TODO: Provide a buffer for the trace lines. We can then avoid
1597      performing writes until the buffer is filled, or the file is
1598      being closed. */
1599
1600   /* NOTE: We could consider adding a comment field to the "din" file
1601      produced using type 3 markers (unknown access). This would then
1602      allow information about the program that the "din" is for, and
1603      the MIPs world that was being simulated, to be placed into the
1604      trace file. */
1605
1606   return;
1607 }
1608 #endif /* TRACE */
1609
1610 /*---------------------------------------------------------------------------*/
1611 /*-- simulator engine -------------------------------------------------------*/
1612 /*---------------------------------------------------------------------------*/
1613
1614 static void
1615 ColdReset (SIM_DESC sd)
1616 {
1617   int cpu_nr;
1618   for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1619     {
1620       sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1621       /* RESET: Fixed PC address: */
1622       PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1623       /* The reset vector address is in the unmapped, uncached memory space. */
1624       
1625       SR &= ~(status_SR | status_TS | status_RP);
1626       SR |= (status_ERL | status_BEV);
1627       
1628       /* Cheat and allow access to the complete register set immediately */
1629       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1630           && WITH_TARGET_WORD_BITSIZE == 64)
1631         SR |= status_FR; /* 64bit registers */
1632       
1633       /* Ensure that any instructions with pending register updates are
1634          cleared: */
1635       PENDING_INVALIDATE();
1636       
1637       /* Initialise the FPU registers to the unknown state */
1638       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1639         {
1640           int rn;
1641           for (rn = 0; (rn < 32); rn++)
1642             FPR_STATE[rn] = fmt_uninterpreted;
1643         }
1644       
1645     }
1646 }
1647
1648
1649
1650
1651 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1652 /* Signal an exception condition. This will result in an exception
1653    that aborts the instruction. The instruction operation pseudocode
1654    will never see a return from this function call. */
1655
1656 void
1657 signal_exception (SIM_DESC sd,
1658                   sim_cpu *cpu,
1659                   address_word cia,
1660                   int exception,...)
1661 {
1662   /* int vector; */
1663
1664 #ifdef DEBUG
1665   sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1666 #endif /* DEBUG */
1667
1668   /* Ensure that any active atomic read/modify/write operation will fail: */
1669   LLBIT = 0;
1670
1671   /* Save registers before interrupt dispatching */
1672 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1673   SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1674 #endif
1675
1676   switch (exception) {
1677
1678     case DebugBreakPoint :
1679       if (! (Debug & Debug_DM))
1680         {
1681           if (INDELAYSLOT())
1682             {
1683               CANCELDELAYSLOT();
1684               
1685               Debug |= Debug_DBD;  /* signaled from within in delay slot */
1686               DEPC = cia - 4;      /* reference the branch instruction */
1687             }
1688           else
1689             {
1690               Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1691               DEPC = cia;
1692             }
1693         
1694           Debug |= Debug_DM;            /* in debugging mode */
1695           Debug |= Debug_DBp;           /* raising a DBp exception */
1696           PC = 0xBFC00200;
1697           sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1698         }
1699       break;
1700
1701     case ReservedInstruction :
1702      {
1703        va_list ap;
1704        unsigned int instruction;
1705        va_start(ap,exception);
1706        instruction = va_arg(ap,unsigned int);
1707        va_end(ap);
1708        /* Provide simple monitor support using ReservedInstruction
1709           exceptions. The following code simulates the fixed vector
1710           entry points into the IDT monitor by causing a simulator
1711           trap, performing the monitor operation, and returning to
1712           the address held in the $ra register (standard PCS return
1713           address). This means we only need to pre-load the vector
1714           space with suitable instruction values. For systems were
1715           actual trap instructions are used, we would not need to
1716           perform this magic. */
1717        if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1718          {
1719            sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
1720            /* NOTE: This assumes that a branch-and-link style
1721               instruction was used to enter the vector (which is the
1722               case with the current IDT monitor). */
1723            sim_engine_restart (SD, CPU, NULL, RA);
1724          }
1725        /* Look for the mips16 entry and exit instructions, and
1726           simulate a handler for them.  */
1727        else if ((cia & 1) != 0
1728                 && (instruction & 0xf81f) == 0xe809
1729                 && (instruction & 0x0c0) != 0x0c0)
1730          {
1731            mips16_entry (SD, CPU, cia, instruction);
1732            sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1733          }
1734        /* else fall through to normal exception processing */
1735        sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1736      }
1737
1738     default:
1739      /* Store exception code into current exception id variable (used
1740         by exit code): */
1741
1742      /* TODO: If not simulating exceptions then stop the simulator
1743         execution. At the moment we always stop the simulation. */
1744
1745 #ifdef SUBTARGET_R3900
1746       /* update interrupt-related registers */
1747
1748       /* insert exception code in bits 6:2 */
1749       CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1750       /* shift IE/KU history bits left */
1751       SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1752
1753       if (STATE & simDELAYSLOT)
1754         {
1755           STATE &= ~simDELAYSLOT;
1756           CAUSE |= cause_BD;
1757           EPC = (cia - 4); /* reference the branch instruction */
1758         }
1759       else
1760         EPC = cia;
1761
1762      if (SR & status_BEV)
1763        PC = (signed)0xBFC00000 + 0x180;
1764      else
1765        PC = (signed)0x80000000 + 0x080;
1766 #else
1767      /* See figure 5-17 for an outline of the code below */
1768      if (! (SR & status_EXL))
1769        {
1770          CAUSE = (exception << 2);
1771          if (STATE & simDELAYSLOT)
1772            {
1773              STATE &= ~simDELAYSLOT;
1774              CAUSE |= cause_BD;
1775              EPC = (cia - 4); /* reference the branch instruction */
1776            }
1777          else
1778            EPC = cia;
1779          /* FIXME: TLB et.al. */
1780          /* vector = 0x180; */
1781        }
1782      else
1783        {
1784          CAUSE = (exception << 2);
1785          /* vector = 0x180; */
1786        }
1787      SR |= status_EXL;
1788      /* Store exception code into current exception id variable (used
1789         by exit code): */
1790
1791      if (SR & status_BEV)
1792        PC = (signed)0xBFC00200 + 0x180;
1793      else
1794        PC = (signed)0x80000000 + 0x180;
1795 #endif
1796
1797      switch ((CAUSE >> 2) & 0x1F)
1798        {
1799        case Interrupt:
1800          /* Interrupts arrive during event processing, no need to
1801             restart */
1802          return;
1803
1804        case NMIReset:
1805          /* Ditto */
1806 #ifdef SUBTARGET_3900
1807          /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000  */
1808          PC = (signed)0xBFC00000;
1809 #endif SUBTARGET_3900
1810          return;
1811
1812        case TLBModification:
1813        case TLBLoad:
1814        case TLBStore:
1815        case AddressLoad:
1816        case AddressStore:
1817        case InstructionFetch:
1818        case DataReference:
1819          /* The following is so that the simulator will continue from the
1820             exception handler address. */
1821          sim_engine_halt (SD, CPU, NULL, PC,
1822                           sim_stopped, SIM_SIGBUS);
1823
1824        case ReservedInstruction:
1825        case CoProcessorUnusable:
1826          PC = EPC;
1827          sim_engine_halt (SD, CPU, NULL, PC,
1828                           sim_stopped, SIM_SIGILL);
1829
1830        case IntegerOverflow:
1831        case FPE:
1832          sim_engine_halt (SD, CPU, NULL, PC,
1833                           sim_stopped, SIM_SIGFPE);
1834          
1835        case BreakPoint:
1836          sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
1837          break;
1838
1839        case SystemCall:
1840        case Trap:
1841          sim_engine_restart (SD, CPU, NULL, PC);
1842          break;
1843
1844        case Watch:
1845          PC = EPC;
1846          sim_engine_halt (SD, CPU, NULL, PC,
1847                           sim_stopped, SIM_SIGTRAP);
1848
1849        default : /* Unknown internal exception */
1850          PC = EPC;
1851          sim_engine_halt (SD, CPU, NULL, PC,
1852                           sim_stopped, SIM_SIGABRT);
1853
1854        }
1855
1856     case SimulatorFault:
1857      {
1858        va_list ap;
1859        char *msg;
1860        va_start(ap,exception);
1861        msg = va_arg(ap,char *);
1862        va_end(ap);
1863        sim_engine_abort (SD, CPU, NULL_CIA,
1864                          "FATAL: Simulator error \"%s\"\n",msg);
1865      }
1866    }
1867
1868   return;
1869 }
1870
1871
1872
1873 #if defined(WARN_RESULT)
1874 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1875 /* This function indicates that the result of the operation is
1876    undefined. However, this should not affect the instruction
1877    stream. All that is meant to happen is that the destination
1878    register is set to an undefined result. To keep the simulator
1879    simple, we just don't bother updating the destination register, so
1880    the overall result will be undefined. If desired we can stop the
1881    simulator by raising a pseudo-exception. */
1882 #define UndefinedResult() undefined_result (sd,cia)
1883 static void
1884 undefined_result(sd,cia)
1885      SIM_DESC sd;
1886      address_word cia;
1887 {
1888   sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
1889 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1890   state |= simSTOP;
1891 #endif
1892   return;
1893 }
1894 #endif /* WARN_RESULT */
1895
1896 /*-- FPU support routines ---------------------------------------------------*/
1897
1898 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1899    formats conform to ANSI/IEEE Std 754-1985. */
1900 /* SINGLE precision floating:
1901  *    seeeeeeeefffffffffffffffffffffff
1902  *      s =  1bit  = sign
1903  *      e =  8bits = exponent
1904  *      f = 23bits = fraction
1905  */
1906 /* SINGLE precision fixed:
1907  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1908  *      s =  1bit  = sign
1909  *      i = 31bits = integer
1910  */
1911 /* DOUBLE precision floating:
1912  *    seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1913  *      s =  1bit  = sign
1914  *      e = 11bits = exponent
1915  *      f = 52bits = fraction
1916  */
1917 /* DOUBLE precision fixed:
1918  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1919  *      s =  1bit  = sign
1920  *      i = 63bits = integer
1921  */
1922
1923 /* Extract sign-bit: */
1924 #define FP_S_s(v)    (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1925 #define FP_D_s(v)    (((v) & ((uword64)1 << 63)) ? 1 : 0)
1926 /* Extract biased exponent: */
1927 #define FP_S_be(v)   (((v) >> 23) & 0xFF)
1928 #define FP_D_be(v)   (((v) >> 52) & 0x7FF)
1929 /* Extract unbiased Exponent: */
1930 #define FP_S_e(v)    (FP_S_be(v) - 0x7F)
1931 #define FP_D_e(v)    (FP_D_be(v) - 0x3FF)
1932 /* Extract complete fraction field: */
1933 #define FP_S_f(v)    ((v) & ~((unsigned)0x1FF << 23))
1934 #define FP_D_f(v)    ((v) & ~((uword64)0xFFF << 52))
1935 /* Extract numbered fraction bit: */
1936 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1937 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1938
1939 /* Explicit QNaN values used when value required: */
1940 #define FPQNaN_SINGLE   (0x7FBFFFFF)
1941 #define FPQNaN_WORD     (0x7FFFFFFF)
1942 #define FPQNaN_DOUBLE   (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1943 #define FPQNaN_LONG     (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1944
1945 /* Explicit Infinity values used when required: */
1946 #define FPINF_SINGLE    (0x7F800000)
1947 #define FPINF_DOUBLE    (((uword64)0x7FF00000 << 32) | 0x00000000)
1948
1949 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1950 #define DOFMT(v)  (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : (((v) == fmt_uninterpreted_32) ? "<uninterpreted_32>" : (((v) == fmt_uninterpreted_64) ? "<uninterpreted_64>" : "<format error>"))))))))
1951
1952 uword64
1953 value_fpr (SIM_DESC sd,
1954            sim_cpu *cpu,
1955            address_word cia,
1956            int fpr,
1957            FP_formats fmt)
1958 {
1959   uword64 value = 0;
1960   int err = 0;
1961
1962   /* Treat unused register values, as fixed-point 64bit values: */
1963   if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
1964 #if 1
1965    /* If request to read data as "uninterpreted", then use the current
1966       encoding: */
1967    fmt = FPR_STATE[fpr];
1968 #else
1969    fmt = fmt_long;
1970 #endif
1971
1972   /* For values not yet accessed, set to the desired format: */
1973   if (FPR_STATE[fpr] == fmt_uninterpreted) {
1974     FPR_STATE[fpr] = fmt;
1975 #ifdef DEBUG
1976     printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
1977 #endif /* DEBUG */
1978   }
1979   if (fmt != FPR_STATE[fpr]) {
1980     sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(cia));
1981     FPR_STATE[fpr] = fmt_unknown;
1982   }
1983
1984   if (FPR_STATE[fpr] == fmt_unknown) {
1985    /* Set QNaN value: */
1986    switch (fmt) {
1987     case fmt_single:
1988      value = FPQNaN_SINGLE;
1989      break;
1990
1991     case fmt_double:
1992      value = FPQNaN_DOUBLE;
1993      break;
1994
1995     case fmt_word:
1996      value = FPQNaN_WORD;
1997      break;
1998
1999     case fmt_long:
2000      value = FPQNaN_LONG;
2001      break;
2002
2003     default:
2004      err = -1;
2005      break;
2006    }
2007   } else if (SizeFGR() == 64) {
2008     switch (fmt) {
2009      case fmt_single:
2010      case fmt_word:
2011       value = (FGR[fpr] & 0xFFFFFFFF);
2012       break;
2013
2014      case fmt_uninterpreted:
2015      case fmt_double:
2016      case fmt_long:
2017       value = FGR[fpr];
2018       break;
2019
2020      default :
2021       err = -1;
2022       break;
2023     }
2024   } else {
2025     switch (fmt) {
2026      case fmt_single:
2027      case fmt_word:
2028       value = (FGR[fpr] & 0xFFFFFFFF);
2029       break;
2030
2031      case fmt_uninterpreted:
2032      case fmt_double:
2033      case fmt_long:
2034       if ((fpr & 1) == 0) { /* even registers only */
2035 #ifdef DEBUG
2036         printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n", 
2037                fpr+1, pr_uword64( (uword64) FGR[fpr+1] ),
2038                fpr, pr_uword64( (uword64) FGR[fpr] ));
2039 #endif
2040         value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
2041       } else {
2042         SignalException(ReservedInstruction,0);
2043       }
2044       break;
2045
2046      default :
2047       err = -1;
2048       break;
2049     }
2050   }
2051
2052   if (err)
2053    SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2054
2055 #ifdef DEBUG
2056   printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
2057 #endif /* DEBUG */
2058
2059   return(value);
2060 }
2061
2062 void
2063 store_fpr (SIM_DESC sd,
2064            sim_cpu *cpu,
2065            address_word cia,
2066            int fpr,
2067            FP_formats fmt,
2068            uword64 value)
2069 {
2070   int err = 0;
2071
2072 #ifdef DEBUG
2073   printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d,\n",fpr,DOFMT(fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
2074 #endif /* DEBUG */
2075
2076   if (SizeFGR() == 64) {
2077     switch (fmt) {
2078       case fmt_uninterpreted_32:
2079         fmt = fmt_uninterpreted;
2080       case fmt_single :
2081       case fmt_word :
2082        if (STATE_VERBOSE_P(SD))
2083          sim_io_eprintf (SD, "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
2084            pr_addr(cia));
2085        FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
2086        FPR_STATE[fpr] = fmt;
2087        break;
2088
2089       case fmt_uninterpreted_64:
2090         fmt = fmt_uninterpreted;
2091       case fmt_uninterpreted:
2092       case fmt_double :
2093       case fmt_long :
2094        FGR[fpr] = value;
2095        FPR_STATE[fpr] = fmt;
2096        break;
2097
2098       default :
2099        FPR_STATE[fpr] = fmt_unknown;
2100        err = -1;
2101        break;
2102     }
2103   } else {
2104     switch (fmt) {
2105       case fmt_uninterpreted_32:
2106         fmt = fmt_uninterpreted;
2107       case fmt_single :
2108       case fmt_word :
2109        FGR[fpr] = (value & 0xFFFFFFFF);
2110        FPR_STATE[fpr] = fmt;
2111        break;
2112
2113       case fmt_uninterpreted_64:
2114         fmt = fmt_uninterpreted;
2115       case fmt_uninterpreted:
2116       case fmt_double :
2117       case fmt_long :
2118         if ((fpr & 1) == 0) { /* even register number only */
2119           FGR[fpr+1] = (value >> 32);
2120           FGR[fpr] = (value & 0xFFFFFFFF);
2121           FPR_STATE[fpr + 1] = fmt;
2122           FPR_STATE[fpr] = fmt;
2123         } else {
2124           FPR_STATE[fpr] = fmt_unknown;
2125           FPR_STATE[fpr + 1] = fmt_unknown;
2126           SignalException(ReservedInstruction,0);
2127         }
2128        break;
2129
2130       default :
2131        FPR_STATE[fpr] = fmt_unknown;
2132        err = -1;
2133        break;
2134     }
2135   }
2136 #if defined(WARN_RESULT)
2137   else
2138     UndefinedResult();
2139 #endif /* WARN_RESULT */
2140
2141   if (err)
2142    SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2143
2144 #ifdef DEBUG
2145   printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_uword64(FGR[fpr]),DOFMT(fmt));
2146 #endif /* DEBUG */
2147
2148   return;
2149 }
2150
2151 int
2152 NaN(op,fmt)
2153      uword64 op;
2154      FP_formats fmt; 
2155 {
2156   int boolean = 0;
2157   switch (fmt) {
2158    case fmt_single:
2159    case fmt_word:
2160     {
2161       sim_fpu wop;
2162       sim_fpu_32to (&wop, op);
2163       boolean = sim_fpu_is_nan (&wop);
2164       break;
2165     }
2166    case fmt_double:
2167    case fmt_long:
2168     {
2169       sim_fpu wop;
2170       sim_fpu_64to (&wop, op);
2171       boolean = sim_fpu_is_nan (&wop);
2172       break;
2173     }
2174    default:
2175     fprintf (stderr, "Bad switch\n");
2176     abort ();
2177   }
2178
2179 #ifdef DEBUG
2180 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2181 #endif /* DEBUG */
2182
2183   return(boolean);
2184 }
2185
2186 int
2187 Infinity(op,fmt)
2188      uword64 op;
2189      FP_formats fmt; 
2190 {
2191   int boolean = 0;
2192
2193 #ifdef DEBUG
2194   printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
2195 #endif /* DEBUG */
2196
2197   switch (fmt) {
2198    case fmt_single:
2199     {
2200       sim_fpu wop;
2201       sim_fpu_32to (&wop, op);
2202       boolean = sim_fpu_is_infinity (&wop);
2203       break;
2204     }
2205    case fmt_double:
2206     {
2207       sim_fpu wop;
2208       sim_fpu_64to (&wop, op);
2209       boolean = sim_fpu_is_infinity (&wop);
2210       break;
2211     }
2212    default:
2213     printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
2214     break;
2215   }
2216
2217 #ifdef DEBUG
2218   printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2219 #endif /* DEBUG */
2220
2221   return(boolean);
2222 }
2223
2224 int
2225 Less(op1,op2,fmt)
2226      uword64 op1;
2227      uword64 op2;
2228      FP_formats fmt; 
2229 {
2230   int boolean = 0;
2231
2232   /* Argument checking already performed by the FPCOMPARE code */
2233
2234 #ifdef DEBUG
2235   printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2236 #endif /* DEBUG */
2237
2238   /* The format type should already have been checked: */
2239   switch (fmt) {
2240    case fmt_single:
2241     {
2242       sim_fpu wop1;
2243       sim_fpu wop2;
2244       sim_fpu_32to (&wop1, op1);
2245       sim_fpu_32to (&wop2, op2);
2246       boolean = sim_fpu_is_lt (&wop1, &wop2);
2247       break;
2248     }
2249    case fmt_double:
2250     {
2251       sim_fpu wop1;
2252       sim_fpu wop2;
2253       sim_fpu_64to (&wop1, op1);
2254       sim_fpu_64to (&wop2, op2);
2255       boolean = sim_fpu_is_lt (&wop1, &wop2);
2256       break;
2257     }
2258    default:
2259     fprintf (stderr, "Bad switch\n");
2260     abort ();
2261   }
2262
2263 #ifdef DEBUG
2264   printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2265 #endif /* DEBUG */
2266
2267   return(boolean);
2268 }
2269
2270 int
2271 Equal(op1,op2,fmt)
2272      uword64 op1;
2273      uword64 op2;
2274      FP_formats fmt; 
2275 {
2276   int boolean = 0;
2277
2278   /* Argument checking already performed by the FPCOMPARE code */
2279
2280 #ifdef DEBUG
2281   printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2282 #endif /* DEBUG */
2283
2284   /* The format type should already have been checked: */
2285   switch (fmt) {
2286    case fmt_single:
2287     {
2288       sim_fpu wop1;
2289       sim_fpu wop2;
2290       sim_fpu_32to (&wop1, op1);
2291       sim_fpu_32to (&wop2, op2);
2292       boolean = sim_fpu_is_eq (&wop1, &wop2);
2293       break;
2294     }
2295    case fmt_double:
2296     {
2297       sim_fpu wop1;
2298       sim_fpu wop2;
2299       sim_fpu_64to (&wop1, op1);
2300       sim_fpu_64to (&wop2, op2);
2301       boolean = sim_fpu_is_eq (&wop1, &wop2);
2302       break;
2303     }
2304    default:
2305     fprintf (stderr, "Bad switch\n");
2306     abort ();
2307   }
2308
2309 #ifdef DEBUG
2310   printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2311 #endif /* DEBUG */
2312
2313   return(boolean);
2314 }
2315
2316 uword64
2317 AbsoluteValue(op,fmt)
2318      uword64 op;
2319      FP_formats fmt; 
2320 {
2321   uword64 result = 0;
2322
2323 #ifdef DEBUG
2324   printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2325 #endif /* DEBUG */
2326
2327   /* The format type should already have been checked: */
2328   switch (fmt) {
2329    case fmt_single:
2330     {
2331       sim_fpu wop;
2332       unsigned32 ans;
2333       sim_fpu_32to (&wop, op);
2334       sim_fpu_abs (&wop, &wop);
2335       sim_fpu_to32 (&ans, &wop);
2336       result = ans;
2337       break;
2338     }
2339    case fmt_double:
2340     {
2341       sim_fpu wop;
2342       unsigned64 ans;
2343       sim_fpu_64to (&wop, op);
2344       sim_fpu_abs (&wop, &wop);
2345       sim_fpu_to64 (&ans, &wop);
2346       result = ans;
2347       break;
2348     }
2349    default:
2350     fprintf (stderr, "Bad switch\n");
2351     abort ();
2352   }
2353
2354   return(result);
2355 }
2356
2357 uword64
2358 Negate(op,fmt)
2359      uword64 op;
2360      FP_formats fmt; 
2361 {
2362   uword64 result = 0;
2363
2364 #ifdef DEBUG
2365   printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2366 #endif /* DEBUG */
2367
2368   /* The format type should already have been checked: */
2369   switch (fmt) {
2370    case fmt_single:
2371     {
2372       sim_fpu wop;
2373       unsigned32 ans;
2374       sim_fpu_32to (&wop, op);
2375       sim_fpu_neg (&wop, &wop);
2376       sim_fpu_to32 (&ans, &wop);
2377       result = ans;
2378       break;
2379     }
2380    case fmt_double:
2381     {
2382       sim_fpu wop;
2383       unsigned64 ans;
2384       sim_fpu_64to (&wop, op);
2385       sim_fpu_neg (&wop, &wop);
2386       sim_fpu_to64 (&ans, &wop);
2387       result = ans;
2388       break;
2389     }
2390    default:
2391     fprintf (stderr, "Bad switch\n");
2392     abort ();
2393   }
2394
2395   return(result);
2396 }
2397
2398 uword64
2399 Add(op1,op2,fmt)
2400      uword64 op1;
2401      uword64 op2;
2402      FP_formats fmt; 
2403 {
2404   uword64 result = 0;
2405
2406 #ifdef DEBUG
2407   printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2408 #endif /* DEBUG */
2409
2410   /* The registers must specify FPRs valid for operands of type
2411      "fmt". If they are not valid, the result is undefined. */
2412
2413   /* The format type should already have been checked: */
2414   switch (fmt) {
2415    case fmt_single:
2416     {
2417       sim_fpu wop1;
2418       sim_fpu wop2;
2419       sim_fpu ans;
2420       unsigned32 res;
2421       sim_fpu_32to (&wop1, op1);
2422       sim_fpu_32to (&wop2, op2);
2423       sim_fpu_add (&ans, &wop1, &wop2);
2424       sim_fpu_to32 (&res, &ans);
2425       result = res;
2426       break;
2427     }
2428    case fmt_double:
2429     {
2430       sim_fpu wop1;
2431       sim_fpu wop2;
2432       sim_fpu ans;
2433       unsigned64 res;
2434       sim_fpu_64to (&wop1, op1);
2435       sim_fpu_64to (&wop2, op2);
2436       sim_fpu_add (&ans, &wop1, &wop2);
2437       sim_fpu_to64 (&res, &ans);
2438       result = res;
2439       break;
2440     }
2441    default:
2442     fprintf (stderr, "Bad switch\n");
2443     abort ();
2444   }
2445
2446 #ifdef DEBUG
2447   printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2448 #endif /* DEBUG */
2449
2450   return(result);
2451 }
2452
2453 uword64
2454 Sub(op1,op2,fmt)
2455      uword64 op1;
2456      uword64 op2;
2457      FP_formats fmt; 
2458 {
2459   uword64 result = 0;
2460
2461 #ifdef DEBUG
2462   printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2463 #endif /* DEBUG */
2464
2465   /* The registers must specify FPRs valid for operands of type
2466      "fmt". If they are not valid, the result is undefined. */
2467
2468   /* The format type should already have been checked: */
2469   switch (fmt) {
2470    case fmt_single:
2471     {
2472       sim_fpu wop1;
2473       sim_fpu wop2;
2474       sim_fpu ans;
2475       unsigned32 res;
2476       sim_fpu_32to (&wop1, op1);
2477       sim_fpu_32to (&wop2, op2);
2478       sim_fpu_sub (&ans, &wop1, &wop2);
2479       sim_fpu_to32 (&res, &ans);
2480       result = res;
2481     }
2482     break;
2483    case fmt_double:
2484     {
2485       sim_fpu wop1;
2486       sim_fpu wop2;
2487       sim_fpu ans;
2488       unsigned64 res;
2489       sim_fpu_64to (&wop1, op1);
2490       sim_fpu_64to (&wop2, op2);
2491       sim_fpu_sub (&ans, &wop1, &wop2);
2492       sim_fpu_to64 (&res, &ans);
2493       result = res;
2494     }
2495     break;
2496    default:
2497     fprintf (stderr, "Bad switch\n");
2498     abort ();
2499   }
2500
2501 #ifdef DEBUG
2502   printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2503 #endif /* DEBUG */
2504
2505   return(result);
2506 }
2507
2508 uword64
2509 Multiply(op1,op2,fmt)
2510      uword64 op1;
2511      uword64 op2;
2512      FP_formats fmt; 
2513 {
2514   uword64 result = 0;
2515
2516 #ifdef DEBUG
2517   printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2518 #endif /* DEBUG */
2519
2520   /* The registers must specify FPRs valid for operands of type
2521      "fmt". If they are not valid, the result is undefined. */
2522
2523   /* The format type should already have been checked: */
2524   switch (fmt) {
2525    case fmt_single:
2526     {
2527       sim_fpu wop1;
2528       sim_fpu wop2;
2529       sim_fpu ans;
2530       unsigned32 res;
2531       sim_fpu_32to (&wop1, op1);
2532       sim_fpu_32to (&wop2, op2);
2533       sim_fpu_mul (&ans, &wop1, &wop2);
2534       sim_fpu_to32 (&res, &ans);
2535       result = res;
2536       break;
2537     }
2538    case fmt_double:
2539     {
2540       sim_fpu wop1;
2541       sim_fpu wop2;
2542       sim_fpu ans;
2543       unsigned64 res;
2544       sim_fpu_64to (&wop1, op1);
2545       sim_fpu_64to (&wop2, op2);
2546       sim_fpu_mul (&ans, &wop1, &wop2);
2547       sim_fpu_to64 (&res, &ans);
2548       result = res;
2549       break;
2550     }
2551    default:
2552     fprintf (stderr, "Bad switch\n");
2553     abort ();
2554   }
2555
2556 #ifdef DEBUG
2557   printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2558 #endif /* DEBUG */
2559
2560   return(result);
2561 }
2562
2563 uword64
2564 Divide(op1,op2,fmt)
2565      uword64 op1;
2566      uword64 op2;
2567      FP_formats fmt; 
2568 {
2569   uword64 result = 0;
2570
2571 #ifdef DEBUG
2572   printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2573 #endif /* DEBUG */
2574
2575   /* The registers must specify FPRs valid for operands of type
2576      "fmt". If they are not valid, the result is undefined. */
2577
2578   /* The format type should already have been checked: */
2579   switch (fmt) {
2580    case fmt_single:
2581     {
2582       sim_fpu wop1;
2583       sim_fpu wop2;
2584       sim_fpu ans;
2585       unsigned32 res;
2586       sim_fpu_32to (&wop1, op1);
2587       sim_fpu_32to (&wop2, op2);
2588       sim_fpu_div (&ans, &wop1, &wop2);
2589       sim_fpu_to32 (&res, &ans);
2590       result = res;
2591       break;
2592     }
2593    case fmt_double:
2594     {
2595       sim_fpu wop1;
2596       sim_fpu wop2;
2597       sim_fpu ans;
2598       unsigned64 res;
2599       sim_fpu_64to (&wop1, op1);
2600       sim_fpu_64to (&wop2, op2);
2601       sim_fpu_div (&ans, &wop1, &wop2);
2602       sim_fpu_to64 (&res, &ans);
2603       result = res;
2604       break;
2605     }
2606    default:
2607     fprintf (stderr, "Bad switch\n");
2608     abort ();
2609   }
2610
2611 #ifdef DEBUG
2612   printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2613 #endif /* DEBUG */
2614
2615   return(result);
2616 }
2617
2618 uword64 UNUSED
2619 Recip(op,fmt)
2620      uword64 op;
2621      FP_formats fmt; 
2622 {
2623   uword64 result = 0;
2624
2625 #ifdef DEBUG
2626   printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2627 #endif /* DEBUG */
2628
2629   /* The registers must specify FPRs valid for operands of type
2630      "fmt". If they are not valid, the result is undefined. */
2631
2632   /* The format type should already have been checked: */
2633   switch (fmt) {
2634    case fmt_single:
2635     {
2636       sim_fpu wop;
2637       sim_fpu ans;
2638       unsigned32 res;
2639       sim_fpu_32to (&wop, op);
2640       sim_fpu_inv (&ans, &wop);
2641       sim_fpu_to32 (&res, &ans);
2642       result = res;
2643       break;
2644     }
2645    case fmt_double:
2646     {
2647       sim_fpu wop;
2648       sim_fpu ans;
2649       unsigned64 res;
2650       sim_fpu_64to (&wop, op);
2651       sim_fpu_inv (&ans, &wop);
2652       sim_fpu_to64 (&res, &ans);
2653       result = res;
2654       break;
2655     }
2656    default:
2657     fprintf (stderr, "Bad switch\n");
2658     abort ();
2659   }
2660
2661 #ifdef DEBUG
2662   printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2663 #endif /* DEBUG */
2664
2665   return(result);
2666 }
2667
2668 uword64
2669 SquareRoot(op,fmt)
2670      uword64 op;
2671      FP_formats fmt; 
2672 {
2673   uword64 result = 0;
2674
2675 #ifdef DEBUG
2676   printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2677 #endif /* DEBUG */
2678
2679   /* The registers must specify FPRs valid for operands of type
2680      "fmt". If they are not valid, the result is undefined. */
2681
2682   /* The format type should already have been checked: */
2683   switch (fmt) {
2684    case fmt_single:
2685     {
2686       sim_fpu wop;
2687       sim_fpu ans;
2688       unsigned32 res;
2689       sim_fpu_32to (&wop, op);
2690       sim_fpu_sqrt (&ans, &wop);
2691       sim_fpu_to32 (&res, &ans);
2692       result = res;
2693       break;
2694     }
2695    case fmt_double:
2696     {
2697       sim_fpu wop;
2698       sim_fpu ans;
2699       unsigned64 res;
2700       sim_fpu_64to (&wop, op);
2701       sim_fpu_sqrt (&ans, &wop);
2702       sim_fpu_to64 (&res, &ans);
2703       result = res;
2704       break;
2705     }
2706    default:
2707     fprintf (stderr, "Bad switch\n");
2708     abort ();
2709   }
2710
2711 #ifdef DEBUG
2712   printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2713 #endif /* DEBUG */
2714
2715   return(result);
2716 }
2717
2718 #if 0
2719 uword64
2720 Max (uword64 op1,
2721      uword64 op2,
2722      FP_formats fmt)
2723 {
2724   int cmp;
2725   unsigned64 result;
2726
2727 #ifdef DEBUG
2728   printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2729 #endif /* DEBUG */
2730
2731   /* The registers must specify FPRs valid for operands of type
2732      "fmt". If they are not valid, the result is undefined. */
2733
2734   /* The format type should already have been checked: */
2735   switch (fmt)
2736     {
2737     case fmt_single:
2738       {
2739         sim_fpu wop1;
2740         sim_fpu wop2;
2741         sim_fpu_32to (&wop1, op1);
2742         sim_fpu_32to (&wop2, op2);
2743         cmp = sim_fpu_cmp (&wop1, &wop2);
2744         break;
2745       }
2746     case fmt_double:
2747       {
2748         sim_fpu wop1;
2749         sim_fpu wop2;
2750         sim_fpu_64to (&wop1, op1);
2751         sim_fpu_64to (&wop2, op2);
2752         cmp = sim_fpu_cmp (&wop1, &wop2);
2753         break;
2754       }
2755     default:
2756       fprintf (stderr, "Bad switch\n");
2757       abort ();
2758     }
2759   
2760   switch (cmp)
2761     {
2762     case SIM_FPU_IS_SNAN:
2763     case SIM_FPU_IS_QNAN:
2764       result = op1;
2765     case SIM_FPU_IS_NINF:
2766     case SIM_FPU_IS_NNUMBER:
2767     case SIM_FPU_IS_NDENORM:
2768     case SIM_FPU_IS_NZERO:
2769       result = op2; /* op1 - op2 < 0 */
2770     case SIM_FPU_IS_PINF:
2771     case SIM_FPU_IS_PNUMBER:
2772     case SIM_FPU_IS_PDENORM:
2773     case SIM_FPU_IS_PZERO:
2774       result = op1; /* op1 - op2 > 0 */
2775     default:
2776       fprintf (stderr, "Bad switch\n");
2777       abort ();
2778     }
2779
2780 #ifdef DEBUG
2781   printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2782 #endif /* DEBUG */
2783
2784   return(result);
2785 }
2786 #endif 
2787
2788 #if 0
2789 uword64
2790 Min (uword64 op1,
2791      uword64 op2,
2792      FP_formats fmt)
2793 {
2794   int cmp;
2795   unsigned64 result;
2796
2797 #ifdef DEBUG
2798   printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2799 #endif /* DEBUG */
2800
2801   /* The registers must specify FPRs valid for operands of type
2802      "fmt". If they are not valid, the result is undefined. */
2803
2804   /* The format type should already have been checked: */
2805   switch (fmt)
2806     {
2807     case fmt_single:
2808       {
2809         sim_fpu wop1;
2810         sim_fpu wop2;
2811         sim_fpu_32to (&wop1, op1);
2812         sim_fpu_32to (&wop2, op2);
2813         cmp = sim_fpu_cmp (&wop1, &wop2);
2814         break;
2815       }
2816     case fmt_double:
2817       {
2818         sim_fpu wop1;
2819         sim_fpu wop2;
2820         sim_fpu_64to (&wop1, op1);
2821         sim_fpu_64to (&wop2, op2);
2822         cmp = sim_fpu_cmp (&wop1, &wop2);
2823         break;
2824       }
2825     default:
2826       fprintf (stderr, "Bad switch\n");
2827       abort ();
2828     }
2829   
2830   switch (cmp)
2831     {
2832     case SIM_FPU_IS_SNAN:
2833     case SIM_FPU_IS_QNAN:
2834       result = op1;
2835     case SIM_FPU_IS_NINF:
2836     case SIM_FPU_IS_NNUMBER:
2837     case SIM_FPU_IS_NDENORM:
2838     case SIM_FPU_IS_NZERO:
2839       result = op1; /* op1 - op2 < 0 */
2840     case SIM_FPU_IS_PINF:
2841     case SIM_FPU_IS_PNUMBER:
2842     case SIM_FPU_IS_PDENORM:
2843     case SIM_FPU_IS_PZERO:
2844       result = op2; /* op1 - op2 > 0 */
2845     default:
2846       fprintf (stderr, "Bad switch\n");
2847       abort ();
2848     }
2849
2850 #ifdef DEBUG
2851   printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2852 #endif /* DEBUG */
2853
2854   return(result);
2855 }
2856 #endif
2857
2858 uword64
2859 convert (SIM_DESC sd,
2860          sim_cpu *cpu,
2861          address_word cia,
2862          int rm,
2863          uword64 op,
2864          FP_formats from,
2865          FP_formats to)
2866 {
2867   sim_fpu wop;
2868   sim_fpu_round round;
2869   unsigned32 result32;
2870   unsigned64 result64;
2871
2872 #ifdef DEBUG
2873 #if 0 /* FIXME: doesn't compile */
2874   printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm),pr_addr(op),DOFMT(from),DOFMT(to),pr_addr(IPC));
2875 #endif
2876 #endif /* DEBUG */
2877
2878   switch (rm)
2879     {
2880     case FP_RM_NEAREST:
2881       /* Round result to nearest representable value. When two
2882          representable values are equally near, round to the value
2883          that has a least significant bit of zero (i.e. is even). */
2884       round = sim_fpu_round_near;
2885       break;
2886     case FP_RM_TOZERO:
2887       /* Round result to the value closest to, and not greater in
2888          magnitude than, the result. */
2889       round = sim_fpu_round_zero;
2890       break;
2891     case FP_RM_TOPINF:
2892       /* Round result to the value closest to, and not less than,
2893          the result. */
2894       round = sim_fpu_round_up;
2895       break;
2896       
2897     case FP_RM_TOMINF:
2898       /* Round result to the value closest to, and not greater than,
2899          the result. */
2900       round = sim_fpu_round_down;
2901       break;
2902     default:
2903       round = 0;
2904       fprintf (stderr, "Bad switch\n");
2905       abort ();
2906     }
2907   
2908   /* Convert the input to sim_fpu internal format */
2909   switch (from)
2910     {
2911     case fmt_double:
2912       sim_fpu_64to (&wop, op);
2913       break;
2914     case fmt_single:
2915       sim_fpu_32to (&wop, op);
2916       break;
2917     case fmt_word:
2918       sim_fpu_i32to (&wop, op, round);
2919       break;
2920     case fmt_long:
2921       sim_fpu_i64to (&wop, op, round);
2922       break;
2923     default:
2924       fprintf (stderr, "Bad switch\n");
2925       abort ();
2926     }
2927
2928   /* Convert sim_fpu format into the output */
2929   /* The value WOP is converted to the destination format, rounding
2930      using mode RM. When the destination is a fixed-point format, then
2931      a source value of Infinity, NaN or one which would round to an
2932      integer outside the fixed point range then an IEEE Invalid
2933      Operation condition is raised. */
2934   switch (to)
2935     {
2936     case fmt_single:
2937       sim_fpu_round_32 (&wop, round, 0);
2938       sim_fpu_to32 (&result32, &wop);
2939       result64 = result32;
2940       break;
2941     case fmt_double:
2942       sim_fpu_round_64 (&wop, round, 0);
2943       sim_fpu_to64 (&result64, &wop);
2944       break;
2945     case fmt_word:
2946       sim_fpu_to32i (&result32, &wop, round);
2947       result64 = result32;
2948       break;
2949     case fmt_long:
2950       sim_fpu_to64i (&result64, &wop, round);
2951       break;
2952     default:
2953       result64 = 0;
2954       fprintf (stderr, "Bad switch\n");
2955       abort ();
2956     }
2957  
2958 #ifdef DEBUG
2959   printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
2960 #endif /* DEBUG */
2961
2962   return(result64);
2963 }
2964
2965
2966 /*-- co-processor support routines ------------------------------------------*/
2967
2968 static int UNUSED
2969 CoProcPresent(unsigned int coproc_number)
2970 {
2971   /* Return TRUE if simulator provides a model for the given co-processor number */
2972   return(0);
2973 }
2974
2975 void
2976 cop_lw (SIM_DESC sd,
2977         sim_cpu *cpu,
2978         address_word cia,
2979         int coproc_num,
2980         int coproc_reg,
2981         unsigned int memword)
2982 {
2983   switch (coproc_num)
2984     {
2985     case 1:
2986       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2987         {
2988 #ifdef DEBUG
2989           printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2990 #endif
2991           StoreFPR(coproc_reg,fmt_word,(uword64)memword);
2992           FPR_STATE[coproc_reg] = fmt_uninterpreted;
2993           break;
2994         }
2995
2996     default:
2997 #if 0 /* this should be controlled by a configuration option */
2998       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));
2999 #endif
3000       break;
3001     }
3002
3003   return;
3004 }
3005
3006 void
3007 cop_ld (SIM_DESC sd,
3008         sim_cpu *cpu,
3009         address_word cia,
3010         int coproc_num,
3011         int coproc_reg,
3012         uword64 memword)
3013 {
3014
3015 #ifdef DEBUG
3016   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) );
3017 #endif
3018
3019   switch (coproc_num) {
3020     case 1:
3021       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3022         {
3023           StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3024           break;
3025         }
3026
3027     default:
3028 #if 0 /* this message should be controlled by a configuration option */
3029      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));
3030 #endif
3031      break;
3032   }
3033
3034   return;
3035 }
3036
3037
3038
3039
3040 unsigned int
3041 cop_sw (SIM_DESC sd,
3042         sim_cpu *cpu,
3043         address_word cia,
3044         int coproc_num,
3045         int coproc_reg)
3046 {
3047   unsigned int value = 0;
3048
3049   switch (coproc_num)
3050     {
3051     case 1:
3052       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3053         {
3054           FP_formats hold;
3055           hold = FPR_STATE[coproc_reg];
3056           FPR_STATE[coproc_reg] = fmt_word;
3057           value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
3058           FPR_STATE[coproc_reg] = hold;
3059           break;
3060         }
3061
3062     default:
3063 #if 0 /* should be controlled by configuration option */
3064       sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3065 #endif
3066       break;
3067     }
3068
3069   return(value);
3070 }
3071
3072 uword64
3073 cop_sd (SIM_DESC sd,
3074         sim_cpu *cpu,
3075         address_word cia,
3076         int coproc_num,
3077         int coproc_reg)
3078 {
3079   uword64 value = 0;
3080   switch (coproc_num)
3081     {
3082     case 1:
3083       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3084         {
3085           value = ValueFPR(coproc_reg,fmt_uninterpreted);
3086           break;
3087         }
3088
3089     default:
3090 #if 0 /* should be controlled by configuration option */
3091       sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3092 #endif
3093       break;
3094     }
3095
3096   return(value);
3097 }
3098
3099
3100
3101
3102 void
3103 decode_coproc (SIM_DESC sd,
3104                sim_cpu *cpu,
3105                address_word cia,
3106                unsigned int instruction)
3107 {
3108   int coprocnum = ((instruction >> 26) & 3);
3109
3110   switch (coprocnum)
3111     {
3112     case 0: /* standard CPU control and cache registers */
3113       {
3114         int code = ((instruction >> 21) & 0x1F);
3115         int rt = ((instruction >> 16) & 0x1F);
3116         int rd = ((instruction >> 11) & 0x1F);
3117         int tail = instruction & 0x3ff;
3118         /* R4000 Users Manual (second edition) lists the following CP0
3119            instructions:
3120                                                                    CODE><-RT><RD-><--TAIL--->
3121            DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
3122            DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
3123            MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
3124            MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
3125            TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
3126            TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
3127            TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
3128            TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
3129            CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3130            ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
3131            */
3132         if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */        
3133              || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */        
3134             && tail == 0)
3135           {
3136             /* Clear double/single coprocessor move bit. */
3137             code &= ~1;
3138
3139             /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
3140             
3141             switch (rd)  /* NOTEs: Standard CP0 registers */
3142               {
3143                 /* 0 = Index               R4000   VR4100  VR4300 */
3144                 /* 1 = Random              R4000   VR4100  VR4300 */
3145                 /* 2 = EntryLo0            R4000   VR4100  VR4300 */
3146                 /* 3 = EntryLo1            R4000   VR4100  VR4300 */
3147                 /* 4 = Context             R4000   VR4100  VR4300 */
3148                 /* 5 = PageMask            R4000   VR4100  VR4300 */
3149                 /* 6 = Wired               R4000   VR4100  VR4300 */
3150                 /* 8 = BadVAddr            R4000   VR4100  VR4300 */
3151                 /* 9 = Count               R4000   VR4100  VR4300 */
3152                 /* 10 = EntryHi            R4000   VR4100  VR4300 */
3153                 /* 11 = Compare            R4000   VR4100  VR4300 */
3154                 /* 12 = SR                 R4000   VR4100  VR4300 */
3155 #ifdef SUBTARGET_R3900
3156               case 3:
3157                 /* 3 = Config              R3900                  */
3158               case 7:
3159                 /* 7 = Cache               R3900                  */
3160               case 15:
3161                 /* 15 = PRID               R3900                  */
3162
3163                 /* ignore */
3164                 break;
3165
3166               case 8:
3167                 /* 8 = BadVAddr            R4000   VR4100  VR4300 */
3168                 if (code == 0x00)
3169                   GPR[rt] = COP0_BADVADDR;
3170                 else
3171                   COP0_BADVADDR = GPR[rt];
3172                 break;
3173
3174 #endif /* SUBTARGET_R3900 */
3175               case 12:
3176                 if (code == 0x00)
3177                   GPR[rt] = SR;
3178                 else
3179                   SR = GPR[rt];
3180                 break;
3181                 /* 13 = Cause              R4000   VR4100  VR4300 */
3182               case 13:
3183                 if (code == 0x00)
3184                   GPR[rt] = CAUSE;
3185                 else
3186                   CAUSE = GPR[rt];
3187                 break;
3188                 /* 14 = EPC                R4000   VR4100  VR4300 */
3189               case 14:
3190                 if (code == 0x00)
3191                   GPR[rt] = (signed_word) (signed_address) EPC;
3192                 else
3193                   EPC = GPR[rt];
3194                 break;
3195                 /* 15 = PRId               R4000   VR4100  VR4300 */
3196 #ifdef SUBTARGET_R3900
3197                 /* 16 = Debug */
3198               case 16:
3199                 if (code == 0x00)
3200                   GPR[rt] = Debug;
3201                 else
3202                   Debug = GPR[rt];
3203                 break;
3204 #else
3205                 /* 16 = Config             R4000   VR4100  VR4300 */
3206               case 16:
3207                 if (code == 0x00)
3208                   GPR[rt] = C0_CONFIG;
3209                 else
3210                   C0_CONFIG = GPR[rt];
3211                 break;
3212 #endif
3213 #ifdef SUBTARGET_R3900
3214                 /* 17 = Debug */
3215               case 17:
3216                 if (code == 0x00)
3217                   GPR[rt] = DEPC;
3218                 else
3219                   DEPC = GPR[rt];
3220                 break;
3221 #else
3222                 /* 17 = LLAddr             R4000   VR4100  VR4300 */
3223 #endif
3224                 /* 18 = WatchLo            R4000   VR4100  VR4300 */
3225                 /* 19 = WatchHi            R4000   VR4100  VR4300 */
3226                 /* 20 = XContext           R4000   VR4100  VR4300 */
3227                 /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
3228                 /* 27 = CacheErr           R4000   VR4100 */
3229                 /* 28 = TagLo              R4000   VR4100  VR4300 */
3230                 /* 29 = TagHi              R4000   VR4100  VR4300 */
3231                 /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
3232                 if (STATE_VERBOSE_P(SD))
3233                   sim_io_eprintf (SD, 
3234                     "Warning: PC 0x%s:interp.c decode_coproc DEADC0DE\n",
3235                       (unsigned)cia);
3236                 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
3237                 /* CPR[0,rd] = GPR[rt]; */
3238               default:
3239                 if (code == 0x00)
3240                   GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
3241                 else
3242                   COP0_GPR[rd] = GPR[rt];
3243 #if 0
3244                 if (code == 0x00)
3245                   sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
3246                 else
3247                   sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
3248 #endif
3249               }
3250           }
3251         else if (code == 0x10 && (tail & 0x3f) == 0x18)
3252           {
3253             /* ERET */
3254             if (SR & status_ERL)
3255               {
3256                 /* Oops, not yet available */
3257                 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
3258                 PC = EPC;
3259                 SR &= ~status_ERL;
3260               }
3261             else
3262               {
3263                 PC = EPC;
3264                 SR &= ~status_EXL;
3265               }
3266           }
3267         else if (code == 0x10 && (tail & 0x3f) == 0x10)
3268           {
3269             /* RFE */
3270 #ifdef SUBTARGET_R3900
3271             /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3272
3273             /* shift IE/KU history bits right */
3274             SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
3275
3276             /* TODO: CACHE register */
3277 #endif /* SUBTARGET_R3900 */
3278           }
3279         else if (code == 0x10 && (tail & 0x3f) == 0x1F)
3280           {
3281             /* DERET */
3282             Debug &= ~Debug_DM;
3283             DELAYSLOT();
3284             DSPC = DEPC;
3285           }
3286         else
3287           sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
3288         /* TODO: When executing an ERET or RFE instruction we should
3289            clear LLBIT, to ensure that any out-standing atomic
3290            read/modify/write sequence fails. */
3291       }
3292     break;
3293     
3294     case 2: /* co-processor 2 */
3295       {
3296         int handle = 0;
3297
3298
3299         if(! handle)
3300           {
3301             sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3302                            instruction,pr_addr(cia));
3303           }
3304       }
3305     break;
3306     
3307     case 1: /* should not occur (FPU co-processor) */
3308     case 3: /* should not occur (FPU co-processor) */
3309       SignalException(ReservedInstruction,instruction);
3310       break;
3311     }
3312   
3313   return;
3314 }
3315
3316
3317 /* This code copied from gdb's utils.c.  Would like to share this code,
3318    but don't know of a common place where both could get to it. */
3319
3320 /* Temporary storage using circular buffer */
3321 #define NUMCELLS 16
3322 #define CELLSIZE 32
3323 static char*
3324 get_cell (void)
3325 {
3326   static char buf[NUMCELLS][CELLSIZE];
3327   static int cell=0;
3328   if (++cell>=NUMCELLS) cell=0;
3329   return buf[cell];
3330 }     
3331
3332 /* Print routines to handle variable size regs, etc */
3333
3334 /* Eliminate warning from compiler on 32-bit systems */
3335 static int thirty_two = 32;     
3336
3337 char* 
3338 pr_addr(addr)
3339   SIM_ADDR addr;
3340 {
3341   char *paddr_str=get_cell();
3342   switch (sizeof(addr))
3343     {
3344       case 8:
3345         sprintf(paddr_str,"%08lx%08lx",
3346                 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3347         break;
3348       case 4:
3349         sprintf(paddr_str,"%08lx",(unsigned long)addr);
3350         break;
3351       case 2:
3352         sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
3353         break;
3354       default:
3355         sprintf(paddr_str,"%x",addr);
3356     }
3357   return paddr_str;
3358 }
3359
3360 char* 
3361 pr_uword64(addr)
3362   uword64 addr;
3363 {
3364   char *paddr_str=get_cell();
3365   sprintf(paddr_str,"%08lx%08lx",
3366           (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3367   return paddr_str;
3368 }
3369
3370
3371 void
3372 mips_core_signal (SIM_DESC sd,
3373                  sim_cpu *cpu,
3374                  sim_cia cia,
3375                  unsigned map,
3376                  int nr_bytes,
3377                  address_word addr,
3378                  transfer_type transfer,
3379                  sim_core_signals sig)
3380 {
3381   const char *copy = (transfer == read_transfer ? "read" : "write");
3382   address_word ip = CIA_ADDR (cia);
3383
3384   switch (sig)
3385     {
3386     case sim_core_unmapped_signal:
3387       sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
3388                       nr_bytes, copy, 
3389                       (unsigned long) addr, (unsigned long) ip);
3390       COP0_BADVADDR = addr;
3391       SignalExceptionDataReference();
3392       break;
3393
3394     case sim_core_unaligned_signal:
3395       sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
3396                       nr_bytes, copy, 
3397                       (unsigned long) addr, (unsigned long) ip);
3398       COP0_BADVADDR = addr;
3399       if(transfer == read_transfer) 
3400         SignalExceptionAddressLoad();
3401       else
3402         SignalExceptionAddressStore();
3403       break;
3404
3405     default:
3406       sim_engine_abort (sd, cpu, cia,
3407                         "mips_core_signal - internal error - bad switch");
3408     }
3409 }
3410
3411
3412 void
3413 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
3414 {
3415   ASSERT(cpu != NULL);
3416
3417   if(cpu->exc_suspended > 0)
3418     sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended); 
3419
3420   PC = cia;
3421   memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
3422   cpu->exc_suspended = 0;
3423 }
3424
3425 void
3426 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
3427 {
3428   ASSERT(cpu != NULL);
3429
3430   if(cpu->exc_suspended > 0)
3431     sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n", 
3432                    cpu->exc_suspended, exception); 
3433
3434   memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
3435   memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
3436   cpu->exc_suspended = exception;
3437 }
3438
3439 void
3440 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
3441 {
3442   ASSERT(cpu != NULL);
3443
3444   if(exception == 0 && cpu->exc_suspended > 0)
3445     {
3446       /* warn not for breakpoints */
3447       if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
3448         sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
3449                        cpu->exc_suspended); 
3450     }
3451   else if(exception != 0 && cpu->exc_suspended > 0)
3452     {
3453       if(exception != cpu->exc_suspended) 
3454         sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
3455                        cpu->exc_suspended, exception); 
3456       
3457       memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers)); 
3458     }
3459   else if(exception != 0 && cpu->exc_suspended == 0)
3460     {
3461       sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception); 
3462     }
3463   cpu->exc_suspended = 0; 
3464 }
3465
3466
3467 /*---------------------------------------------------------------------------*/
3468 /*> EOF interp.c <*/