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