9c53ff9081a6e4b6252767013a3f40aae00895f5
[external/binutils.git] / sim / mips / interp.c
1 /*> interp.c <*/
2 /* Simulator for the MIPS architecture.
3
4    This file is part of the MIPS sim
5
6                 THIS SOFTWARE IS NOT COPYRIGHTED
7
8    Cygnus offers the following for use in the public domain.  Cygnus
9    makes no warranty with regard to the software or it's performance
10    and the user accepts the software "AS IS" with all faults.
11
12    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
16    $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 */
460
461       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
462       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
463       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
464       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x804); /* DRAMC */
465       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
466       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
467       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
468       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
469
470       /* --- simulated devices --- */
471       sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
472       sim_hw_parse (sd, "/tx3904cpu");
473       sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
474       sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
475       sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
476       sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
477       {
478         /* FIXME: poking at dv-sockser internals, use tcp backend if
479          --sockser_addr option was given.*/
480         extern char* sockser_addr;
481         if(sockser_addr == NULL)
482           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
483         else
484           sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
485       }
486       sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
487       sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
488
489       /* -- device connections --- */
490       sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
491       sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
492       sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
493       sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
494       sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
495       sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
496
497       /* add PAL timer & I/O module */
498       if(! strcmp(board, BOARD_JMR3904_PAL))
499         {
500          /* the device */
501          sim_hw_parse (sd, "/pal@0xffff0000");
502          sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
503
504          /* wire up interrupt ports to irc */
505          sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
506          sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
507          sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
508         }
509
510       if(! strcmp(board, BOARD_JMR3904_DEBUG))
511         {
512           /* -- DEBUG: glue interrupt generators --- */
513           sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
514           sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
515           sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
516           sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
517           sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
518           sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
519           sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
520           sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
521           sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
522           sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
523           sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
524           sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
525           sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
526           sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
527           sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
528           sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
529           sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
530           sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
531           sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
532         }
533
534       device_init(sd);
535     }
536 #endif
537
538
539   /* check for/establish the a reference program image */
540   if (sim_analyze_program (sd,
541                            (STATE_PROG_ARGV (sd) != NULL
542                             ? *STATE_PROG_ARGV (sd)
543                             : NULL),
544                            abfd) != SIM_RC_OK)
545     {
546       sim_module_uninstall (sd);
547       return 0;
548     }
549
550   /* Configure/verify the target byte order and other runtime
551      configuration options */
552   if (sim_config (sd) != SIM_RC_OK)
553     {
554       sim_module_uninstall (sd);
555       return 0;
556     }
557
558   if (sim_post_argv_init (sd) != SIM_RC_OK)
559     {
560       /* Uninstall the modules to avoid memory leaks,
561          file descriptor leaks, etc.  */
562       sim_module_uninstall (sd);
563       return 0;
564     }
565
566   /* verify assumptions the simulator made about the host type system.
567      This macro does not return if there is a problem */
568   SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
569   SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
570
571   /* This is NASTY, in that we are assuming the size of specific
572      registers: */
573   {
574     int rn;
575     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
576       {
577         if (rn < 32)
578           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
579         else if ((rn >= FGRIDX) && (rn < (FGRIDX + NR_FGR)))
580           cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
581         else if ((rn >= 33) && (rn <= 37))
582           cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
583         else if ((rn == SRIDX)
584                  || (rn == FCR0IDX)
585                  || (rn == FCR31IDX)
586                  || ((rn >= 72) && (rn <= 89)))
587           cpu->register_widths[rn] = 32;
588         else
589           cpu->register_widths[rn] = 0;
590       }
591
592
593   }
594
595 #if defined(TRACE)
596   if (STATE & simTRACE)
597     open_trace(sd);
598 #endif /* TRACE */
599
600   /*
601   sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", 
602                   idt_monitor_base,
603                   pmon_monitor_base, 
604                   lsipmon_monitor_base);
605   */
606
607   /* Write the monitor trap address handlers into the monitor (eeprom)
608      address space.  This can only be done once the target endianness
609      has been determined. */
610   if (idt_monitor_base != 0)
611     {
612       unsigned loop;
613       unsigned idt_monitor_size = 1 << 11;
614
615       /* the default monitor region */
616       sim_do_commandf (sd, "memory region 0x%x,0x%x",
617                        idt_monitor_base, idt_monitor_size);
618
619       /* Entry into the IDT monitor is via fixed address vectors, and
620          not using machine instructions. To avoid clashing with use of
621          the MIPS TRAP system, we place our own (simulator specific)
622          "undefined" instructions into the relevant vector slots. */
623       for (loop = 0; (loop < idt_monitor_size); loop += 4)
624         {
625           address_word vaddr = (idt_monitor_base + loop);
626           unsigned32 insn = (RSVD_INSTRUCTION |
627                              (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
628                               << RSVD_INSTRUCTION_ARG_SHIFT));
629           H2T (insn);
630           sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
631         }
632     }
633
634   if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
635     {
636     /* The PMON monitor uses the same address space, but rather than
637        branching into it the address of a routine is loaded. We can
638        cheat for the moment, and direct the PMON routine to IDT style
639        instructions within the monitor space. This relies on the IDT
640        monitor not using the locations from 0xBFC00500 onwards as its
641        entry points.*/
642       unsigned loop;
643       for (loop = 0; (loop < 24); loop++)
644         {
645           unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
646           switch (loop)
647             {
648             case 0: /* read */
649               value = 7;
650               break;
651             case 1: /* write */
652               value = 8;
653               break;
654             case 2: /* open */
655               value = 6;
656               break;
657             case 3: /* close */
658               value = 10;
659               break;
660             case 5: /* printf */
661               value = ((0x500 - 16) / 8); /* not an IDT reason code */
662               break;
663             case 8: /* cliexit */
664               value = 17;
665               break;
666             case 11: /* flush_cache */
667               value = 28;
668               break;
669           }
670
671         SIM_ASSERT (idt_monitor_base != 0);
672         value = ((unsigned int) idt_monitor_base + (value * 8));
673         H2T (value);
674
675         if (pmon_monitor_base != 0)
676           {
677             address_word vaddr = (pmon_monitor_base + (loop * 4));
678             sim_write (sd, vaddr, (char *)&value, sizeof (value));
679           }
680
681         if (lsipmon_monitor_base != 0)
682           {
683             address_word vaddr = (lsipmon_monitor_base + (loop * 4));
684             sim_write (sd, vaddr, (char *)&value, sizeof (value));
685           }
686       }
687
688   /* Write an abort sequence into the TRAP (common) exception vector
689      addresses.  This is to catch code executing a TRAP (et.al.)
690      instruction without installing a trap handler. */
691   if ((idt_monitor_base != 0) || 
692       (pmon_monitor_base != 0) || 
693       (lsipmon_monitor_base != 0))
694     {
695       unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
696                              HALT_INSTRUCTION /* BREAK */ };
697       H2T (halt[0]);
698       H2T (halt[1]);
699       sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
700       sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
701       sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
702       /* XXX: Write here unconditionally? */
703       sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
704       sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
705       sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
706     }
707   }
708
709
710
711   return sd;
712 }
713
714 #if defined(TRACE)
715 static void
716 open_trace(sd)
717      SIM_DESC sd;
718 {
719   tracefh = fopen(tracefile,"wb+");
720   if (tracefh == NULL)
721     {
722       sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
723       tracefh = stderr;
724   }
725 }
726 #endif /* TRACE */
727
728 /* Return name of an insn, used by insn profiling.  */
729 static const char *
730 get_insn_name (sim_cpu *cpu, int i)
731 {
732   return itable[i].name;
733 }
734
735 void
736 sim_close (sd, quitting)
737      SIM_DESC sd;
738      int quitting;
739 {
740 #ifdef DEBUG
741   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
742 #endif
743
744
745   /* "quitting" is non-zero if we cannot hang on errors */
746
747   /* shut down modules */
748   sim_module_uninstall (sd);
749
750   /* Ensure that any resources allocated through the callback
751      mechanism are released: */
752   sim_io_shutdown (sd);
753
754 #if defined(TRACE)
755   if (tracefh != NULL && tracefh != stderr)
756    fclose(tracefh);
757   tracefh = NULL;
758 #endif /* TRACE */
759
760   /* FIXME - free SD */
761
762   return;
763 }
764
765
766 int
767 sim_write (sd,addr,buffer,size)
768      SIM_DESC sd;
769      SIM_ADDR addr;
770      unsigned char *buffer;
771      int size;
772 {
773   int index;
774   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
775
776   /* Return the number of bytes written, or zero if error. */
777 #ifdef DEBUG
778   sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
779 #endif
780
781   /* We use raw read and write routines, since we do not want to count
782      the GDB memory accesses in our statistics gathering. */
783
784   for (index = 0; index < size; index++)
785     {
786       address_word vaddr = (address_word)addr + index;
787       address_word paddr;
788       int cca;
789       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
790         break;
791       if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
792         break;
793     }
794
795   return(index);
796 }
797
798 int
799 sim_read (sd,addr,buffer,size)
800      SIM_DESC sd;
801      SIM_ADDR addr;
802      unsigned char *buffer;
803      int size;
804 {
805   int index;
806   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
807
808   /* Return the number of bytes read, or zero if error. */
809 #ifdef DEBUG
810   sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
811 #endif /* DEBUG */
812
813   for (index = 0; (index < size); index++)
814     {
815       address_word vaddr = (address_word)addr + index;
816       address_word paddr;
817       int cca;
818       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
819         break;
820       if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
821         break;
822     }
823
824   return(index);
825 }
826
827 int
828 sim_store_register (sd,rn,memory,length)
829      SIM_DESC sd;
830      int rn;
831      unsigned char *memory;
832      int length;
833 {
834   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
835   /* NOTE: gdb (the client) stores registers in target byte order
836      while the simulator uses host byte order */
837 #ifdef DEBUG
838   sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
839 #endif /* DEBUG */
840
841   /* Unfortunately this suffers from the same problem as the register
842      numbering one. We need to know what the width of each logical
843      register number is for the architecture being simulated. */
844
845   if (cpu->register_widths[rn] == 0)
846     {
847       sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
848       return 0;
849     }
850
851
852
853   if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
854     {
855       cpu->fpr_state[rn - FGRIDX] = fmt_uninterpreted;
856       if (cpu->register_widths[rn] == 32)
857         {
858           if (length == 8)
859             {
860               cpu->fgr[rn - FGRIDX] = 
861                 (unsigned32) T2H_8 (*(unsigned64*)memory);
862               return 8;
863             }
864           else
865             {
866               cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
867               return 4;
868             }
869         }
870       else
871         {
872           cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
873           return 8;
874         }
875     }
876
877   if (cpu->register_widths[rn] == 32)
878     {
879       if (length == 8)
880         {
881           cpu->registers[rn] =
882             (unsigned32) T2H_8 (*(unsigned64*)memory);
883           return 8;
884         }
885       else
886         {
887           cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
888           return 4;
889         }
890     }
891   else
892     {
893       cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
894       return 8;
895     }
896
897   return 0;
898 }
899
900 int
901 sim_fetch_register (sd,rn,memory,length)
902      SIM_DESC sd;
903      int rn;
904      unsigned char *memory;
905      int length;
906 {
907   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
908   /* NOTE: gdb (the client) stores registers in target byte order
909      while the simulator uses host byte order */
910 #ifdef DEBUG
911 #if 0  /* FIXME: doesn't compile */
912   sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
913 #endif
914 #endif /* DEBUG */
915
916   if (cpu->register_widths[rn] == 0)
917     {
918       sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
919       return 0;
920     }
921
922
923
924   /* Any floating point register */
925   if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
926     {
927       if (cpu->register_widths[rn] == 32)
928         {
929           if (length == 8)
930             {
931               *(unsigned64*)memory =
932                 H2T_8 ((unsigned32) (cpu->fgr[rn - FGRIDX]));
933               return 8;
934             }
935           else
936             {
937               *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
938               return 4;
939             }
940         }
941       else
942         {
943           *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
944           return 8;
945         }
946     }
947
948   if (cpu->register_widths[rn] == 32)
949     {
950       if (length == 8)
951         {
952           *(unsigned64*)memory =
953             H2T_8 ((unsigned32) (cpu->registers[rn]));
954           return 8;
955         }
956       else
957         {
958           *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
959           return 4;
960         }
961     }
962   else
963     {
964       *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
965       return 8;
966     }
967
968   return 0;
969 }
970
971
972 SIM_RC
973 sim_create_inferior (sd, abfd, argv,env)
974      SIM_DESC sd;
975      struct _bfd *abfd;
976      char **argv;
977      char **env;
978 {
979
980 #ifdef DEBUG
981 #if 0 /* FIXME: doesn't compile */
982   printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
983          pr_addr(PC));
984 #endif
985 #endif /* DEBUG */
986
987   ColdReset(sd);
988
989   if (abfd != NULL)
990     {
991       /* override PC value set by ColdReset () */
992       int cpu_nr;
993       for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
994         {
995           sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
996           CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
997         }
998     }
999
1000 #if 0 /* def DEBUG */
1001   if (argv || env)
1002     {
1003       /* We should really place the argv slot values into the argument
1004          registers, and onto the stack as required. However, this
1005          assumes that we have a stack defined, which is not
1006          necessarily true at the moment. */
1007       char **cptr;
1008       sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1009       for (cptr = argv; (cptr && *cptr); cptr++)
1010         printf("DBG: arg \"%s\"\n",*cptr);
1011     }
1012 #endif /* DEBUG */
1013
1014   return SIM_RC_OK;
1015 }
1016
1017 void
1018 sim_do_command (sd,cmd)
1019      SIM_DESC sd;
1020      char *cmd;
1021 {
1022   if (sim_args_command (sd, cmd) != SIM_RC_OK)
1023     sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1024                    cmd);
1025 }
1026
1027 /*---------------------------------------------------------------------------*/
1028 /*-- Private simulator support interface ------------------------------------*/
1029 /*---------------------------------------------------------------------------*/
1030
1031 /* Read a null terminated string from memory, return in a buffer */
1032 static char *
1033 fetch_str (SIM_DESC sd,
1034            address_word addr)
1035 {
1036   char *buf;
1037   int nr = 0;
1038   char null;
1039   while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1040     nr++;
1041   buf = NZALLOC (char, nr + 1);
1042   sim_read (sd, addr, buf, nr);
1043   return buf;
1044 }
1045
1046
1047 /* Implements the "sim firmware" command:
1048         sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1049                 NAME can be idt, pmon, or lsipmon.  If omitted, ADDRESS
1050                 defaults to the normal address for that monitor.
1051         sim firmware none --- don't emulate any ROM monitor.  Useful
1052                 if you need a clean address space.  */
1053 static SIM_RC
1054 sim_firmware_command (SIM_DESC sd, char *arg)
1055 {
1056   int address_present = 0;
1057   SIM_ADDR address;
1058
1059   /* Signal occurrence of this option. */
1060   firmware_option_p = 1;
1061
1062   /* Parse out the address, if present.  */
1063   {
1064     char *p = strchr (arg, '@');
1065     if (p)
1066       {
1067         char *q;
1068         address_present = 1;
1069         p ++; /* skip over @ */
1070
1071         address = strtoul (p, &q, 0);
1072         if (*q != '\0') 
1073           {
1074             sim_io_printf (sd, "Invalid address given to the"
1075                            "`sim firmware NAME@ADDRESS' command: %s\n",
1076                            p);
1077             return SIM_RC_FAIL;
1078           }
1079       }
1080     else
1081       address_present = 0;
1082   }
1083
1084   if (! strncmp (arg, "idt", 3))
1085     {
1086       idt_monitor_base = address_present ? address : 0xBFC00000;
1087       pmon_monitor_base = 0;
1088       lsipmon_monitor_base = 0;
1089     }
1090   else if (! strncmp (arg, "pmon", 4))
1091     {
1092       /* pmon uses indirect calls.  Hook into implied idt. */
1093       pmon_monitor_base = address_present ? address : 0xBFC00500;
1094       idt_monitor_base = pmon_monitor_base - 0x500;
1095       lsipmon_monitor_base = 0;
1096     }
1097   else if (! strncmp (arg, "lsipmon", 7))
1098     {
1099       /* lsipmon uses indirect calls.  Hook into implied idt. */
1100       pmon_monitor_base = 0;
1101       lsipmon_monitor_base = address_present ? address : 0xBFC00200;
1102       idt_monitor_base = lsipmon_monitor_base - 0x200;
1103     }
1104   else if (! strncmp (arg, "none", 4))
1105     {
1106       if (address_present)
1107         {
1108           sim_io_printf (sd,
1109                          "The `sim firmware none' command does "
1110                          "not take an `ADDRESS' argument.\n");
1111           return SIM_RC_FAIL;
1112         }
1113       idt_monitor_base = 0;
1114       pmon_monitor_base = 0;
1115       lsipmon_monitor_base = 0;
1116     }
1117   else
1118     {
1119       sim_io_printf (sd, "\
1120 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1121 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1122                      arg);
1123       return SIM_RC_FAIL;
1124     }
1125   
1126   return SIM_RC_OK;
1127 }
1128
1129
1130
1131 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1132 void
1133 sim_monitor (SIM_DESC sd,
1134              sim_cpu *cpu,
1135              address_word cia,
1136              unsigned int reason)
1137 {
1138 #ifdef DEBUG
1139   printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1140 #endif /* DEBUG */
1141
1142   /* The IDT monitor actually allows two instructions per vector
1143      slot. However, the simulator currently causes a trap on each
1144      individual instruction. We cheat, and lose the bottom bit. */
1145   reason >>= 1;
1146
1147   /* The following callback functions are available, however the
1148      monitor we are simulating does not make use of them: get_errno,
1149      isatty, lseek, rename, system, time and unlink */
1150   switch (reason)
1151     {
1152
1153     case 6: /* int open(char *path,int flags) */
1154       {
1155         char *path = fetch_str (sd, A0);
1156         V0 = sim_io_open (sd, path, (int)A1);
1157         zfree (path);
1158         break;
1159       }
1160
1161     case 7: /* int read(int file,char *ptr,int len) */
1162       {
1163         int fd = A0;
1164         int nr = A2;
1165         char *buf = zalloc (nr);
1166         V0 = sim_io_read (sd, fd, buf, nr);
1167         sim_write (sd, A1, buf, nr);
1168         zfree (buf);
1169       }
1170       break;
1171
1172     case 8: /* int write(int file,char *ptr,int len) */
1173       {
1174         int fd = A0;
1175         int nr = A2;
1176         char *buf = zalloc (nr);
1177         sim_read (sd, A1, buf, nr);
1178         V0 = sim_io_write (sd, fd, buf, nr);
1179         zfree (buf);
1180         break;
1181       }
1182
1183     case 10: /* int close(int file) */
1184       {
1185         V0 = sim_io_close (sd, (int)A0);
1186         break;
1187       }
1188
1189     case 2:  /* Densan monitor: char inbyte(int waitflag) */
1190       {
1191         if (A0 == 0)    /* waitflag == NOWAIT */
1192           V0 = (unsigned_word)-1;
1193       }
1194      /* Drop through to case 11 */
1195
1196     case 11: /* char inbyte(void) */
1197       {
1198         char tmp;
1199         /* ensure that all output has gone... */
1200         sim_io_flush_stdout (sd);
1201         if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1202           {
1203             sim_io_error(sd,"Invalid return from character read");
1204             V0 = (unsigned_word)-1;
1205           }
1206         else
1207           V0 = (unsigned_word)tmp;
1208         break;
1209       }
1210
1211     case 3:  /* Densan monitor: void co(char chr) */
1212     case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1213       {
1214         char tmp = (char)(A0 & 0xFF);
1215         sim_io_write_stdout (sd, &tmp, sizeof(char));
1216         break;
1217       }
1218
1219     case 17: /* void _exit() */
1220       {
1221         sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1222         sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1223                          (unsigned int)(A0 & 0xFFFFFFFF));
1224         break;
1225       }
1226
1227     case 28 : /* PMON flush_cache */
1228       break;
1229
1230     case 55: /* void get_mem_info(unsigned int *ptr) */
1231       /* in:  A0 = pointer to three word memory location */
1232       /* out: [A0 + 0] = size */
1233       /*      [A0 + 4] = instruction cache size */
1234       /*      [A0 + 8] = data cache size */
1235       {
1236         unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
1237         unsigned_4 zero = 0;
1238         H2T (value);
1239         sim_write (sd, A0 + 0, (char *)&value, 4);
1240         sim_write (sd, A0 + 4, (char *)&zero, 4);
1241         sim_write (sd, A0 + 8, (char *)&zero, 4);
1242         /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1243         break;
1244       }
1245     
1246     case 158 : /* PMON printf */
1247       /* in:  A0 = pointer to format string */
1248       /*      A1 = optional argument 1 */
1249       /*      A2 = optional argument 2 */
1250       /*      A3 = optional argument 3 */
1251       /* out: void */
1252       /* The following is based on the PMON printf source */
1253       {
1254         address_word s = A0;
1255         char c;
1256         signed_word *ap = &A1; /* 1st argument */
1257         /* This isn't the quickest way, since we call the host print
1258            routine for every character almost. But it does avoid
1259            having to allocate and manage a temporary string buffer. */
1260         /* TODO: Include check that we only use three arguments (A1,
1261            A2 and A3) */
1262         while (sim_read (sd, s++, &c, 1) && c != '\0')
1263           {
1264             if (c == '%')
1265               {
1266                 char tmp[40];
1267                 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1268                 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1269                 while (sim_read (sd, s++, &c, 1) && c != '\0')
1270                   {
1271                     if (strchr ("dobxXulscefg%", c))
1272                       break;
1273                     else if (c == '-')
1274                       fmt = FMT_LJUST;
1275                     else if (c == '0')
1276                       fmt = FMT_RJUST0;
1277                     else if (c == '~')
1278                       fmt = FMT_CENTER;
1279                     else if (c == '*')
1280                       {
1281                         if (haddot)
1282                           trunc = (int)*ap++;
1283                         else
1284                           width = (int)*ap++;
1285                       }
1286                     else if (c >= '1' && c <= '9')
1287                       {
1288                         address_word t = s;
1289                         unsigned int n;
1290                         while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1291                           tmp[s - t] = c;
1292                         tmp[s - t] = '\0';
1293                         n = (unsigned int)strtol(tmp,NULL,10);
1294                         if (haddot)
1295                           trunc = n;
1296                         else
1297                           width = n;
1298                         s--;
1299                       }
1300                     else if (c == '.')
1301                       haddot = 1;
1302                   }
1303                 switch (c)
1304                   {
1305                   case '%':
1306                     sim_io_printf (sd, "%%");
1307                     break;
1308                   case 's':
1309                     if ((int)*ap != 0)
1310                       {
1311                         address_word p = *ap++;
1312                         char ch;
1313                         while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1314                           sim_io_printf(sd, "%c", ch);
1315                       }
1316                     else
1317                       sim_io_printf(sd,"(null)");
1318                     break;
1319                   case 'c':
1320                     sim_io_printf (sd, "%c", (int)*ap++);
1321                     break;
1322                   default:
1323                     if (c == 'l')
1324                       {
1325                         sim_read (sd, s++, &c, 1);
1326                         if (c == 'l')
1327                           {
1328                             longlong = 1;
1329                             sim_read (sd, s++, &c, 1);
1330                           }
1331                       }
1332                     if (strchr ("dobxXu", c))
1333                       {
1334                         word64 lv = (word64) *ap++;
1335                         if (c == 'b')
1336                           sim_io_printf(sd,"<binary not supported>");
1337                         else
1338                           {
1339                             sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
1340                             if (longlong)
1341                               sim_io_printf(sd, tmp, lv);
1342                             else
1343                               sim_io_printf(sd, tmp, (int)lv);
1344                           }
1345                       }
1346                     else if (strchr ("eEfgG", c))
1347                       {
1348                         double dbl = *(double*)(ap++);
1349                         sprintf (tmp, "%%%d.%d%c", width, trunc, c);
1350                         sim_io_printf (sd, tmp, dbl);
1351                         trunc = 0;
1352                       }
1353                   }
1354               }
1355             else
1356               sim_io_printf(sd, "%c", c);
1357           }
1358         break;
1359       }
1360
1361     default:
1362       sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1363                     reason, pr_addr(cia));
1364       break;
1365   }
1366   return;
1367 }
1368
1369 /* Store a word into memory.  */
1370
1371 static void
1372 store_word (SIM_DESC sd,
1373             sim_cpu *cpu,
1374             address_word cia,
1375             uword64 vaddr,
1376             signed_word val)
1377 {
1378   address_word paddr;
1379   int uncached;
1380
1381   if ((vaddr & 3) != 0)
1382     SignalExceptionAddressStore ();
1383   else
1384     {
1385       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1386                               isTARGET, isREAL))
1387         {
1388           const uword64 mask = 7;
1389           uword64 memval;
1390           unsigned int byte;
1391
1392           paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1393           byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1394           memval = ((uword64) val) << (8 * byte);
1395           StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1396                        isREAL);
1397         }
1398     }
1399 }
1400
1401 /* Load a word from memory.  */
1402
1403 static signed_word
1404 load_word (SIM_DESC sd,
1405            sim_cpu *cpu,
1406            address_word cia,
1407            uword64 vaddr)
1408 {
1409   if ((vaddr & 3) != 0)
1410     {
1411       SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1412     }
1413   else
1414     {
1415       address_word paddr;
1416       int uncached;
1417
1418       if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1419                               isTARGET, isREAL))
1420         {
1421           const uword64 mask = 0x7;
1422           const unsigned int reverse = ReverseEndian ? 1 : 0;
1423           const unsigned int bigend = BigEndianCPU ? 1 : 0;
1424           uword64 memval;
1425           unsigned int byte;
1426
1427           paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1428           LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1429                                isDATA, isREAL);
1430           byte = (vaddr & mask) ^ (bigend << 2);
1431           return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
1432         }
1433     }
1434
1435   return 0;
1436 }
1437
1438 /* Simulate the mips16 entry and exit pseudo-instructions.  These
1439    would normally be handled by the reserved instruction exception
1440    code, but for ease of simulation we just handle them directly.  */
1441
1442 static void
1443 mips16_entry (SIM_DESC sd,
1444               sim_cpu *cpu,
1445               address_word cia,
1446               unsigned int insn)
1447 {
1448   int aregs, sregs, rreg;
1449
1450 #ifdef DEBUG
1451   printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1452 #endif /* DEBUG */
1453
1454   aregs = (insn & 0x700) >> 8;
1455   sregs = (insn & 0x0c0) >> 6;
1456   rreg =  (insn & 0x020) >> 5;
1457
1458   /* This should be checked by the caller.  */
1459   if (sregs == 3)
1460     abort ();
1461
1462   if (aregs < 5)
1463     {
1464       int i;
1465       signed_word tsp;
1466
1467       /* This is the entry pseudo-instruction.  */
1468
1469       for (i = 0; i < aregs; i++)
1470         store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1471
1472       tsp = SP;
1473       SP -= 32;
1474
1475       if (rreg)
1476         {
1477           tsp -= 4;
1478           store_word (SD, CPU, cia, (uword64) tsp, RA);
1479         }
1480
1481       for (i = 0; i < sregs; i++)
1482         {
1483           tsp -= 4;
1484           store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1485         }
1486     }
1487   else
1488     {
1489       int i;
1490       signed_word tsp;
1491
1492       /* This is the exit pseudo-instruction.  */
1493
1494       tsp = SP + 32;
1495
1496       if (rreg)
1497         {
1498           tsp -= 4;
1499           RA = load_word (SD, CPU, cia, (uword64) tsp);
1500         }
1501
1502       for (i = 0; i < sregs; i++)
1503         {
1504           tsp -= 4;
1505           GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1506         }
1507
1508       SP += 32;
1509
1510       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1511         {
1512           if (aregs == 5)
1513             {
1514               FGR[0] = WORD64LO (GPR[4]);
1515               FPR_STATE[0] = fmt_uninterpreted;
1516             }
1517           else if (aregs == 6)
1518             {
1519               FGR[0] = WORD64LO (GPR[5]);
1520               FGR[1] = WORD64LO (GPR[4]);
1521               FPR_STATE[0] = fmt_uninterpreted;
1522               FPR_STATE[1] = fmt_uninterpreted;
1523             }
1524         }         
1525
1526       PC = RA;
1527     }
1528   
1529 }
1530
1531 /*-- trace support ----------------------------------------------------------*/
1532
1533 /* The TRACE support is provided (if required) in the memory accessing
1534    routines. Since we are also providing the architecture specific
1535    features, the architecture simulation code can also deal with
1536    notifying the TRACE world of cache flushes, etc. Similarly we do
1537    not need to provide profiling support in the simulator engine,
1538    since we can sample in the instruction fetch control loop. By
1539    defining the TRACE manifest, we add tracing as a run-time
1540    option. */
1541
1542 #if defined(TRACE)
1543 /* Tracing by default produces "din" format (as required by
1544    dineroIII). Each line of such a trace file *MUST* have a din label
1545    and address field. The rest of the line is ignored, so comments can
1546    be included if desired. The first field is the label which must be
1547    one of the following values:
1548
1549         0       read data
1550         1       write data
1551         2       instruction fetch
1552         3       escape record (treated as unknown access type)
1553         4       escape record (causes cache flush)
1554
1555    The address field is a 32bit (lower-case) hexadecimal address
1556    value. The address should *NOT* be preceded by "0x".
1557
1558    The size of the memory transfer is not important when dealing with
1559    cache lines (as long as no more than a cache line can be
1560    transferred in a single operation :-), however more information
1561    could be given following the dineroIII requirement to allow more
1562    complete memory and cache simulators to provide better
1563    results. i.e. the University of Pisa has a cache simulator that can
1564    also take bus size and speed as (variable) inputs to calculate
1565    complete system performance (a much more useful ability when trying
1566    to construct an end product, rather than a processor). They
1567    currently have an ARM version of their tool called ChARM. */
1568
1569
1570 void
1571 dotrace (SIM_DESC sd,
1572          sim_cpu *cpu,
1573          FILE *tracefh,
1574          int type,
1575          SIM_ADDR address,
1576          int width,
1577          char *comment,...)
1578 {
1579   if (STATE & simTRACE) {
1580     va_list ap;
1581     fprintf(tracefh,"%d %s ; width %d ; ", 
1582                 type,
1583                 pr_addr(address),
1584                 width);
1585     va_start(ap,comment);
1586     vfprintf(tracefh,comment,ap);
1587     va_end(ap);
1588     fprintf(tracefh,"\n");
1589   }
1590   /* NOTE: Since the "din" format will only accept 32bit addresses, and
1591      we may be generating 64bit ones, we should put the hi-32bits of the
1592      address into the comment field. */
1593
1594   /* TODO: Provide a buffer for the trace lines. We can then avoid
1595      performing writes until the buffer is filled, or the file is
1596      being closed. */
1597
1598   /* NOTE: We could consider adding a comment field to the "din" file
1599      produced using type 3 markers (unknown access). This would then
1600      allow information about the program that the "din" is for, and
1601      the MIPs world that was being simulated, to be placed into the
1602      trace file. */
1603
1604   return;
1605 }
1606 #endif /* TRACE */
1607
1608 /*---------------------------------------------------------------------------*/
1609 /*-- simulator engine -------------------------------------------------------*/
1610 /*---------------------------------------------------------------------------*/
1611
1612 static void
1613 ColdReset (SIM_DESC sd)
1614 {
1615   int cpu_nr;
1616   for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1617     {
1618       sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1619       /* RESET: Fixed PC address: */
1620       PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1621       /* The reset vector address is in the unmapped, uncached memory space. */
1622       
1623       SR &= ~(status_SR | status_TS | status_RP);
1624       SR |= (status_ERL | status_BEV);
1625       
1626       /* Cheat and allow access to the complete register set immediately */
1627       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1628           && WITH_TARGET_WORD_BITSIZE == 64)
1629         SR |= status_FR; /* 64bit registers */
1630       
1631       /* Ensure that any instructions with pending register updates are
1632          cleared: */
1633       PENDING_INVALIDATE();
1634       
1635       /* Initialise the FPU registers to the unknown state */
1636       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1637         {
1638           int rn;
1639           for (rn = 0; (rn < 32); rn++)
1640             FPR_STATE[rn] = fmt_uninterpreted;
1641         }
1642       
1643     }
1644 }
1645
1646
1647
1648
1649 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1650 /* Signal an exception condition. This will result in an exception
1651    that aborts the instruction. The instruction operation pseudocode
1652    will never see a return from this function call. */
1653
1654 void
1655 signal_exception (SIM_DESC sd,
1656                   sim_cpu *cpu,
1657                   address_word cia,
1658                   int exception,...)
1659 {
1660   /* int vector; */
1661
1662 #ifdef DEBUG
1663   sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1664 #endif /* DEBUG */
1665
1666   /* Ensure that any active atomic read/modify/write operation will fail: */
1667   LLBIT = 0;
1668
1669   /* Save registers before interrupt dispatching */
1670 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1671   SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1672 #endif
1673
1674   switch (exception) {
1675
1676     case DebugBreakPoint :
1677       if (! (Debug & Debug_DM))
1678         {
1679           if (INDELAYSLOT())
1680             {
1681               CANCELDELAYSLOT();
1682               
1683               Debug |= Debug_DBD;  /* signaled from within in delay slot */
1684               DEPC = cia - 4;      /* reference the branch instruction */
1685             }
1686           else
1687             {
1688               Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1689               DEPC = cia;
1690             }
1691         
1692           Debug |= Debug_DM;            /* in debugging mode */
1693           Debug |= Debug_DBp;           /* raising a DBp exception */
1694           PC = 0xBFC00200;
1695           sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1696         }
1697       break;
1698
1699     case ReservedInstruction :
1700      {
1701        va_list ap;
1702        unsigned int instruction;
1703        va_start(ap,exception);
1704        instruction = va_arg(ap,unsigned int);
1705        va_end(ap);
1706        /* Provide simple monitor support using ReservedInstruction
1707           exceptions. The following code simulates the fixed vector
1708           entry points into the IDT monitor by causing a simulator
1709           trap, performing the monitor operation, and returning to
1710           the address held in the $ra register (standard PCS return
1711           address). This means we only need to pre-load the vector
1712           space with suitable instruction values. For systems were
1713           actual trap instructions are used, we would not need to
1714           perform this magic. */
1715        if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1716          {
1717            sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
1718            /* NOTE: This assumes that a branch-and-link style
1719               instruction was used to enter the vector (which is the
1720               case with the current IDT monitor). */
1721            sim_engine_restart (SD, CPU, NULL, RA);
1722          }
1723        /* Look for the mips16 entry and exit instructions, and
1724           simulate a handler for them.  */
1725        else if ((cia & 1) != 0
1726                 && (instruction & 0xf81f) == 0xe809
1727                 && (instruction & 0x0c0) != 0x0c0)
1728          {
1729            mips16_entry (SD, CPU, cia, instruction);
1730            sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1731          }
1732        /* else fall through to normal exception processing */
1733        sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1734      }
1735
1736     default:
1737      /* Store exception code into current exception id variable (used
1738         by exit code): */
1739
1740      /* TODO: If not simulating exceptions then stop the simulator
1741         execution. At the moment we always stop the simulation. */
1742
1743 #ifdef SUBTARGET_R3900
1744       /* update interrupt-related registers */
1745
1746       /* insert exception code in bits 6:2 */
1747       CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1748       /* shift IE/KU history bits left */
1749       SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1750
1751       if (STATE & simDELAYSLOT)
1752         {
1753           STATE &= ~simDELAYSLOT;
1754           CAUSE |= cause_BD;
1755           EPC = (cia - 4); /* reference the branch instruction */
1756         }
1757       else
1758         EPC = cia;
1759
1760      if (SR & status_BEV)
1761        PC = (signed)0xBFC00000 + 0x180;
1762      else
1763        PC = (signed)0x80000000 + 0x080;
1764 #else
1765      /* See figure 5-17 for an outline of the code below */
1766      if (! (SR & status_EXL))
1767        {
1768          CAUSE = (exception << 2);
1769          if (STATE & simDELAYSLOT)
1770            {
1771              STATE &= ~simDELAYSLOT;
1772              CAUSE |= cause_BD;
1773              EPC = (cia - 4); /* reference the branch instruction */
1774            }
1775          else
1776            EPC = cia;
1777          /* FIXME: TLB et.al. */
1778          /* vector = 0x180; */
1779        }
1780      else
1781        {
1782          CAUSE = (exception << 2);
1783          /* vector = 0x180; */
1784        }
1785      SR |= status_EXL;
1786      /* Store exception code into current exception id variable (used
1787         by exit code): */
1788
1789      if (SR & status_BEV)
1790        PC = (signed)0xBFC00200 + 0x180;
1791      else
1792        PC = (signed)0x80000000 + 0x180;
1793 #endif
1794
1795      switch ((CAUSE >> 2) & 0x1F)
1796        {
1797        case Interrupt:
1798          /* Interrupts arrive during event processing, no need to
1799             restart */
1800          return;
1801
1802        case NMIReset:
1803          /* Ditto */
1804 #ifdef SUBTARGET_3900
1805          /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000  */
1806          PC = (signed)0xBFC00000;
1807 #endif SUBTARGET_3900
1808          return;
1809
1810        case TLBModification:
1811        case TLBLoad:
1812        case TLBStore:
1813        case AddressLoad:
1814        case AddressStore:
1815        case InstructionFetch:
1816        case DataReference:
1817          /* The following is so that the simulator will continue from the
1818             exception handler address. */
1819          sim_engine_halt (SD, CPU, NULL, PC,
1820                           sim_stopped, SIM_SIGBUS);
1821
1822        case ReservedInstruction:
1823        case CoProcessorUnusable:
1824          PC = EPC;
1825          sim_engine_halt (SD, CPU, NULL, PC,
1826                           sim_stopped, SIM_SIGILL);
1827
1828        case IntegerOverflow:
1829        case FPE:
1830          sim_engine_halt (SD, CPU, NULL, PC,
1831                           sim_stopped, SIM_SIGFPE);
1832          
1833        case BreakPoint:
1834          sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
1835          break;
1836
1837        case SystemCall:
1838        case Trap:
1839          sim_engine_restart (SD, CPU, NULL, PC);
1840          break;
1841
1842        case Watch:
1843          PC = EPC;
1844          sim_engine_halt (SD, CPU, NULL, PC,
1845                           sim_stopped, SIM_SIGTRAP);
1846
1847        default : /* Unknown internal exception */
1848          PC = EPC;
1849          sim_engine_halt (SD, CPU, NULL, PC,
1850                           sim_stopped, SIM_SIGABRT);
1851
1852        }
1853
1854     case SimulatorFault:
1855      {
1856        va_list ap;
1857        char *msg;
1858        va_start(ap,exception);
1859        msg = va_arg(ap,char *);
1860        va_end(ap);
1861        sim_engine_abort (SD, CPU, NULL_CIA,
1862                          "FATAL: Simulator error \"%s\"\n",msg);
1863      }
1864    }
1865
1866   return;
1867 }
1868
1869
1870
1871 #if defined(WARN_RESULT)
1872 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1873 /* This function indicates that the result of the operation is
1874    undefined. However, this should not affect the instruction
1875    stream. All that is meant to happen is that the destination
1876    register is set to an undefined result. To keep the simulator
1877    simple, we just don't bother updating the destination register, so
1878    the overall result will be undefined. If desired we can stop the
1879    simulator by raising a pseudo-exception. */
1880 #define UndefinedResult() undefined_result (sd,cia)
1881 static void
1882 undefined_result(sd,cia)
1883      SIM_DESC sd;
1884      address_word cia;
1885 {
1886   sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
1887 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1888   state |= simSTOP;
1889 #endif
1890   return;
1891 }
1892 #endif /* WARN_RESULT */
1893
1894 /*-- FPU support routines ---------------------------------------------------*/
1895
1896 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1897    formats conform to ANSI/IEEE Std 754-1985. */
1898 /* SINGLE precision floating:
1899  *    seeeeeeeefffffffffffffffffffffff
1900  *      s =  1bit  = sign
1901  *      e =  8bits = exponent
1902  *      f = 23bits = fraction
1903  */
1904 /* SINGLE precision fixed:
1905  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1906  *      s =  1bit  = sign
1907  *      i = 31bits = integer
1908  */
1909 /* DOUBLE precision floating:
1910  *    seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1911  *      s =  1bit  = sign
1912  *      e = 11bits = exponent
1913  *      f = 52bits = fraction
1914  */
1915 /* DOUBLE precision fixed:
1916  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1917  *      s =  1bit  = sign
1918  *      i = 63bits = integer
1919  */
1920
1921 /* Extract sign-bit: */
1922 #define FP_S_s(v)    (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1923 #define FP_D_s(v)    (((v) & ((uword64)1 << 63)) ? 1 : 0)
1924 /* Extract biased exponent: */
1925 #define FP_S_be(v)   (((v) >> 23) & 0xFF)
1926 #define FP_D_be(v)   (((v) >> 52) & 0x7FF)
1927 /* Extract unbiased Exponent: */
1928 #define FP_S_e(v)    (FP_S_be(v) - 0x7F)
1929 #define FP_D_e(v)    (FP_D_be(v) - 0x3FF)
1930 /* Extract complete fraction field: */
1931 #define FP_S_f(v)    ((v) & ~((unsigned)0x1FF << 23))
1932 #define FP_D_f(v)    ((v) & ~((uword64)0xFFF << 52))
1933 /* Extract numbered fraction bit: */
1934 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1935 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1936
1937 /* Explicit QNaN values used when value required: */
1938 #define FPQNaN_SINGLE   (0x7FBFFFFF)
1939 #define FPQNaN_WORD     (0x7FFFFFFF)
1940 #define FPQNaN_DOUBLE   (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1941 #define FPQNaN_LONG     (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1942
1943 /* Explicit Infinity values used when required: */
1944 #define FPINF_SINGLE    (0x7F800000)
1945 #define FPINF_DOUBLE    (((uword64)0x7FF00000 << 32) | 0x00000000)
1946
1947 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1948 #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>"))))))))
1949
1950 uword64
1951 value_fpr (SIM_DESC sd,
1952            sim_cpu *cpu,
1953            address_word cia,
1954            int fpr,
1955            FP_formats fmt)
1956 {
1957   uword64 value = 0;
1958   int err = 0;
1959
1960   /* Treat unused register values, as fixed-point 64bit values: */
1961   if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
1962 #if 1
1963    /* If request to read data as "uninterpreted", then use the current
1964       encoding: */
1965    fmt = FPR_STATE[fpr];
1966 #else
1967    fmt = fmt_long;
1968 #endif
1969
1970   /* For values not yet accessed, set to the desired format: */
1971   if (FPR_STATE[fpr] == fmt_uninterpreted) {
1972     FPR_STATE[fpr] = fmt;
1973 #ifdef DEBUG
1974     printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
1975 #endif /* DEBUG */
1976   }
1977   if (fmt != FPR_STATE[fpr]) {
1978     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));
1979     FPR_STATE[fpr] = fmt_unknown;
1980   }
1981
1982   if (FPR_STATE[fpr] == fmt_unknown) {
1983    /* Set QNaN value: */
1984    switch (fmt) {
1985     case fmt_single:
1986      value = FPQNaN_SINGLE;
1987      break;
1988
1989     case fmt_double:
1990      value = FPQNaN_DOUBLE;
1991      break;
1992
1993     case fmt_word:
1994      value = FPQNaN_WORD;
1995      break;
1996
1997     case fmt_long:
1998      value = FPQNaN_LONG;
1999      break;
2000
2001     default:
2002      err = -1;
2003      break;
2004    }
2005   } else if (SizeFGR() == 64) {
2006     switch (fmt) {
2007      case fmt_single:
2008      case fmt_word:
2009       value = (FGR[fpr] & 0xFFFFFFFF);
2010       break;
2011
2012      case fmt_uninterpreted:
2013      case fmt_double:
2014      case fmt_long:
2015       value = FGR[fpr];
2016       break;
2017
2018      default :
2019       err = -1;
2020       break;
2021     }
2022   } else {
2023     switch (fmt) {
2024      case fmt_single:
2025      case fmt_word:
2026       value = (FGR[fpr] & 0xFFFFFFFF);
2027       break;
2028
2029      case fmt_uninterpreted:
2030      case fmt_double:
2031      case fmt_long:
2032       if ((fpr & 1) == 0) { /* even registers only */
2033 #ifdef DEBUG
2034         printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n", 
2035                fpr+1, pr_uword64( (uword64) FGR[fpr+1] ),
2036                fpr, pr_uword64( (uword64) FGR[fpr] ));
2037 #endif
2038         value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
2039       } else {
2040         SignalException(ReservedInstruction,0);
2041       }
2042       break;
2043
2044      default :
2045       err = -1;
2046       break;
2047     }
2048   }
2049
2050   if (err)
2051    SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2052
2053 #ifdef DEBUG
2054   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());
2055 #endif /* DEBUG */
2056
2057   return(value);
2058 }
2059
2060 void
2061 store_fpr (SIM_DESC sd,
2062            sim_cpu *cpu,
2063            address_word cia,
2064            int fpr,
2065            FP_formats fmt,
2066            uword64 value)
2067 {
2068   int err = 0;
2069
2070 #ifdef DEBUG
2071   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());
2072 #endif /* DEBUG */
2073
2074   if (SizeFGR() == 64) {
2075     switch (fmt) {
2076       case fmt_uninterpreted_32:
2077         fmt = fmt_uninterpreted;
2078       case fmt_single :
2079       case fmt_word :
2080        FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
2081        FPR_STATE[fpr] = fmt;
2082        break;
2083
2084       case fmt_uninterpreted_64:
2085         fmt = fmt_uninterpreted;
2086       case fmt_uninterpreted:
2087       case fmt_double :
2088       case fmt_long :
2089        FGR[fpr] = value;
2090        FPR_STATE[fpr] = fmt;
2091        break;
2092
2093       default :
2094        FPR_STATE[fpr] = fmt_unknown;
2095        err = -1;
2096        break;
2097     }
2098   } else {
2099     switch (fmt) {
2100       case fmt_uninterpreted_32:
2101         fmt = fmt_uninterpreted;
2102       case fmt_single :
2103       case fmt_word :
2104        FGR[fpr] = (value & 0xFFFFFFFF);
2105        FPR_STATE[fpr] = fmt;
2106        break;
2107
2108       case fmt_uninterpreted_64:
2109         fmt = fmt_uninterpreted;
2110       case fmt_uninterpreted:
2111       case fmt_double :
2112       case fmt_long :
2113         if ((fpr & 1) == 0) { /* even register number only */
2114           FGR[fpr+1] = (value >> 32);
2115           FGR[fpr] = (value & 0xFFFFFFFF);
2116           FPR_STATE[fpr + 1] = fmt;
2117           FPR_STATE[fpr] = fmt;
2118         } else {
2119           FPR_STATE[fpr] = fmt_unknown;
2120           FPR_STATE[fpr + 1] = fmt_unknown;
2121           SignalException(ReservedInstruction,0);
2122         }
2123        break;
2124
2125       default :
2126        FPR_STATE[fpr] = fmt_unknown;
2127        err = -1;
2128        break;
2129     }
2130   }
2131 #if defined(WARN_RESULT)
2132   else
2133     UndefinedResult();
2134 #endif /* WARN_RESULT */
2135
2136   if (err)
2137    SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2138
2139 #ifdef DEBUG
2140   printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_uword64(FGR[fpr]),DOFMT(fmt));
2141 #endif /* DEBUG */
2142
2143   return;
2144 }
2145
2146 int
2147 NaN(op,fmt)
2148      uword64 op;
2149      FP_formats fmt; 
2150 {
2151   int boolean = 0;
2152   switch (fmt) {
2153    case fmt_single:
2154    case fmt_word:
2155     {
2156       sim_fpu wop;
2157       sim_fpu_32to (&wop, op);
2158       boolean = sim_fpu_is_nan (&wop);
2159       break;
2160     }
2161    case fmt_double:
2162    case fmt_long:
2163     {
2164       sim_fpu wop;
2165       sim_fpu_64to (&wop, op);
2166       boolean = sim_fpu_is_nan (&wop);
2167       break;
2168     }
2169    default:
2170     fprintf (stderr, "Bad switch\n");
2171     abort ();
2172   }
2173
2174 #ifdef DEBUG
2175 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2176 #endif /* DEBUG */
2177
2178   return(boolean);
2179 }
2180
2181 int
2182 Infinity(op,fmt)
2183      uword64 op;
2184      FP_formats fmt; 
2185 {
2186   int boolean = 0;
2187
2188 #ifdef DEBUG
2189   printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
2190 #endif /* DEBUG */
2191
2192   switch (fmt) {
2193    case fmt_single:
2194     {
2195       sim_fpu wop;
2196       sim_fpu_32to (&wop, op);
2197       boolean = sim_fpu_is_infinity (&wop);
2198       break;
2199     }
2200    case fmt_double:
2201     {
2202       sim_fpu wop;
2203       sim_fpu_64to (&wop, op);
2204       boolean = sim_fpu_is_infinity (&wop);
2205       break;
2206     }
2207    default:
2208     printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
2209     break;
2210   }
2211
2212 #ifdef DEBUG
2213   printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2214 #endif /* DEBUG */
2215
2216   return(boolean);
2217 }
2218
2219 int
2220 Less(op1,op2,fmt)
2221      uword64 op1;
2222      uword64 op2;
2223      FP_formats fmt; 
2224 {
2225   int boolean = 0;
2226
2227   /* Argument checking already performed by the FPCOMPARE code */
2228
2229 #ifdef DEBUG
2230   printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2231 #endif /* DEBUG */
2232
2233   /* The format type should already have been checked: */
2234   switch (fmt) {
2235    case fmt_single:
2236     {
2237       sim_fpu wop1;
2238       sim_fpu wop2;
2239       sim_fpu_32to (&wop1, op1);
2240       sim_fpu_32to (&wop2, op2);
2241       boolean = sim_fpu_is_lt (&wop1, &wop2);
2242       break;
2243     }
2244    case fmt_double:
2245     {
2246       sim_fpu wop1;
2247       sim_fpu wop2;
2248       sim_fpu_64to (&wop1, op1);
2249       sim_fpu_64to (&wop2, op2);
2250       boolean = sim_fpu_is_lt (&wop1, &wop2);
2251       break;
2252     }
2253    default:
2254     fprintf (stderr, "Bad switch\n");
2255     abort ();
2256   }
2257
2258 #ifdef DEBUG
2259   printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2260 #endif /* DEBUG */
2261
2262   return(boolean);
2263 }
2264
2265 int
2266 Equal(op1,op2,fmt)
2267      uword64 op1;
2268      uword64 op2;
2269      FP_formats fmt; 
2270 {
2271   int boolean = 0;
2272
2273   /* Argument checking already performed by the FPCOMPARE code */
2274
2275 #ifdef DEBUG
2276   printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2277 #endif /* DEBUG */
2278
2279   /* The format type should already have been checked: */
2280   switch (fmt) {
2281    case fmt_single:
2282     {
2283       sim_fpu wop1;
2284       sim_fpu wop2;
2285       sim_fpu_32to (&wop1, op1);
2286       sim_fpu_32to (&wop2, op2);
2287       boolean = sim_fpu_is_eq (&wop1, &wop2);
2288       break;
2289     }
2290    case fmt_double:
2291     {
2292       sim_fpu wop1;
2293       sim_fpu wop2;
2294       sim_fpu_64to (&wop1, op1);
2295       sim_fpu_64to (&wop2, op2);
2296       boolean = sim_fpu_is_eq (&wop1, &wop2);
2297       break;
2298     }
2299    default:
2300     fprintf (stderr, "Bad switch\n");
2301     abort ();
2302   }
2303
2304 #ifdef DEBUG
2305   printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2306 #endif /* DEBUG */
2307
2308   return(boolean);
2309 }
2310
2311 uword64
2312 AbsoluteValue(op,fmt)
2313      uword64 op;
2314      FP_formats fmt; 
2315 {
2316   uword64 result = 0;
2317
2318 #ifdef DEBUG
2319   printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2320 #endif /* DEBUG */
2321
2322   /* The format type should already have been checked: */
2323   switch (fmt) {
2324    case fmt_single:
2325     {
2326       sim_fpu wop;
2327       unsigned32 ans;
2328       sim_fpu_32to (&wop, op);
2329       sim_fpu_abs (&wop, &wop);
2330       sim_fpu_to32 (&ans, &wop);
2331       result = ans;
2332       break;
2333     }
2334    case fmt_double:
2335     {
2336       sim_fpu wop;
2337       unsigned64 ans;
2338       sim_fpu_64to (&wop, op);
2339       sim_fpu_abs (&wop, &wop);
2340       sim_fpu_to64 (&ans, &wop);
2341       result = ans;
2342       break;
2343     }
2344    default:
2345     fprintf (stderr, "Bad switch\n");
2346     abort ();
2347   }
2348
2349   return(result);
2350 }
2351
2352 uword64
2353 Negate(op,fmt)
2354      uword64 op;
2355      FP_formats fmt; 
2356 {
2357   uword64 result = 0;
2358
2359 #ifdef DEBUG
2360   printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2361 #endif /* DEBUG */
2362
2363   /* The format type should already have been checked: */
2364   switch (fmt) {
2365    case fmt_single:
2366     {
2367       sim_fpu wop;
2368       unsigned32 ans;
2369       sim_fpu_32to (&wop, op);
2370       sim_fpu_neg (&wop, &wop);
2371       sim_fpu_to32 (&ans, &wop);
2372       result = ans;
2373       break;
2374     }
2375    case fmt_double:
2376     {
2377       sim_fpu wop;
2378       unsigned64 ans;
2379       sim_fpu_64to (&wop, op);
2380       sim_fpu_neg (&wop, &wop);
2381       sim_fpu_to64 (&ans, &wop);
2382       result = ans;
2383       break;
2384     }
2385    default:
2386     fprintf (stderr, "Bad switch\n");
2387     abort ();
2388   }
2389
2390   return(result);
2391 }
2392
2393 uword64
2394 Add(op1,op2,fmt)
2395      uword64 op1;
2396      uword64 op2;
2397      FP_formats fmt; 
2398 {
2399   uword64 result = 0;
2400
2401 #ifdef DEBUG
2402   printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2403 #endif /* DEBUG */
2404
2405   /* The registers must specify FPRs valid for operands of type
2406      "fmt". If they are not valid, the result is undefined. */
2407
2408   /* The format type should already have been checked: */
2409   switch (fmt) {
2410    case fmt_single:
2411     {
2412       sim_fpu wop1;
2413       sim_fpu wop2;
2414       sim_fpu ans;
2415       unsigned32 res;
2416       sim_fpu_32to (&wop1, op1);
2417       sim_fpu_32to (&wop2, op2);
2418       sim_fpu_add (&ans, &wop1, &wop2);
2419       sim_fpu_to32 (&res, &ans);
2420       result = res;
2421       break;
2422     }
2423    case fmt_double:
2424     {
2425       sim_fpu wop1;
2426       sim_fpu wop2;
2427       sim_fpu ans;
2428       unsigned64 res;
2429       sim_fpu_64to (&wop1, op1);
2430       sim_fpu_64to (&wop2, op2);
2431       sim_fpu_add (&ans, &wop1, &wop2);
2432       sim_fpu_to64 (&res, &ans);
2433       result = res;
2434       break;
2435     }
2436    default:
2437     fprintf (stderr, "Bad switch\n");
2438     abort ();
2439   }
2440
2441 #ifdef DEBUG
2442   printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2443 #endif /* DEBUG */
2444
2445   return(result);
2446 }
2447
2448 uword64
2449 Sub(op1,op2,fmt)
2450      uword64 op1;
2451      uword64 op2;
2452      FP_formats fmt; 
2453 {
2454   uword64 result = 0;
2455
2456 #ifdef DEBUG
2457   printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2458 #endif /* DEBUG */
2459
2460   /* The registers must specify FPRs valid for operands of type
2461      "fmt". If they are not valid, the result is undefined. */
2462
2463   /* The format type should already have been checked: */
2464   switch (fmt) {
2465    case fmt_single:
2466     {
2467       sim_fpu wop1;
2468       sim_fpu wop2;
2469       sim_fpu ans;
2470       unsigned32 res;
2471       sim_fpu_32to (&wop1, op1);
2472       sim_fpu_32to (&wop2, op2);
2473       sim_fpu_sub (&ans, &wop1, &wop2);
2474       sim_fpu_to32 (&res, &ans);
2475       result = res;
2476     }
2477     break;
2478    case fmt_double:
2479     {
2480       sim_fpu wop1;
2481       sim_fpu wop2;
2482       sim_fpu ans;
2483       unsigned64 res;
2484       sim_fpu_64to (&wop1, op1);
2485       sim_fpu_64to (&wop2, op2);
2486       sim_fpu_sub (&ans, &wop1, &wop2);
2487       sim_fpu_to64 (&res, &ans);
2488       result = res;
2489     }
2490     break;
2491    default:
2492     fprintf (stderr, "Bad switch\n");
2493     abort ();
2494   }
2495
2496 #ifdef DEBUG
2497   printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2498 #endif /* DEBUG */
2499
2500   return(result);
2501 }
2502
2503 uword64
2504 Multiply(op1,op2,fmt)
2505      uword64 op1;
2506      uword64 op2;
2507      FP_formats fmt; 
2508 {
2509   uword64 result = 0;
2510
2511 #ifdef DEBUG
2512   printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2513 #endif /* DEBUG */
2514
2515   /* The registers must specify FPRs valid for operands of type
2516      "fmt". If they are not valid, the result is undefined. */
2517
2518   /* The format type should already have been checked: */
2519   switch (fmt) {
2520    case fmt_single:
2521     {
2522       sim_fpu wop1;
2523       sim_fpu wop2;
2524       sim_fpu ans;
2525       unsigned32 res;
2526       sim_fpu_32to (&wop1, op1);
2527       sim_fpu_32to (&wop2, op2);
2528       sim_fpu_mul (&ans, &wop1, &wop2);
2529       sim_fpu_to32 (&res, &ans);
2530       result = res;
2531       break;
2532     }
2533    case fmt_double:
2534     {
2535       sim_fpu wop1;
2536       sim_fpu wop2;
2537       sim_fpu ans;
2538       unsigned64 res;
2539       sim_fpu_64to (&wop1, op1);
2540       sim_fpu_64to (&wop2, op2);
2541       sim_fpu_mul (&ans, &wop1, &wop2);
2542       sim_fpu_to64 (&res, &ans);
2543       result = res;
2544       break;
2545     }
2546    default:
2547     fprintf (stderr, "Bad switch\n");
2548     abort ();
2549   }
2550
2551 #ifdef DEBUG
2552   printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2553 #endif /* DEBUG */
2554
2555   return(result);
2556 }
2557
2558 uword64
2559 Divide(op1,op2,fmt)
2560      uword64 op1;
2561      uword64 op2;
2562      FP_formats fmt; 
2563 {
2564   uword64 result = 0;
2565
2566 #ifdef DEBUG
2567   printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2568 #endif /* DEBUG */
2569
2570   /* The registers must specify FPRs valid for operands of type
2571      "fmt". If they are not valid, the result is undefined. */
2572
2573   /* The format type should already have been checked: */
2574   switch (fmt) {
2575    case fmt_single:
2576     {
2577       sim_fpu wop1;
2578       sim_fpu wop2;
2579       sim_fpu ans;
2580       unsigned32 res;
2581       sim_fpu_32to (&wop1, op1);
2582       sim_fpu_32to (&wop2, op2);
2583       sim_fpu_div (&ans, &wop1, &wop2);
2584       sim_fpu_to32 (&res, &ans);
2585       result = res;
2586       break;
2587     }
2588    case fmt_double:
2589     {
2590       sim_fpu wop1;
2591       sim_fpu wop2;
2592       sim_fpu ans;
2593       unsigned64 res;
2594       sim_fpu_64to (&wop1, op1);
2595       sim_fpu_64to (&wop2, op2);
2596       sim_fpu_div (&ans, &wop1, &wop2);
2597       sim_fpu_to64 (&res, &ans);
2598       result = res;
2599       break;
2600     }
2601    default:
2602     fprintf (stderr, "Bad switch\n");
2603     abort ();
2604   }
2605
2606 #ifdef DEBUG
2607   printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2608 #endif /* DEBUG */
2609
2610   return(result);
2611 }
2612
2613 uword64 UNUSED
2614 Recip(op,fmt)
2615      uword64 op;
2616      FP_formats fmt; 
2617 {
2618   uword64 result = 0;
2619
2620 #ifdef DEBUG
2621   printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2622 #endif /* DEBUG */
2623
2624   /* The registers must specify FPRs valid for operands of type
2625      "fmt". If they are not valid, the result is undefined. */
2626
2627   /* The format type should already have been checked: */
2628   switch (fmt) {
2629    case fmt_single:
2630     {
2631       sim_fpu wop;
2632       sim_fpu ans;
2633       unsigned32 res;
2634       sim_fpu_32to (&wop, op);
2635       sim_fpu_inv (&ans, &wop);
2636       sim_fpu_to32 (&res, &ans);
2637       result = res;
2638       break;
2639     }
2640    case fmt_double:
2641     {
2642       sim_fpu wop;
2643       sim_fpu ans;
2644       unsigned64 res;
2645       sim_fpu_64to (&wop, op);
2646       sim_fpu_inv (&ans, &wop);
2647       sim_fpu_to64 (&res, &ans);
2648       result = res;
2649       break;
2650     }
2651    default:
2652     fprintf (stderr, "Bad switch\n");
2653     abort ();
2654   }
2655
2656 #ifdef DEBUG
2657   printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2658 #endif /* DEBUG */
2659
2660   return(result);
2661 }
2662
2663 uword64
2664 SquareRoot(op,fmt)
2665      uword64 op;
2666      FP_formats fmt; 
2667 {
2668   uword64 result = 0;
2669
2670 #ifdef DEBUG
2671   printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2672 #endif /* DEBUG */
2673
2674   /* The registers must specify FPRs valid for operands of type
2675      "fmt". If they are not valid, the result is undefined. */
2676
2677   /* The format type should already have been checked: */
2678   switch (fmt) {
2679    case fmt_single:
2680     {
2681       sim_fpu wop;
2682       sim_fpu ans;
2683       unsigned32 res;
2684       sim_fpu_32to (&wop, op);
2685       sim_fpu_sqrt (&ans, &wop);
2686       sim_fpu_to32 (&res, &ans);
2687       result = res;
2688       break;
2689     }
2690    case fmt_double:
2691     {
2692       sim_fpu wop;
2693       sim_fpu ans;
2694       unsigned64 res;
2695       sim_fpu_64to (&wop, op);
2696       sim_fpu_sqrt (&ans, &wop);
2697       sim_fpu_to64 (&res, &ans);
2698       result = res;
2699       break;
2700     }
2701    default:
2702     fprintf (stderr, "Bad switch\n");
2703     abort ();
2704   }
2705
2706 #ifdef DEBUG
2707   printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2708 #endif /* DEBUG */
2709
2710   return(result);
2711 }
2712
2713 #if 0
2714 uword64
2715 Max (uword64 op1,
2716      uword64 op2,
2717      FP_formats fmt)
2718 {
2719   int cmp;
2720   unsigned64 result;
2721
2722 #ifdef DEBUG
2723   printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2724 #endif /* DEBUG */
2725
2726   /* The registers must specify FPRs valid for operands of type
2727      "fmt". If they are not valid, the result is undefined. */
2728
2729   /* The format type should already have been checked: */
2730   switch (fmt)
2731     {
2732     case fmt_single:
2733       {
2734         sim_fpu wop1;
2735         sim_fpu wop2;
2736         sim_fpu_32to (&wop1, op1);
2737         sim_fpu_32to (&wop2, op2);
2738         cmp = sim_fpu_cmp (&wop1, &wop2);
2739         break;
2740       }
2741     case fmt_double:
2742       {
2743         sim_fpu wop1;
2744         sim_fpu wop2;
2745         sim_fpu_64to (&wop1, op1);
2746         sim_fpu_64to (&wop2, op2);
2747         cmp = sim_fpu_cmp (&wop1, &wop2);
2748         break;
2749       }
2750     default:
2751       fprintf (stderr, "Bad switch\n");
2752       abort ();
2753     }
2754   
2755   switch (cmp)
2756     {
2757     case SIM_FPU_IS_SNAN:
2758     case SIM_FPU_IS_QNAN:
2759       result = op1;
2760     case SIM_FPU_IS_NINF:
2761     case SIM_FPU_IS_NNUMBER:
2762     case SIM_FPU_IS_NDENORM:
2763     case SIM_FPU_IS_NZERO:
2764       result = op2; /* op1 - op2 < 0 */
2765     case SIM_FPU_IS_PINF:
2766     case SIM_FPU_IS_PNUMBER:
2767     case SIM_FPU_IS_PDENORM:
2768     case SIM_FPU_IS_PZERO:
2769       result = op1; /* op1 - op2 > 0 */
2770     default:
2771       fprintf (stderr, "Bad switch\n");
2772       abort ();
2773     }
2774
2775 #ifdef DEBUG
2776   printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2777 #endif /* DEBUG */
2778
2779   return(result);
2780 }
2781 #endif 
2782
2783 #if 0
2784 uword64
2785 Min (uword64 op1,
2786      uword64 op2,
2787      FP_formats fmt)
2788 {
2789   int cmp;
2790   unsigned64 result;
2791
2792 #ifdef DEBUG
2793   printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2794 #endif /* DEBUG */
2795
2796   /* The registers must specify FPRs valid for operands of type
2797      "fmt". If they are not valid, the result is undefined. */
2798
2799   /* The format type should already have been checked: */
2800   switch (fmt)
2801     {
2802     case fmt_single:
2803       {
2804         sim_fpu wop1;
2805         sim_fpu wop2;
2806         sim_fpu_32to (&wop1, op1);
2807         sim_fpu_32to (&wop2, op2);
2808         cmp = sim_fpu_cmp (&wop1, &wop2);
2809         break;
2810       }
2811     case fmt_double:
2812       {
2813         sim_fpu wop1;
2814         sim_fpu wop2;
2815         sim_fpu_64to (&wop1, op1);
2816         sim_fpu_64to (&wop2, op2);
2817         cmp = sim_fpu_cmp (&wop1, &wop2);
2818         break;
2819       }
2820     default:
2821       fprintf (stderr, "Bad switch\n");
2822       abort ();
2823     }
2824   
2825   switch (cmp)
2826     {
2827     case SIM_FPU_IS_SNAN:
2828     case SIM_FPU_IS_QNAN:
2829       result = op1;
2830     case SIM_FPU_IS_NINF:
2831     case SIM_FPU_IS_NNUMBER:
2832     case SIM_FPU_IS_NDENORM:
2833     case SIM_FPU_IS_NZERO:
2834       result = op1; /* op1 - op2 < 0 */
2835     case SIM_FPU_IS_PINF:
2836     case SIM_FPU_IS_PNUMBER:
2837     case SIM_FPU_IS_PDENORM:
2838     case SIM_FPU_IS_PZERO:
2839       result = op2; /* op1 - op2 > 0 */
2840     default:
2841       fprintf (stderr, "Bad switch\n");
2842       abort ();
2843     }
2844
2845 #ifdef DEBUG
2846   printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2847 #endif /* DEBUG */
2848
2849   return(result);
2850 }
2851 #endif
2852
2853 uword64
2854 convert (SIM_DESC sd,
2855          sim_cpu *cpu,
2856          address_word cia,
2857          int rm,
2858          uword64 op,
2859          FP_formats from,
2860          FP_formats to)
2861 {
2862   sim_fpu wop;
2863   sim_fpu_round round;
2864   unsigned32 result32;
2865   unsigned64 result64;
2866
2867 #ifdef DEBUG
2868 #if 0 /* FIXME: doesn't compile */
2869   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));
2870 #endif
2871 #endif /* DEBUG */
2872
2873   switch (rm)
2874     {
2875     case FP_RM_NEAREST:
2876       /* Round result to nearest representable value. When two
2877          representable values are equally near, round to the value
2878          that has a least significant bit of zero (i.e. is even). */
2879       round = sim_fpu_round_near;
2880       break;
2881     case FP_RM_TOZERO:
2882       /* Round result to the value closest to, and not greater in
2883          magnitude than, the result. */
2884       round = sim_fpu_round_zero;
2885       break;
2886     case FP_RM_TOPINF:
2887       /* Round result to the value closest to, and not less than,
2888          the result. */
2889       round = sim_fpu_round_up;
2890       break;
2891       
2892     case FP_RM_TOMINF:
2893       /* Round result to the value closest to, and not greater than,
2894          the result. */
2895       round = sim_fpu_round_down;
2896       break;
2897     default:
2898       round = 0;
2899       fprintf (stderr, "Bad switch\n");
2900       abort ();
2901     }
2902   
2903   /* Convert the input to sim_fpu internal format */
2904   switch (from)
2905     {
2906     case fmt_double:
2907       sim_fpu_64to (&wop, op);
2908       break;
2909     case fmt_single:
2910       sim_fpu_32to (&wop, op);
2911       break;
2912     case fmt_word:
2913       sim_fpu_i32to (&wop, op, round);
2914       break;
2915     case fmt_long:
2916       sim_fpu_i64to (&wop, op, round);
2917       break;
2918     default:
2919       fprintf (stderr, "Bad switch\n");
2920       abort ();
2921     }
2922
2923   /* Convert sim_fpu format into the output */
2924   /* The value WOP is converted to the destination format, rounding
2925      using mode RM. When the destination is a fixed-point format, then
2926      a source value of Infinity, NaN or one which would round to an
2927      integer outside the fixed point range then an IEEE Invalid
2928      Operation condition is raised. */
2929   switch (to)
2930     {
2931     case fmt_single:
2932       sim_fpu_round_32 (&wop, round, 0);
2933       sim_fpu_to32 (&result32, &wop);
2934       result64 = result32;
2935       break;
2936     case fmt_double:
2937       sim_fpu_round_64 (&wop, round, 0);
2938       sim_fpu_to64 (&result64, &wop);
2939       break;
2940     case fmt_word:
2941       sim_fpu_to32i (&result32, &wop, round);
2942       result64 = result32;
2943       break;
2944     case fmt_long:
2945       sim_fpu_to64i (&result64, &wop, round);
2946       break;
2947     default:
2948       result64 = 0;
2949       fprintf (stderr, "Bad switch\n");
2950       abort ();
2951     }
2952  
2953 #ifdef DEBUG
2954   printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
2955 #endif /* DEBUG */
2956
2957   return(result64);
2958 }
2959
2960
2961 /*-- co-processor support routines ------------------------------------------*/
2962
2963 static int UNUSED
2964 CoProcPresent(unsigned int coproc_number)
2965 {
2966   /* Return TRUE if simulator provides a model for the given co-processor number */
2967   return(0);
2968 }
2969
2970 void
2971 cop_lw (SIM_DESC sd,
2972         sim_cpu *cpu,
2973         address_word cia,
2974         int coproc_num,
2975         int coproc_reg,
2976         unsigned int memword)
2977 {
2978   switch (coproc_num)
2979     {
2980     case 1:
2981       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2982         {
2983 #ifdef DEBUG
2984           printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2985 #endif
2986           StoreFPR(coproc_reg,fmt_word,(uword64)memword);
2987           FPR_STATE[coproc_reg] = fmt_uninterpreted;
2988           break;
2989         }
2990
2991     default:
2992 #if 0 /* this should be controlled by a configuration option */
2993       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));
2994 #endif
2995       break;
2996     }
2997
2998   return;
2999 }
3000
3001 void
3002 cop_ld (SIM_DESC sd,
3003         sim_cpu *cpu,
3004         address_word cia,
3005         int coproc_num,
3006         int coproc_reg,
3007         uword64 memword)
3008 {
3009
3010 #ifdef DEBUG
3011   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) );
3012 #endif
3013
3014   switch (coproc_num) {
3015     case 1:
3016       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3017         {
3018           StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3019           break;
3020         }
3021
3022     default:
3023 #if 0 /* this message should be controlled by a configuration option */
3024      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));
3025 #endif
3026      break;
3027   }
3028
3029   return;
3030 }
3031
3032
3033
3034
3035 unsigned int
3036 cop_sw (SIM_DESC sd,
3037         sim_cpu *cpu,
3038         address_word cia,
3039         int coproc_num,
3040         int coproc_reg)
3041 {
3042   unsigned int value = 0;
3043
3044   switch (coproc_num)
3045     {
3046     case 1:
3047       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3048         {
3049           FP_formats hold;
3050           hold = FPR_STATE[coproc_reg];
3051           FPR_STATE[coproc_reg] = fmt_word;
3052           value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
3053           FPR_STATE[coproc_reg] = hold;
3054           break;
3055         }
3056
3057     default:
3058 #if 0 /* should be controlled by configuration option */
3059       sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3060 #endif
3061       break;
3062     }
3063
3064   return(value);
3065 }
3066
3067 uword64
3068 cop_sd (SIM_DESC sd,
3069         sim_cpu *cpu,
3070         address_word cia,
3071         int coproc_num,
3072         int coproc_reg)
3073 {
3074   uword64 value = 0;
3075   switch (coproc_num)
3076     {
3077     case 1:
3078       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3079         {
3080           value = ValueFPR(coproc_reg,fmt_uninterpreted);
3081           break;
3082         }
3083
3084     default:
3085 #if 0 /* should be controlled by configuration option */
3086       sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3087 #endif
3088       break;
3089     }
3090
3091   return(value);
3092 }
3093
3094
3095
3096
3097 void
3098 decode_coproc (SIM_DESC sd,
3099                sim_cpu *cpu,
3100                address_word cia,
3101                unsigned int instruction)
3102 {
3103   int coprocnum = ((instruction >> 26) & 3);
3104
3105   switch (coprocnum)
3106     {
3107     case 0: /* standard CPU control and cache registers */
3108       {
3109         int code = ((instruction >> 21) & 0x1F);
3110         int rt = ((instruction >> 16) & 0x1F);
3111         int rd = ((instruction >> 11) & 0x1F);
3112         int tail = instruction & 0x3ff;
3113         /* R4000 Users Manual (second edition) lists the following CP0
3114            instructions:
3115                                                                    CODE><-RT><RD-><--TAIL--->
3116            DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
3117            DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
3118            MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
3119            MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
3120            TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
3121            TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
3122            TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
3123            TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
3124            CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3125            ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
3126            */
3127         if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */        
3128              || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */        
3129             && tail == 0)
3130           {
3131             /* Clear double/single coprocessor move bit. */
3132             code &= ~1;
3133
3134             /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
3135             
3136             switch (rd)  /* NOTEs: Standard CP0 registers */
3137               {
3138                 /* 0 = Index               R4000   VR4100  VR4300 */
3139                 /* 1 = Random              R4000   VR4100  VR4300 */
3140                 /* 2 = EntryLo0            R4000   VR4100  VR4300 */
3141                 /* 3 = EntryLo1            R4000   VR4100  VR4300 */
3142                 /* 4 = Context             R4000   VR4100  VR4300 */
3143                 /* 5 = PageMask            R4000   VR4100  VR4300 */
3144                 /* 6 = Wired               R4000   VR4100  VR4300 */
3145                 /* 8 = BadVAddr            R4000   VR4100  VR4300 */
3146                 /* 9 = Count               R4000   VR4100  VR4300 */
3147                 /* 10 = EntryHi            R4000   VR4100  VR4300 */
3148                 /* 11 = Compare            R4000   VR4100  VR4300 */
3149                 /* 12 = SR                 R4000   VR4100  VR4300 */
3150 #ifdef SUBTARGET_R3900
3151               case 3:
3152                 /* 3 = Config              R3900                  */
3153               case 7:
3154                 /* 7 = Cache               R3900                  */
3155               case 15:
3156                 /* 15 = PRID               R3900                  */
3157
3158                 /* ignore */
3159                 break;
3160
3161               case 8:
3162                 /* 8 = BadVAddr            R4000   VR4100  VR4300 */
3163                 if (code == 0x00)
3164                   GPR[rt] = COP0_BADVADDR;
3165                 else
3166                   COP0_BADVADDR = GPR[rt];
3167                 break;
3168
3169 #endif /* SUBTARGET_R3900 */
3170               case 12:
3171                 if (code == 0x00)
3172                   GPR[rt] = SR;
3173                 else
3174                   SR = GPR[rt];
3175                 break;
3176                 /* 13 = Cause              R4000   VR4100  VR4300 */
3177               case 13:
3178                 if (code == 0x00)
3179                   GPR[rt] = CAUSE;
3180                 else
3181                   CAUSE = GPR[rt];
3182                 break;
3183                 /* 14 = EPC                R4000   VR4100  VR4300 */
3184               case 14:
3185                 if (code == 0x00)
3186                   GPR[rt] = (signed_word) (signed_address) EPC;
3187                 else
3188                   EPC = GPR[rt];
3189                 break;
3190                 /* 15 = PRId               R4000   VR4100  VR4300 */
3191 #ifdef SUBTARGET_R3900
3192                 /* 16 = Debug */
3193               case 16:
3194                 if (code == 0x00)
3195                   GPR[rt] = Debug;
3196                 else
3197                   Debug = GPR[rt];
3198                 break;
3199 #else
3200                 /* 16 = Config             R4000   VR4100  VR4300 */
3201               case 16:
3202                 if (code == 0x00)
3203                   GPR[rt] = C0_CONFIG;
3204                 else
3205                   C0_CONFIG = GPR[rt];
3206                 break;
3207 #endif
3208 #ifdef SUBTARGET_R3900
3209                 /* 17 = Debug */
3210               case 17:
3211                 if (code == 0x00)
3212                   GPR[rt] = DEPC;
3213                 else
3214                   DEPC = GPR[rt];
3215                 break;
3216 #else
3217                 /* 17 = LLAddr             R4000   VR4100  VR4300 */
3218 #endif
3219                 /* 18 = WatchLo            R4000   VR4100  VR4300 */
3220                 /* 19 = WatchHi            R4000   VR4100  VR4300 */
3221                 /* 20 = XContext           R4000   VR4100  VR4300 */
3222                 /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
3223                 /* 27 = CacheErr           R4000   VR4100 */
3224                 /* 28 = TagLo              R4000   VR4100  VR4300 */
3225                 /* 29 = TagHi              R4000   VR4100  VR4300 */
3226                 /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
3227                 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
3228                 /* CPR[0,rd] = GPR[rt]; */
3229               default:
3230                 if (code == 0x00)
3231                   GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
3232                 else
3233                   COP0_GPR[rd] = GPR[rt];
3234 #if 0
3235                 if (code == 0x00)
3236                   sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
3237                 else
3238                   sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
3239 #endif
3240               }
3241           }
3242         else if (code == 0x10 && (tail & 0x3f) == 0x18)
3243           {
3244             /* ERET */
3245             if (SR & status_ERL)
3246               {
3247                 /* Oops, not yet available */
3248                 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
3249                 PC = EPC;
3250                 SR &= ~status_ERL;
3251               }
3252             else
3253               {
3254                 PC = EPC;
3255                 SR &= ~status_EXL;
3256               }
3257           }
3258         else if (code == 0x10 && (tail & 0x3f) == 0x10)
3259           {
3260             /* RFE */
3261 #ifdef SUBTARGET_R3900
3262             /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3263
3264             /* shift IE/KU history bits right */
3265             SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
3266
3267             /* TODO: CACHE register */
3268 #endif /* SUBTARGET_R3900 */
3269           }
3270         else if (code == 0x10 && (tail & 0x3f) == 0x1F)
3271           {
3272             /* DERET */
3273             Debug &= ~Debug_DM;
3274             DELAYSLOT();
3275             DSPC = DEPC;
3276           }
3277         else
3278           sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
3279         /* TODO: When executing an ERET or RFE instruction we should
3280            clear LLBIT, to ensure that any out-standing atomic
3281            read/modify/write sequence fails. */
3282       }
3283     break;
3284     
3285     case 2: /* co-processor 2 */
3286       {
3287         int handle = 0;
3288
3289
3290         if(! handle)
3291           {
3292             sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3293                            instruction,pr_addr(cia));
3294           }
3295       }
3296     break;
3297     
3298     case 1: /* should not occur (FPU co-processor) */
3299     case 3: /* should not occur (FPU co-processor) */
3300       SignalException(ReservedInstruction,instruction);
3301       break;
3302     }
3303   
3304   return;
3305 }
3306
3307
3308 /* This code copied from gdb's utils.c.  Would like to share this code,
3309    but don't know of a common place where both could get to it. */
3310
3311 /* Temporary storage using circular buffer */
3312 #define NUMCELLS 16
3313 #define CELLSIZE 32
3314 static char*
3315 get_cell (void)
3316 {
3317   static char buf[NUMCELLS][CELLSIZE];
3318   static int cell=0;
3319   if (++cell>=NUMCELLS) cell=0;
3320   return buf[cell];
3321 }     
3322
3323 /* Print routines to handle variable size regs, etc */
3324
3325 /* Eliminate warning from compiler on 32-bit systems */
3326 static int thirty_two = 32;     
3327
3328 char* 
3329 pr_addr(addr)
3330   SIM_ADDR addr;
3331 {
3332   char *paddr_str=get_cell();
3333   switch (sizeof(addr))
3334     {
3335       case 8:
3336         sprintf(paddr_str,"%08lx%08lx",
3337                 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3338         break;
3339       case 4:
3340         sprintf(paddr_str,"%08lx",(unsigned long)addr);
3341         break;
3342       case 2:
3343         sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
3344         break;
3345       default:
3346         sprintf(paddr_str,"%x",addr);
3347     }
3348   return paddr_str;
3349 }
3350
3351 char* 
3352 pr_uword64(addr)
3353   uword64 addr;
3354 {
3355   char *paddr_str=get_cell();
3356   sprintf(paddr_str,"%08lx%08lx",
3357           (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3358   return paddr_str;
3359 }
3360
3361
3362 void
3363 mips_core_signal (SIM_DESC sd,
3364                  sim_cpu *cpu,
3365                  sim_cia cia,
3366                  unsigned map,
3367                  int nr_bytes,
3368                  address_word addr,
3369                  transfer_type transfer,
3370                  sim_core_signals sig)
3371 {
3372   const char *copy = (transfer == read_transfer ? "read" : "write");
3373   address_word ip = CIA_ADDR (cia);
3374
3375   switch (sig)
3376     {
3377     case sim_core_unmapped_signal:
3378       sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
3379                       nr_bytes, copy, 
3380                       (unsigned long) addr, (unsigned long) ip);
3381       COP0_BADVADDR = addr;
3382       SignalExceptionDataReference();
3383       break;
3384
3385     case sim_core_unaligned_signal:
3386       sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
3387                       nr_bytes, copy, 
3388                       (unsigned long) addr, (unsigned long) ip);
3389       COP0_BADVADDR = addr;
3390       if(transfer == read_transfer) 
3391         SignalExceptionAddressLoad();
3392       else
3393         SignalExceptionAddressStore();
3394       break;
3395
3396     default:
3397       sim_engine_abort (sd, cpu, cia,
3398                         "mips_core_signal - internal error - bad switch");
3399     }
3400 }
3401
3402
3403 void
3404 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
3405 {
3406   ASSERT(cpu != NULL);
3407
3408   if(cpu->exc_suspended > 0)
3409     sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended); 
3410
3411   PC = cia;
3412   memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
3413   cpu->exc_suspended = 0;
3414 }
3415
3416 void
3417 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
3418 {
3419   ASSERT(cpu != NULL);
3420
3421   if(cpu->exc_suspended > 0)
3422     sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n", 
3423                    cpu->exc_suspended, exception); 
3424
3425   memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
3426   memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
3427   cpu->exc_suspended = exception;
3428 }
3429
3430 void
3431 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
3432 {
3433   ASSERT(cpu != NULL);
3434
3435   if(exception == 0 && cpu->exc_suspended > 0)
3436     {
3437       /* warn not for breakpoints */
3438       if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
3439         sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
3440                        cpu->exc_suspended); 
3441     }
3442   else if(exception != 0 && cpu->exc_suspended > 0)
3443     {
3444       if(exception != cpu->exc_suspended) 
3445         sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
3446                        cpu->exc_suspended, exception); 
3447       
3448       memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers)); 
3449     }
3450   else if(exception != 0 && cpu->exc_suspended == 0)
3451     {
3452       sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception); 
3453     }
3454   cpu->exc_suspended = 0; 
3455 }
3456
3457
3458 /*---------------------------------------------------------------------------*/
3459 /*> EOF interp.c <*/