OSDN Git Service

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