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