]> Git Repo - binutils.git/blob - sim/mips/interp.c
o Fixes to repeated watchpoints
[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      $Author$
18        $Date$             
19
20 NOTEs:
21
22 We only need to take account of the target endianness when moving data
23 between the simulator and the host. We do not need to worry about the
24 endianness of the host, since this sim code and GDB are executing in
25 the same process.
26
27 The IDT monitor (found on the VR4300 board), seems to lie about
28 register contents. It seems to treat the registers as sign-extended
29 32-bit values. This cause *REAL* problems when single-stepping 64-bit
30 code on the hardware.
31
32 */
33
34 /* The TRACE and PROFILE manifests enable the provision of extra
35    features. If they are not defined then a simpler (quicker)
36    simulator is constructed without the required run-time checks,
37    etc. */
38 #if 1 /* 0 to allow user build selection, 1 to force inclusion */
39 #define TRACE (1)
40 #define PROFILE (1)
41 #endif
42
43 #include "bfd.h"
44 #include "sim-main.h"
45 #include "sim-utils.h"
46 #include "sim-options.h"
47 #include "sim-assert.h"
48
49 #include "config.h"
50
51 #include <stdio.h>
52 #include <stdarg.h>
53 #include <ansidecl.h>
54 #include <signal.h>
55 #include <ctype.h>
56 #include <limits.h>
57 #include <math.h>
58 #ifdef HAVE_STDLIB_H
59 #include <stdlib.h>
60 #endif
61 #ifdef HAVE_STRING_H
62 #include <string.h>
63 #else
64 #ifdef HAVE_STRINGS_H
65 #include <strings.h>
66 #endif
67 #endif
68
69 #include "getopt.h"
70 #include "libiberty.h"
71 #include "bfd.h"
72 #include "callback.h"   /* GDB simulator callback interface */
73 #include "remote-sim.h" /* GDB simulator interface */
74
75 #include "support.h"    /* internal support manifests */
76
77 #include "sysdep.h"
78
79 #ifndef PARAMS
80 #define PARAMS(x) 
81 #endif
82
83 char* pr_addr PARAMS ((SIM_ADDR addr));
84 char* pr_uword64 PARAMS ((uword64 addr));
85
86 #ifndef SIGBUS
87 #define SIGBUS SIGSEGV
88 #endif
89
90 /* Get the simulator engine description, without including the code: */
91 #define SIM_MANIFESTS
92 #include "engine.c"
93 #undef SIM_MANIFESTS
94
95 struct sim_state simulator;
96
97 /* The following reserved instruction value is used when a simulator
98    trap is required. NOTE: Care must be taken, since this value may be
99    used in later revisions of the MIPS ISA. */
100 #define RSVD_INSTRUCTION           (0x00000005)
101 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
102
103 #define RSVD_INSTRUCTION_ARG_SHIFT 6
104 #define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
105
106
107 /* NOTE: These numbers depend on the processor architecture being
108    simulated: */
109 #define Interrupt               (0)
110 #define TLBModification         (1)
111 #define TLBLoad                 (2)
112 #define TLBStore                (3)
113 #define AddressLoad             (4)
114 #define AddressStore            (5)
115 #define InstructionFetch        (6)
116 #define DataReference           (7)
117 #define SystemCall              (8)
118 #define BreakPoint              (9)
119 #define ReservedInstruction     (10)
120 #define CoProcessorUnusable     (11)
121 #define IntegerOverflow         (12)    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
122 #define Trap                    (13)
123 #define FPE                     (15)
124 #define Watch                   (23)
125
126 /* The following exception code is actually private to the simulator
127    world. It is *NOT* a processor feature, and is used to signal
128    run-time errors in the simulator. */
129 #define SimulatorFault      (0xFFFFFFFF)
130
131 /* The following are generic to all versions of the MIPS architecture
132    to date: */
133 /* Memory Access Types (for CCA): */
134 #define Uncached                (0)
135 #define CachedNoncoherent       (1)
136 #define CachedCoherent          (2)
137 #define Cached                  (3)
138
139 #define isINSTRUCTION   (1 == 0) /* FALSE */
140 #define isDATA          (1 == 1) /* TRUE */
141
142 #define isLOAD          (1 == 0) /* FALSE */
143 #define isSTORE         (1 == 1) /* TRUE */
144
145 #define isREAL          (1 == 0) /* FALSE */
146 #define isRAW           (1 == 1) /* TRUE */
147
148 #define isTARGET        (1 == 0) /* FALSE */
149 #define isHOST          (1 == 1) /* TRUE */
150
151 /* The "AccessLength" specifications for Loads and Stores. NOTE: This
152    is the number of bytes minus 1. */
153 #define AccessLength_BYTE       (0)
154 #define AccessLength_HALFWORD   (1)
155 #define AccessLength_TRIPLEBYTE (2)
156 #define AccessLength_WORD       (3)
157 #define AccessLength_QUINTIBYTE (4)
158 #define AccessLength_SEXTIBYTE  (5)
159 #define AccessLength_SEPTIBYTE  (6)
160 #define AccessLength_DOUBLEWORD (7)
161 #define AccessLength_QUADWORD   (15)
162
163 #if defined(HASFPU)
164 /* FPU registers must be one of the following types. All other values
165    are reserved (and undefined). */
166 typedef enum {
167  fmt_single  = 0,
168  fmt_double  = 1,
169  fmt_word    = 4,
170  fmt_long    = 5,
171  /* The following are well outside the normal acceptable format
172     range, and are used in the register status vector. */
173  fmt_unknown       = 0x10000000,
174  fmt_uninterpreted = 0x20000000,
175 } FP_formats;
176 #endif /* HASFPU */
177
178 /* NOTE: We cannot avoid globals, since the GDB "sim_" interface does
179    not allow a private variable to be passed around. This means that
180    simulators under GDB can only be single-threaded. However, it would
181    be possible for the simulators to be multi-threaded if GDB allowed
182    for a private pointer to be maintained. i.e. a general "void **ptr"
183    variable that GDB passed around in the argument list to all of
184    sim_xxx() routines. It could be initialised to NULL by GDB, and
185    then updated by sim_open() and used by the other sim_xxx() support
186    functions. This would allow new features in the simulator world,
187    like storing a context - continuing execution to gather a result,
188    and then going back to the point where the context was saved and
189    changing some state before continuing. i.e. the ability to perform
190    UNDOs on simulations. It would also allow the simulation of
191    shared-memory multi-processor systems.
192
193    [NOTE: This is now partially implemented] */
194
195 static host_callback *callback = NULL; /* handle onto the current callback structure */
196
197 /* This is nasty, since we have to rely on matching the register
198    numbers used by GDB. Unfortunately, depending on the MIPS target
199    GDB uses different register numbers. We cannot just include the
200    relevant "gdb/tm.h" link, since GDB may not be configured before
201    the sim world, and also the GDB header file requires too much other
202    state. */
203 /* TODO: Sort out a scheme for *KNOWING* the mapping between real
204    registers, and the numbers that GDB uses. At the moment due to the
205    order that the tools are built, we cannot rely on a configured GDB
206    world whilst constructing the simulator. This means we have to
207    assume the GDB register number mapping. */
208 #ifndef TM_MIPS_H
209 #define LAST_EMBED_REGNUM (89)
210 #endif
211
212 /* To keep this default simulator simple, and fast, we use a direct
213    vector of registers. The internal simulator engine then uses
214    manifests to access the correct slot. */
215 static ut_reg registers[LAST_EMBED_REGNUM + 1];
216 static int register_widths[LAST_EMBED_REGNUM + 1];
217
218 #define GPR     (&registers[0])
219 #if defined(HASFPU)
220 #define FGRIDX  (38)
221 #define FGR     (&registers[FGRIDX])
222 #endif /* HASFPU */
223 #define LO      (registers[33])
224 #define HI      (registers[34])
225 #define PC      (registers[37])
226 #define CAUSE   (registers[36])
227 #define SRIDX   (32)
228 #define SR      (registers[SRIDX])      /* CPU status register */
229 #define FCR0IDX  (71)
230 #define FCR0    (registers[FCR0IDX])    /* really a 32bit register */
231 #define FCR31IDX (70)
232 #define FCR31   (registers[FCR31IDX])   /* really a 32bit register */
233 #define FCSR    (FCR31)
234 #define COCIDX  (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
235
236 /* The following are pseudonyms for standard registers */
237 #define ZERO    (registers[0])
238 #define V0      (registers[2])
239 #define A0      (registers[4])
240 #define A1      (registers[5])
241 #define A2      (registers[6])
242 #define A3      (registers[7])
243 #define SP      (registers[29])
244 #define RA      (registers[31])
245
246
247 /* start-sanitize-r5900 */
248 /* 
249 The R5900 has 128 bit registers, but the hi 64 bits are only touched by 
250 multimedia (MMI) instructions.  The normal mips instructions just use the
251 lower 64 bits.  To avoid changing the older parts of the simulator to 
252 handle this weirdness, the high 64 bits of each register are kept in 
253 a separate array (registers1).  The high 64 bits of any register are by
254 convention refered by adding a '1' to the end of the normal register's 
255 name.  So LO still refers to the low 64 bits of the LO register, LO1
256 refers to the high 64 bits of that same register.
257 */
258
259 /* The high part of each register */
260 static ut_reg registers1[LAST_EMBED_REGNUM + 1];
261
262 #define GPR1     (&registers1[0])
263
264 #define LO1      (registers1[33])
265 #define HI1      (registers1[34])
266
267 #define BYTES_IN_MMI_REGS       (sizeof(registers[0])+sizeof(registers1[0]))
268 #define HALFWORDS_IN_MMI_REGS   (BYTES_IN_MMI_REGS/2)
269 #define WORDS_IN_MMI_REGS       (BYTES_IN_MMI_REGS/4)
270 #define DOUBLEWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/8)
271
272 #define BYTES_IN_MIPS_REGS       (sizeof(registers[0]))
273 #define HALFWORDS_IN_MIPS_REGS   (BYTES_IN_MIPS_REGS/2)
274 #define WORDS_IN_MIPS_REGS       (BYTES_IN_MIPS_REGS/4)
275 #define DOUBLEWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/8)
276
277
278 /*
279 SUB_REG_FETCH - return as lvalue some sub-part of a "register"
280    T  - type of the sub part
281    TC - # of T's in the mips part of the "register"
282    I  - index (from 0) of desired sub part
283    A  - low part of "register"
284    A1 - high part of register
285 */
286 #define SUB_REG_FETCH(T,TC,A,A1,I) (*(((T*)(((I) < (TC)) ? (A) : (A1))) + ((I) % (TC))))
287
288 /* 
289 GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R 
290             where <type> has two letters:
291                   1 is S=signed or U=unsigned
292                   2 is B=byte H=halfword W=word D=doubleword 
293 */
294
295 #define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed char,       BYTES_IN_MIPS_REGS,       A, A1, I)
296 #define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed short,      HALFWORDS_IN_MIPS_REGS,   A, A1, I)
297 #define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed int,        WORDS_IN_MIPS_REGS,       A, A1, I)
298 #define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed long long,  DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
299
300 #define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned char,     BYTES_IN_MIPS_REGS,       A, A1, I)
301 #define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned short,    HALFWORDS_IN_MIPS_REGS,   A, A1, I)
302 #define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned int,      WORDS_IN_MIPS_REGS,       A, A1, I)
303 #define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned long long,DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
304
305
306
307 #define GPR_SB(R,I) SUB_REG_SB(&registers[R], &registers1[R], I)
308 #define GPR_SH(R,I) SUB_REG_SH(&registers[R], &registers1[R], I)
309 #define GPR_SW(R,I) SUB_REG_SW(&registers[R], &registers1[R], I)
310 #define GPR_SD(R,I) SUB_REG_SD(&registers[R], &registers1[R], I)
311
312 #define GPR_UB(R,I) SUB_REG_UB(&registers[R], &registers1[R], I)
313 #define GPR_UH(R,I) SUB_REG_UH(&registers[R], &registers1[R], I)
314 #define GPR_UW(R,I) SUB_REG_UW(&registers[R], &registers1[R], I)
315 #define GPR_UD(R,I) SUB_REG_UD(&registers[R], &registers1[R], I)
316
317
318 #define RS_SB(I) SUB_REG_SB(&rs_reg, &rs_reg1, I)
319 #define RS_SH(I) SUB_REG_SH(&rs_reg, &rs_reg1, I)
320 #define RS_SW(I) SUB_REG_SW(&rs_reg, &rs_reg1, I)
321 #define RS_SD(I) SUB_REG_SD(&rs_reg, &rs_reg1, I)
322
323 #define RS_UB(I) SUB_REG_UB(&rs_reg, &rs_reg1, I)
324 #define RS_UH(I) SUB_REG_UH(&rs_reg, &rs_reg1, I)
325 #define RS_UW(I) SUB_REG_UW(&rs_reg, &rs_reg1, I)
326 #define RS_UD(I) SUB_REG_UD(&rs_reg, &rs_reg1, I)
327
328 #define RT_SB(I) SUB_REG_SB(&rt_reg, &rt_reg1, I)
329 #define RT_SH(I) SUB_REG_SH(&rt_reg, &rt_reg1, I)
330 #define RT_SW(I) SUB_REG_SW(&rt_reg, &rt_reg1, I)
331 #define RT_SD(I) SUB_REG_SD(&rt_reg, &rt_reg1, I)
332
333 #define RT_UB(I) SUB_REG_UB(&rt_reg, &rt_reg1, I)
334 #define RT_UH(I) SUB_REG_UH(&rt_reg, &rt_reg1, I)
335 #define RT_UW(I) SUB_REG_UW(&rt_reg, &rt_reg1, I)
336 #define RT_UD(I) SUB_REG_UD(&rt_reg, &rt_reg1, I)
337
338
339
340 #define LO_SB(I) SUB_REG_SB(&LO, &LO1, I)
341 #define LO_SH(I) SUB_REG_SH(&LO, &LO1, I)
342 #define LO_SW(I) SUB_REG_SW(&LO, &LO1, I)
343 #define LO_SD(I) SUB_REG_SD(&LO, &LO1, I)
344
345 #define LO_UB(I) SUB_REG_UB(&LO, &LO1, I)
346 #define LO_UH(I) SUB_REG_UH(&LO, &LO1, I)
347 #define LO_UW(I) SUB_REG_UW(&LO, &LO1, I)
348 #define LO_UD(I) SUB_REG_UD(&LO, &LO1, I)
349
350 #define HI_SB(I) SUB_REG_SB(&HI, &HI1, I)
351 #define HI_SH(I) SUB_REG_SH(&HI, &HI1, I)
352 #define HI_SW(I) SUB_REG_SW(&HI, &HI1, I)
353 #define HI_SD(I) SUB_REG_SD(&HI, &HI1, I)
354
355 #define HI_UB(I) SUB_REG_UB(&HI, &HI1, I)
356 #define HI_UH(I) SUB_REG_UH(&HI, &HI1, I)
357 #define HI_UW(I) SUB_REG_UW(&HI, &HI1, I)
358 #define HI_UD(I) SUB_REG_UD(&HI, &HI1, I)
359 /* end-sanitize-r5900 */
360
361
362 /* start-sanitize-r5900 */
363 static ut_reg SA;        /* the shift amount register */
364 /* end-sanitize-r5900 */
365
366 static ut_reg EPC = 0; /* Exception PC */
367
368 #if defined(HASFPU)
369 /* Keep the current format state for each register: */
370 static FP_formats fpr_state[32];
371 #endif /* HASFPU */
372
373 /* The following are internal simulator state variables: */
374 static ut_reg IPC = 0; /* internal Instruction PC */
375 static ut_reg DSPC = 0;  /* delay-slot PC */
376
377
378 /* TODO : these should be the bitmasks for these bits within the
379    status register. At the moment the following are VR4300
380    bit-positions: */
381 #define status_KSU_mask  (0x3)          /* mask for KSU bits */
382 #define status_KSU_shift (3)            /* shift for field */
383 #define ksu_kernel       (0x0)
384 #define ksu_supervisor   (0x1)
385 #define ksu_user         (0x2)
386 #define ksu_unknown      (0x3)
387
388 #define status_IE        (1 <<  0)      /* Interrupt enable */
389 #define status_EXL       (1 <<  1)      /* Exception level */
390 #define status_RE        (1 << 25)      /* Reverse Endian in user mode */
391 #define status_FR        (1 << 26)      /* enables MIPS III additional FP registers */
392 #define status_SR        (1 << 20)      /* soft reset or NMI */
393 #define status_BEV       (1 << 22)      /* Location of general exception vectors */
394 #define status_TS        (1 << 21)      /* TLB shutdown has occurred */
395 #define status_ERL       (1 <<  2)      /* Error level */
396 #define status_RP        (1 << 27)      /* Reduced Power mode */
397
398 #define cause_BD        ((unsigned)1 << 31)     /* Exception in branch delay slot */
399
400 #if defined(HASFPU)
401 /* Macro to update FPSR condition-code field. This is complicated by
402    the fact that there is a hole in the index range of the bits within
403    the FCSR register. Also, the number of bits visible depends on the
404    MIPS ISA version being supported. */
405 #define SETFCC(cc,v) {\
406                     int bit = ((cc == 0) ? 23 : (24 + (cc)));\
407                     FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
408                   }
409 #define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1 : 0)
410
411 /* This should be the COC1 value at the start of the preceding
412    instruction: */
413 #define PREVCOC1() ((state & simPCOC1) ? 1 : 0)
414 #endif /* HASFPU */
415
416 /* Standard FCRS bits: */
417 #define IR (0) /* Inexact Result */
418 #define UF (1) /* UnderFlow */
419 #define OF (2) /* OverFlow */
420 #define DZ (3) /* Division by Zero */
421 #define IO (4) /* Invalid Operation */
422 #define UO (5) /* Unimplemented Operation */
423
424 /* Get masks for individual flags: */
425 #if 1 /* SAFE version */
426 #define FP_FLAGS(b)  (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
427 #define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
428 #define FP_CAUSE(b)  (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
429 #else
430 #define FP_FLAGS(b)  (1 << ((b) + 2))
431 #define FP_ENABLE(b) (1 << ((b) + 7))
432 #define FP_CAUSE(b)  (1 << ((b) + 12))
433 #endif
434
435 #define FP_FS         (1 << 24) /* MIPS III onwards : Flush to Zero */
436
437 #define FP_MASK_RM    (0x3)
438 #define FP_SH_RM      (0)
439 #define FP_RM_NEAREST (0) /* Round to nearest        (Round) */
440 #define FP_RM_TOZERO  (1) /* Round to zero           (Trunc) */
441 #define FP_RM_TOPINF  (2) /* Round to Plus infinity  (Ceil) */
442 #define FP_RM_TOMINF  (3) /* Round to Minus infinity (Floor) */
443 #define GETRM()       (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
444
445 /* Slots for delayed register updates. For the moment we just have a
446    fixed number of slots (rather than a more generic, dynamic
447    system). This keeps the simulator fast. However, we only allow for
448    the register update to be delayed for a single instruction
449    cycle. */
450 #define PSLOTS (5) /* Maximum number of instruction cycles */
451 static int    pending_in;
452 static int    pending_out;
453 static int    pending_total;
454 static int    pending_slot_count[PSLOTS];
455 static int    pending_slot_reg[PSLOTS];
456 static ut_reg pending_slot_value[PSLOTS];
457
458 /*---------------------------------------------------------------------------*/
459 /*-- GDB simulator interface ------------------------------------------------*/
460 /*---------------------------------------------------------------------------*/
461
462 static void dotrace PARAMS((FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...));
463 static void sim_warning PARAMS((char *fmt,...));
464 extern void sim_error PARAMS((char *fmt,...));
465 static void ColdReset PARAMS((void));
466 static int AddressTranslation PARAMS((uword64 vAddr,int IorD,int LorS,uword64 *pAddr,int *CCA,int host,int raw));
467 static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64 MemElem1,uword64 pAddr,uword64 vAddr,int raw));
468 static void LoadMemory PARAMS((uword64*memvalp,uword64*memval1p,int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
469 static void SignalException PARAMS((int exception,...));
470 static long getnum PARAMS((char *value));
471 extern void sim_set_profile PARAMS((int frequency));
472 static unsigned int power2 PARAMS((unsigned int value));
473
474 /*---------------------------------------------------------------------------*/
475
476 /* The following are not used for MIPS IV onwards: */
477 #define PENDING_FILL(r,v) {\
478 /* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total); */\
479                             if (pending_slot_reg[pending_in] != (LAST_EMBED_REGNUM + 1))\
480                              sim_warning("Attempt to over-write pending value");\
481                             pending_slot_count[pending_in] = 2;\
482                             pending_slot_reg[pending_in] = (r);\
483                             pending_slot_value[pending_in] = (uword64)(v);\
484 /*printf("DBG: FILL        reg %d value = 0x%s\n",(r),pr_addr(v));*/\
485                             pending_total++;\
486                             pending_in++;\
487                             if (pending_in == PSLOTS)\
488                              pending_in = 0;\
489 /*printf("DBG: FILL AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);*/\
490                           }
491
492 static int LLBIT = 0;
493 /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
494    read-write instructions. It is set when a linked load occurs. It is
495    tested and cleared by the conditional store. It is cleared (during
496    other CPU operations) when a store to the location would no longer
497    be atomic. In particular, it is cleared by exception return
498    instructions. */
499
500 static int HIACCESS = 0;
501 static int LOACCESS = 0;
502 static int HI1ACCESS = 0;
503 static int LO1ACCESS = 0;
504
505 /* ??? The 4300 and a few other processors have interlocks on hi/lo register
506    reads, and hence do not have this problem.  To avoid spurious warnings,
507    we just disable this always.  */
508 #if 1
509 #define CHECKHILO(s)
510 #else
511 /* The HIACCESS and LOACCESS counts are used to ensure that
512    corruptions caused by using the HI or LO register to close to a
513    following operation are spotted. */
514 static ut_reg HLPC = 0;
515 /* If either of the preceding two instructions have accessed the HI or
516    LO registers, then the values they see should be
517    undefined. However, to keep the simulator world simple, we just let
518    them use the value read and raise a warning to notify the user: */
519 #define CHECKHILO(s)    {\
520                           if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\
521                             sim_warning("%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
522                         }
523 #endif
524
525 /* NOTE: We keep the following status flags as bit values (1 for true,
526    0 for false). This allows them to be used in binary boolean
527    operations without worrying about what exactly the non-zero true
528    value is. */
529
530 /* UserMode */
531 #define UserMode        ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
532
533 /* BigEndianMem */
534 /* Hardware configuration. Affects endianness of LoadMemory and
535    StoreMemory and the endianness of Kernel and Supervisor mode
536    execution. The value is 0 for little-endian; 1 for big-endian. */
537 #define BigEndianMem    (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
538 /*(state & simBE) ? 1 : 0)*/
539
540 /* ByteSwapMem */
541 /* This is true if the host and target have different endianness.  */
542 #define ByteSwapMem (CURRENT_TARGET_BYTE_ORDER != CURRENT_HOST_BYTE_ORDER)
543
544 /* ReverseEndian */
545 /* This mode is selected if in User mode with the RE bit being set in
546    SR (Status Register). It reverses the endianness of load and store
547    instructions. */
548 #define ReverseEndian   (((SR & status_RE) && UserMode) ? 1 : 0)
549
550 /* BigEndianCPU */
551 /* The endianness for load and store instructions (0=little;1=big). In
552    User mode this endianness may be switched by setting the state_RE
553    bit in the SR register. Thus, BigEndianCPU may be computed as
554    (BigEndianMem EOR ReverseEndian). */
555 #define BigEndianCPU    (BigEndianMem ^ ReverseEndian) /* Already bits */
556
557 #if !defined(FASTSIM) || defined(PROFILE)
558 /* At the moment these values will be the same, since we do not have
559    access to the pipeline cycle count information from the simulator
560    engine. */
561 static unsigned int instruction_fetches = 0;
562 static unsigned int instruction_fetch_overflow = 0;
563 #endif
564
565 /* Flags in the "state" variable: */
566 #define simHALTEX       (1 << 2)  /* 0 = run; 1 = halt on exception */
567 #define simHALTIN       (1 << 3)  /* 0 = run; 1 = halt on interrupt */
568 #define simTRACE        (1 << 8)  /* 0 = do nothing; 1 = trace address activity */
569 #define simPROFILE      (1 << 9)  /* 0 = do nothing; 1 = gather profiling samples */
570 #define simPCOC0        (1 << 17) /* COC[1] from current */
571 #define simPCOC1        (1 << 18) /* COC[1] from previous */
572 #define simDELAYSLOT    (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */
573 #define simSKIPNEXT     (1 << 25) /* 0 = do nothing; 1 = skip instruction */
574 #define simSIGINT       (1 << 28)  /* 0 = do nothing; 1 = SIGINT has occured */
575 #define simJALDELAYSLOT (1 << 29) /* 1 = in jal delay slot */
576
577 static unsigned int state = 0;
578
579 #define DELAYSLOT()     {\
580                           if (state & simDELAYSLOT)\
581                             sim_warning("Delay slot already activated (branch in delay slot?)");\
582                           state |= simDELAYSLOT;\
583                         }
584
585 #define JALDELAYSLOT()  {\
586                           DELAYSLOT ();\
587                           state |= simJALDELAYSLOT;\
588                         }
589
590 #define NULLIFY()       {\
591                           state &= ~simDELAYSLOT;\
592                           state |= simSKIPNEXT;\
593                         }
594
595 #define INDELAYSLOT()   ((state & simDELAYSLOT) != 0)
596 #define INJALDELAYSLOT() ((state & simJALDELAYSLOT) != 0)
597
598 #define K0BASE  (0x80000000)
599 #define K0SIZE  (0x20000000)
600 #define K1BASE  (0xA0000000)
601 #define K1SIZE  (0x20000000)
602
603 /* Simple run-time monitor support */
604 static unsigned char *monitor = NULL;
605 static ut_reg monitor_base = 0xBFC00000;
606 static unsigned monitor_size = (1 << 11); /* power-of-2 */
607
608 static char *logfile = NULL; /* logging disabled by default */
609 static FILE *logfh = NULL;
610
611 #if defined(TRACE)
612 static char *tracefile = "trace.din"; /* default filename for trace log */
613 static FILE *tracefh = NULL;
614 static void open_trace PARAMS((void));
615 #endif /* TRACE */
616
617 #if defined(PROFILE)
618 static unsigned profile_frequency = 256;
619 static unsigned profile_nsamples = (128 << 10);
620 static unsigned short *profile_hist = NULL;
621 static ut_reg profile_minpc;
622 static ut_reg profile_maxpc;
623 static int profile_shift = 0; /* address shift amount */
624 #endif /* PROFILE */
625
626
627 static SIM_RC
628 mips_option_handler (sd, opt, arg)
629      SIM_DESC sd;
630      int opt;
631      char *arg;
632 {
633   switch (opt)
634     {
635     case 'l':
636       if (arg != NULL) {
637         char *tmp;
638         tmp = (char *)malloc(strlen(arg) + 1);
639         if (tmp == NULL)
640           callback->printf_filtered(callback,"Failed to allocate buffer for logfile name \"%s\"\n",optarg);
641         else {
642           strcpy(tmp,optarg);
643           logfile = tmp;
644         }
645       }
646       return SIM_RC_OK;
647
648     case 'n': /* OK */
649       callback->printf_filtered(callback,"Explicit model selection not yet available (Ignoring \"%s\")\n",optarg);
650       return SIM_RC_FAIL;
651
652     case 't': /* ??? */
653 #if defined(TRACE)
654       /* Eventually the simTRACE flag could be treated as a toggle, to
655          allow external control of the program points being traced
656          (i.e. only from main onwards, excluding the run-time setup,
657          etc.). */
658       if (arg == NULL)
659         state |= simTRACE;
660       else if (strcmp (arg, "yes") == 0)
661         state |= simTRACE;
662       else if (strcmp (arg, "no") == 0)
663         state &= ~simTRACE;
664       else
665         {
666           fprintf (stderr, "Unreconized trace option `%s'\n", arg);
667           return SIM_RC_FAIL;
668         }
669       return SIM_RC_OK;
670 #else /* !TRACE */
671       fprintf(stderr,"\
672 Simulator constructed without tracing support (for performance).\n\
673 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
674       return SIM_RC_FAIL;
675 #endif /* !TRACE */
676
677     case 'z':
678 #if defined(TRACE)
679       if (optarg != NULL) {
680         char *tmp;
681         tmp = (char *)malloc(strlen(optarg) + 1);
682         if (tmp == NULL)
683           {
684             callback->printf_filtered(callback,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
685             return SIM_RC_FAIL;
686           }
687         else {
688           strcpy(tmp,optarg);
689           tracefile = tmp;
690           callback->printf_filtered(callback,"Placing trace information into file \"%s\"\n",tracefile);
691         }
692       }
693 #endif /* TRACE */
694       return SIM_RC_OK;
695
696     case 'p':
697 #if defined(PROFILE)
698       state |= simPROFILE;
699       return SIM_RC_OK;
700 #else /* !PROFILE */
701       fprintf(stderr,"\
702 Simulator constructed without profiling support (for performance).\n\
703 Re-compile simulator with \"-DPROFILE\" to enable this option.\n");
704       return SIM_RC_FAIL;
705 #endif /* !PROFILE */
706
707     case 'x':
708 #if defined(PROFILE)
709       profile_nsamples = (unsigned)getnum(optarg);
710 #endif /* PROFILE */
711       return SIM_RC_OK;
712
713     case 'y':
714 #if defined(PROFILE)
715       sim_set_profile((int)getnum(optarg));
716 #endif /* PROFILE */
717       return SIM_RC_OK;
718
719     }
720
721   return SIM_RC_OK;
722 }
723
724 static const OPTION mips_options[] =
725 {
726   { {"log",      required_argument, NULL,'l'},
727       'l', "FILE", "Log file",
728       mips_option_handler },
729   { {"name",     required_argument, NULL,'n'},
730       'n', "MODEL", "Select arch model",
731       mips_option_handler },
732   { {"profile",  optional_argument, NULL,'p'},
733       'p', "on|off", "Enable profiling",
734       mips_option_handler },
735   { {"trace",    optional_argument, NULL,'t'},
736       't', "on|off", "Enable tracing",
737       mips_option_handler },
738   { {"tracefile",required_argument, NULL,'z'},
739       'z', "FILE", "Write trace to file",
740       mips_option_handler },
741   { {"frequency",required_argument, NULL,'y'},
742       'y', "FREQ", "Profile frequency",
743       mips_option_handler },
744   { {"samples",  required_argument, NULL,'x'},
745       'y', "SIZE", "Profile sample size",
746       mips_option_handler },
747   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
748 };
749
750
751 int interrupt_pending;
752
753 static void
754 interrupt_event (SIM_DESC sd, void *data)
755 {
756   if (SR & status_IE)
757     {
758       interrupt_pending = 0;
759       SignalException (Interrupt);
760     }
761   else if (!interrupt_pending)
762     sim_events_schedule (sd, 1, interrupt_event, data);
763 }
764
765
766
767 /*---------------------------------------------------------------------------*/
768 /*-- GDB simulator interface ------------------------------------------------*/
769 /*---------------------------------------------------------------------------*/
770
771 SIM_DESC
772 sim_open (kind,cb,argv)
773      SIM_OPEN_KIND kind;
774      host_callback *cb;
775      char **argv;
776 {
777   SIM_DESC sd = &simulator;
778
779   STATE_OPEN_KIND (sd) = kind;
780   STATE_MAGIC (sd) = SIM_MAGIC_NUMBER;
781   STATE_CALLBACK (sd) = cb;
782   callback = cb;
783   CPU_STATE (STATE_CPU (sd, 0)) = sd;
784
785   /* FIXME: watchpoints code shouldn't need this */
786   STATE_WATCHPOINTS (sd)->pc = &(PC);
787   STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
788   STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
789
790   /* memory defaults (unless sim_size was here first) */
791   if (STATE_MEM_SIZE (sd) == 0)
792     STATE_MEM_SIZE (sd) = (2 << 20);
793   STATE_MEM_BASE (sd) = K1BASE;
794
795   if (callback == NULL) {
796     fprintf(stderr,"SIM Error: sim_open() called without callbacks attached\n");
797     return 0;
798   }
799
800   state = 0;
801   
802   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
803     return 0;
804   sim_add_option_table (sd, mips_options);
805
806   /* getopt will print the error message so we just have to exit if this fails.
807      FIXME: Hmmm...  in the case of gdb we need getopt to call
808      print_filtered.  */
809   if (sim_parse_args (sd, argv) != SIM_RC_OK)
810     {
811       /* Uninstall the modules to avoid memory leaks,
812          file descriptor leaks, etc.  */
813       sim_module_uninstall (sd);
814       return 0;
815     }
816
817   if (sim_post_argv_init (sd) != SIM_RC_OK)
818     {
819       /* Uninstall the modules to avoid memory leaks,
820          file descriptor leaks, etc.  */
821       sim_module_uninstall (sd);
822       return 0;
823     }
824
825   /* verify assumptions the simulator made about the host type system.
826      This macro does not return if there is a problem */
827   CHECKSIM();
828
829 #if defined(HASFPU)
830   /* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
831      and DOUBLE binary formats. This is a bit nasty, requiring that we
832      trust the explicit manifests held in the source: */
833   /* TODO: We need to cope with the simulated target and the host not
834      having the same endianness. This will require the high and low
835      words of a (double) to be swapped when converting between the
836      host and the simulated target. */
837   {
838     union {
839       unsigned int i[2];
840       double d;
841       float f[2];
842     } s;
843
844     s.d = (double)523.2939453125;
845
846     if ((s.i[0] == 0 && (s.f[1] != (float)4.01102924346923828125
847                          || s.i[1] != 0x40805A5A))
848         || (s.i[1] == 0 && (s.f[0] != (float)4.01102924346923828125
849                             || s.i[0] != 0x40805A5A)))
850       {
851         fprintf(stderr,"The host executing the simulator does not seem to have IEEE 754-1985 std FP\n");
852         return 0;
853       }
854   }
855 #endif /* HASFPU */
856
857   /* This is NASTY, in that we are assuming the size of specific
858      registers: */
859   {
860     int rn;
861     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++) {
862       if (rn < 32)
863        register_widths[rn] = GPRLEN;
864       else if ((rn >= FGRIDX) && (rn < (FGRIDX + 32)))
865        register_widths[rn] = GPRLEN;
866       else if ((rn >= 33) && (rn <= 37))
867        register_widths[rn] = GPRLEN;
868       else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89)))
869        register_widths[rn] = 32;
870       else
871        register_widths[rn] = 0;
872     }
873   }
874
875
876   if (logfile != NULL) {
877     if (strcmp(logfile,"-") == 0)
878      logfh = stdout;
879     else {
880       logfh = fopen(logfile,"wb+");
881       if (logfh == NULL) {
882         callback->printf_filtered(callback,"Failed to create file \"%s\", writing log information to stderr.\n",tracefile);
883         logfh = stderr;
884       }
885     }
886   }
887
888   /* FIXME: In the future both of these malloc's can be replaced by
889      calls to sim-core.  */
890
891   /* If the host has "mmap" available we could use it to provide a
892      very large virtual address space for the simulator, since memory
893      would only be allocated within the "mmap" space as it is
894      accessed. This can also be linked to the architecture specific
895      support, required to simulate the MMU. */
896   sim_size(STATE_MEM_SIZE (sd));
897   /* NOTE: The above will also have enabled any profiling state! */
898
899   /* Create the monitor address space as well */
900   monitor = (unsigned char *)calloc(1,monitor_size);
901   if (!monitor)
902     fprintf(stderr,"Not enough VM for monitor simulation (%d bytes)\n",
903             monitor_size);
904
905 #if defined(TRACE)
906   if (state & simTRACE)
907     open_trace();
908 #endif /* TRACE */
909
910   return sd;
911 }
912
913 #if defined(TRACE)
914 static void
915 open_trace()
916 {
917   tracefh = fopen(tracefile,"wb+");
918   if (tracefh == NULL)
919     {
920       sim_warning("Failed to create file \"%s\", writing trace information to stderr.",tracefile);
921       tracefh = stderr;
922   }
923 }
924 #endif /* TRACE */
925
926 /* For the profile writing, we write the data in the host
927    endianness. This unfortunately means we are assuming that the
928    profile file we create is processed on the same host executing the
929    simulator. The gmon.out file format should either have an explicit
930    endianness, or a method of encoding the endianness in the file
931    header. */
932 static int
933 writeout32(fh,val)
934      FILE *fh;
935      unsigned int val;
936 {
937   char buff[4];
938   int res = 1;
939
940   if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
941     buff[3] = ((val >>  0) & 0xFF);
942     buff[2] = ((val >>  8) & 0xFF);
943     buff[1] = ((val >> 16) & 0xFF);
944     buff[0] = ((val >> 24) & 0xFF);
945   } else {
946     buff[0] = ((val >>  0) & 0xFF);
947     buff[1] = ((val >>  8) & 0xFF);
948     buff[2] = ((val >> 16) & 0xFF);
949     buff[3] = ((val >> 24) & 0xFF);
950   }
951   if (fwrite(buff,4,1,fh) != 1) {
952     sim_warning("Failed to write 4bytes to the profile file");
953     res = 0;
954   }
955   return(res);
956 }
957
958 static int
959 writeout16(fh,val)
960      FILE *fh;
961      unsigned short val;
962 {
963   char buff[2];
964   int res = 1;
965   if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
966     buff[1] = ((val >>  0) & 0xFF);
967     buff[0] = ((val >>  8) & 0xFF);
968   } else {
969     buff[0] = ((val >>  0) & 0xFF);
970     buff[1] = ((val >>  8) & 0xFF);
971   }
972   if (fwrite(buff,2,1,fh) != 1) {
973     sim_warning("Failed to write 2bytes to the profile file");
974     res = 0;
975   }
976   return(res);
977 }
978
979 void
980 sim_close (sd, quitting)
981      SIM_DESC sd;
982      int quitting;
983 {
984 #ifdef DEBUG
985   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
986 #endif
987
988   /* Cannot assume sim_kill() has been called */
989   /* "quitting" is non-zero if we cannot hang on errors */
990
991   /* Ensure that any resources allocated through the callback
992      mechanism are released: */
993   callback->shutdown(callback);
994
995 #if defined(PROFILE)
996   if ((state & simPROFILE) && (profile_hist != NULL)) {
997     FILE *pf = fopen("gmon.out","wb");
998     unsigned loop;
999
1000     if (pf == NULL)
1001      sim_warning("Failed to open \"gmon.out\" profile file");
1002     else {
1003       int ok;
1004 #ifdef DEBUG
1005       printf("DBG: minpc = 0x%s\n",pr_addr(profile_minpc));
1006       printf("DBG: maxpc = 0x%s\n",pr_addr(profile_maxpc));
1007 #endif /* DEBUG */
1008       ok = writeout32(pf,(unsigned int)profile_minpc);
1009       if (ok)
1010        ok = writeout32(pf,(unsigned int)profile_maxpc);
1011       if (ok)
1012        ok = writeout32(pf,(profile_nsamples * 2) + 12); /* size of sample buffer (+ header) */
1013 #ifdef DEBUG
1014       printf("DBG: nsamples = %d (size = 0x%08X)\n",profile_nsamples,((profile_nsamples * 2) + 12));
1015 #endif /* DEBUG */
1016       for (loop = 0; (ok && (loop < profile_nsamples)); loop++) {
1017         ok = writeout16(pf,profile_hist[loop]);
1018         if (!ok)
1019          break;
1020       }
1021
1022       fclose(pf);
1023     }
1024
1025     free(profile_hist);
1026     profile_hist = NULL;
1027     state &= ~simPROFILE;
1028   }
1029 #endif /* PROFILE */
1030
1031 #if defined(TRACE)
1032   if (tracefh != NULL && tracefh != stderr)
1033    fclose(tracefh);
1034   tracefh = NULL;
1035   state &= ~simTRACE;
1036 #endif /* TRACE */
1037
1038   if (logfh != NULL && logfh != stdout && logfh != stderr)
1039    fclose(logfh);
1040   logfh = NULL;
1041
1042   if (STATE_MEMORY (sd) != NULL)
1043     free(STATE_MEMORY (sd)); /* cfree not available on all hosts */
1044   STATE_MEMORY (sd) = NULL;
1045
1046   return;
1047 }
1048
1049
1050 int
1051 sim_write (sd,addr,buffer,size)
1052      SIM_DESC sd;
1053      SIM_ADDR addr;
1054      unsigned char *buffer;
1055      int size;
1056 {
1057   int index = size;
1058   uword64 vaddr = (uword64)addr;
1059
1060   /* Return the number of bytes written, or zero if error. */
1061 #ifdef DEBUG
1062   callback->printf_filtered(callback,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
1063 #endif
1064
1065   /* We provide raw read and write routines, since we do not want to
1066      count the GDB memory accesses in our statistics gathering. */
1067
1068   /* There is a lot of code duplication in the individual blocks
1069      below, but the variables are declared locally to a block to give
1070      the optimiser the best chance of improving the code. We have to
1071      perform slow byte reads from the host memory, to ensure that we
1072      get the data into the correct endianness for the (simulated)
1073      target memory world. */
1074
1075   /* Mask count to get odd byte, odd halfword, and odd word out of the
1076      way. We can then perform doubleword transfers to and from the
1077      simulator memory for optimum performance. */
1078   if (index && (index & 1)) {
1079     uword64 paddr;
1080     int cca;
1081     if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1082       uword64 value = ((uword64)(*buffer++));
1083       StoreMemory(cca,AccessLength_BYTE,value,0,paddr,vaddr,isRAW);
1084     }
1085     vaddr++;
1086     index &= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
1087   }
1088   if (index && (index & 2)) {
1089     uword64 paddr;
1090     int cca;
1091     if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1092       uword64 value;
1093       /* We need to perform the following magic to ensure that that
1094          bytes are written into same byte positions in the target memory
1095          world, regardless of the endianness of the host. */
1096       if (BigEndianMem) {
1097         value =  ((uword64)(*buffer++) << 8);
1098         value |= ((uword64)(*buffer++) << 0);
1099       } else {
1100         value =  ((uword64)(*buffer++) << 0);
1101         value |= ((uword64)(*buffer++) << 8);
1102       }
1103       StoreMemory(cca,AccessLength_HALFWORD,value,0,paddr,vaddr,isRAW);
1104     }
1105     vaddr += 2;
1106     index &= ~2;
1107   }
1108   if (index && (index & 4)) {
1109     uword64 paddr;
1110     int cca;
1111     if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1112       uword64 value;
1113       if (BigEndianMem) {
1114         value =  ((uword64)(*buffer++) << 24);
1115         value |= ((uword64)(*buffer++) << 16);
1116         value |= ((uword64)(*buffer++) << 8);
1117         value |= ((uword64)(*buffer++) << 0);
1118       } else {
1119         value =  ((uword64)(*buffer++) << 0);
1120         value |= ((uword64)(*buffer++) << 8);
1121         value |= ((uword64)(*buffer++) << 16);
1122         value |= ((uword64)(*buffer++) << 24);
1123       }
1124       StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1125     }
1126     vaddr += 4;
1127     index &= ~4;
1128   }
1129   for (;index; index -= 8) {
1130     uword64 paddr;
1131     int cca;
1132     if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1133       uword64 value;
1134       if (BigEndianMem) {
1135         value =  ((uword64)(*buffer++) << 56);
1136         value |= ((uword64)(*buffer++) << 48);
1137         value |= ((uword64)(*buffer++) << 40);
1138         value |= ((uword64)(*buffer++) << 32);
1139         value |= ((uword64)(*buffer++) << 24);
1140         value |= ((uword64)(*buffer++) << 16);
1141         value |= ((uword64)(*buffer++) << 8);
1142         value |= ((uword64)(*buffer++) << 0);
1143       } else {
1144         value =  ((uword64)(*buffer++) << 0);
1145         value |= ((uword64)(*buffer++) << 8);
1146         value |= ((uword64)(*buffer++) << 16);
1147         value |= ((uword64)(*buffer++) << 24);
1148         value |= ((uword64)(*buffer++) << 32);
1149         value |= ((uword64)(*buffer++) << 40);
1150         value |= ((uword64)(*buffer++) << 48);
1151         value |= ((uword64)(*buffer++) << 56);
1152       }
1153       StoreMemory(cca,AccessLength_DOUBLEWORD,value,0,paddr,vaddr,isRAW);
1154     }
1155     vaddr += 8;
1156   }
1157
1158   return(size);
1159 }
1160
1161 int
1162 sim_read (sd,addr,buffer,size)
1163      SIM_DESC sd;
1164      SIM_ADDR addr;
1165      unsigned char *buffer;
1166      int size;
1167 {
1168   int index;
1169
1170   /* Return the number of bytes read, or zero if error. */
1171 #ifdef DEBUG
1172   callback->printf_filtered(callback,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
1173 #endif /* DEBUG */
1174
1175   /* TODO: Perform same optimisation as the sim_write() code
1176      above. NOTE: This will require a bit more work since we will need
1177      to ensure that the source physical address is doubleword aligned
1178      before, and then deal with trailing bytes. */
1179   for (index = 0; (index < size); index++) {
1180     uword64 vaddr,paddr,value;
1181     int cca;
1182     vaddr = (uword64)addr + index;
1183     if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&cca,isTARGET,isRAW)) {
1184       LoadMemory(&value,NULL,cca,AccessLength_BYTE,paddr,vaddr,isDATA,isRAW);
1185       buffer[index] = (unsigned char)(value&0xFF);
1186     } else
1187      break;
1188   }
1189
1190   return(index);
1191 }
1192
1193 void
1194 sim_store_register (sd,rn,memory)
1195      SIM_DESC sd;
1196      int rn;
1197      unsigned char *memory;
1198 {
1199   /* NOTE: gdb (the client) stores registers in target byte order
1200      while the simulator uses host byte order */
1201 #ifdef DEBUG
1202   callback->printf_filtered(callback,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
1203 #endif /* DEBUG */
1204
1205   /* Unfortunately this suffers from the same problem as the register
1206      numbering one. We need to know what the width of each logical
1207      register number is for the architecture being simulated. */
1208
1209   if (register_widths[rn] == 0)
1210     sim_warning("Invalid register width for %d (register store ignored)",rn);
1211   else
1212     {
1213       if (register_widths[rn] == 32)
1214         registers[rn] = T2H_4 (*(unsigned int*)memory);
1215       else
1216         registers[rn] = T2H_8 (*(uword64*)memory);
1217     }
1218
1219   return;
1220 }
1221
1222 void
1223 sim_fetch_register (sd,rn,memory)
1224      SIM_DESC sd;
1225      int rn;
1226      unsigned char *memory;
1227 {
1228   /* NOTE: gdb (the client) stores registers in target byte order
1229      while the simulator uses host byte order */
1230 #ifdef DEBUG
1231   callback->printf_filtered(callback,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
1232 #endif /* DEBUG */
1233
1234   if (register_widths[rn] == 0)
1235     sim_warning("Invalid register width for %d (register fetch ignored)",rn);
1236   else
1237     {
1238       if (register_widths[rn] == 32)
1239         *((unsigned int *)memory) = H2T_4 ((unsigned int)(registers[rn] & 0xFFFFFFFF));
1240       else /* 64bit register */
1241         *((uword64 *)memory) = H2T_8 (registers[rn]);
1242     }
1243
1244   return;
1245 }
1246
1247
1248 void
1249 sim_info (sd,verbose)
1250      SIM_DESC sd;
1251      int verbose;
1252 {
1253   
1254   return;
1255   /* Accessed from the GDB "info files" command: */
1256   if (STATE_VERBOSE_P (sd) || verbose)
1257     {
1258       
1259       sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
1260                      (PROCESSOR_64BIT ? 64 : 32),
1261                      (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
1262       
1263       sim_io_printf (sd, "0x%08X bytes of memory at 0x%s\n",
1264                      STATE_MEM_SIZE (sd),
1265                      pr_addr (STATE_MEM_BASE (sd)));
1266       
1267 #if !defined(FASTSIM)
1268 #if 0
1269       /* at present this simulator executes one instruction per
1270          simulator cycle.  Consequently this data never changes */
1271       if (instruction_fetch_overflow != 0)
1272         sim_io_printf (sd, "Instruction fetches = 0x%08X%08X\n",
1273                        instruction_fetch_overflow, instruction_fetches);
1274       else
1275         sim_io_printf (sd, "Instruction fetches = %d\n", instruction_fetches);
1276 #endif
1277       /* It would be a useful feature, if when performing multi-cycle
1278          simulations (rather than single-stepping) we keep the start and
1279          end times of the execution, so that we can give a performance
1280          figure for the simulator. */
1281 #endif /* !FASTSIM */
1282       sim_io_printf (sd, "Number of execution cycles = %ld\n",
1283                      (long) sim_events_time (sd));
1284       
1285       /* print information pertaining to MIPS ISA and architecture being simulated */
1286       /* things that may be interesting */
1287       /* instructions executed - if available */
1288       /* cycles executed - if available */
1289       /* pipeline stalls - if available */
1290       /* virtual time taken */
1291       /* profiling size */
1292       /* profiling frequency */
1293       /* profile minpc */
1294       /* profile maxpc */
1295     }
1296 }
1297
1298 SIM_RC
1299 sim_load (sd,prog,abfd,from_tty)
1300      SIM_DESC sd;
1301      char *prog;
1302      bfd *abfd;
1303      int from_tty;
1304 {
1305   bfd *prog_bfd;
1306
1307   prog_bfd = sim_load_file (sd,
1308                             STATE_MY_NAME (sd),
1309                             callback,
1310                             prog,
1311                             /* pass NULL for abfd, we always open our own */
1312                             NULL,
1313                             STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG);
1314   if (prog_bfd == NULL)
1315     return SIM_RC_FAIL;
1316   sim_analyze_program (sd, prog_bfd);
1317
1318   /* Configure/verify the target byte order and other runtime
1319      configuration options */
1320   sim_config (sd, PREFERED_TARGET_BYTE_ORDER(prog_bfd));
1321
1322   /* (re) Write the monitor trap address handlers into the monitor
1323      (eeprom) address space.  This can only be done once the target
1324      endianness has been determined. */
1325   {
1326     unsigned loop;
1327     /* Entry into the IDT monitor is via fixed address vectors, and
1328        not using machine instructions. To avoid clashing with use of
1329        the MIPS TRAP system, we place our own (simulator specific)
1330        "undefined" instructions into the relevant vector slots. */
1331     for (loop = 0; (loop < monitor_size); loop += 4) {
1332       uword64 vaddr = (monitor_base + loop);
1333       uword64 paddr;
1334       int cca;
1335       if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
1336         StoreMemory(cca, AccessLength_WORD,
1337                     (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)),
1338                     0, paddr, vaddr, isRAW);
1339     }
1340     /* The PMON monitor uses the same address space, but rather than
1341        branching into it the address of a routine is loaded. We can
1342        cheat for the moment, and direct the PMON routine to IDT style
1343        instructions within the monitor space. This relies on the IDT
1344        monitor not using the locations from 0xBFC00500 onwards as its
1345        entry points.*/
1346     for (loop = 0; (loop < 24); loop++)
1347       {
1348         uword64 vaddr = (monitor_base + 0x500 + (loop * 4));
1349         uword64 paddr;
1350         int cca;
1351         unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
1352         switch (loop)
1353           {
1354             case 0: /* read */
1355               value = 7;
1356               break;
1357
1358             case 1: /* write */
1359               value = 8;
1360               break;
1361
1362             case 2: /* open */
1363               value = 6;
1364               break;
1365
1366             case 3: /* close */
1367               value = 10;
1368               break;
1369
1370             case 5: /* printf */
1371               value = ((0x500 - 16) / 8); /* not an IDT reason code */
1372               break;
1373
1374             case 8: /* cliexit */
1375               value = 17;
1376               break;
1377
1378             case 11: /* flush_cache */
1379               value = 28;
1380               break;
1381           }
1382             /* FIXME - should monitor_base be SIM_ADDR?? */
1383         value = ((unsigned int)monitor_base + (value * 8));
1384         if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
1385           StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1386         else
1387           sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
1388
1389         /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500.  */
1390         vaddr -= 0x300;
1391         if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
1392           StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1393         else
1394           sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
1395       }
1396   }
1397
1398   return SIM_RC_OK;
1399 }
1400
1401 SIM_RC
1402 sim_create_inferior (sd, argv,env)
1403      SIM_DESC sd;
1404      char **argv;
1405      char **env;
1406 {
1407
1408 #ifdef DEBUG
1409   printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1410          pr_addr(PC));
1411 #endif /* DEBUG */
1412
1413   ColdReset();
1414   /* If we were providing a more complete I/O, co-processor or memory
1415      simulation, we should perform any "device" initialisation at this
1416      point. This can include pre-loading memory areas with particular
1417      patterns (e.g. simulating ROM monitors). */
1418
1419 #if 1
1420   PC = (uword64) STATE_START_ADDR(sd);
1421 #else
1422   /* TODO: Sort this properly. SIM_ADDR may already be a 64bit value: */
1423   PC = SIGNEXTEND(bfd_get_start_address(prog_bfd),32);
1424 #endif
1425
1426   /* Prepare to execute the program to be simulated */
1427   /* argv and env are NULL terminated lists of pointers */
1428
1429   if (argv || env) {
1430 #if 0 /* def DEBUG */
1431     callback->printf_filtered(callback,"sim_create_inferior() : passed arguments ignored\n");
1432     {
1433      char **cptr;
1434      for (cptr = argv; (cptr && *cptr); cptr++)
1435       printf("DBG: arg \"%s\"\n",*cptr);
1436     }
1437 #endif /* DEBUG */
1438     /* We should really place the argv slot values into the argument
1439        registers, and onto the stack as required. However, this
1440        assumes that we have a stack defined, which is not necessarily
1441        true at the moment. */
1442   }
1443
1444   return SIM_RC_OK;
1445 }
1446
1447 void
1448 sim_kill (sd)
1449      SIM_DESC sd;
1450 {
1451 #if 1
1452   /* This routine should be for terminating any existing simulation
1453      thread. Since we are single-threaded only at the moment, this is
1454      not an issue. It should *NOT* be used to terminate the
1455      simulator. */
1456 #else /* do *NOT* call sim_close */
1457   sim_close(sd, 1); /* Do not hang on errors */
1458   /* This would also be the point where any memory mapped areas used
1459      by the simulator should be released. */
1460 #endif
1461   return;
1462 }
1463
1464 typedef enum {e_terminate,e_help,e_setmemsize,e_reset} e_cmds;
1465
1466 static struct t_sim_command {
1467  e_cmds id;
1468  const char *name;
1469  const char *help;
1470 } sim_commands[] = {
1471   {e_help,      "help",           ": Show MIPS simulator private commands"},
1472   {e_setmemsize,"set-memory-size","<n> : Specify amount of memory simulated"},
1473   {e_reset,     "reset-system",   ": Reset the simulated processor"},
1474   {e_terminate, NULL}
1475 };
1476
1477 void
1478 sim_do_command (sd,cmd)
1479      SIM_DESC sd;
1480      char *cmd;
1481 {
1482   struct t_sim_command *cptr;
1483
1484   if (callback == NULL) {
1485     fprintf(stderr,"Simulator not enabled: \"target sim\" should be used to activate\n");
1486     return;
1487   }
1488
1489   if (!(cmd && *cmd != '\0'))
1490    cmd = "help";
1491
1492   /* NOTE: Accessed from the GDB "sim" commmand: */
1493   for (cptr = sim_commands; cptr && cptr->name; cptr++)
1494     if (strncmp (cmd, cptr->name, strlen(cptr->name)) == 0)
1495       {
1496         cmd += strlen(cptr->name);
1497         switch (cptr->id) {
1498         case e_help: /* no arguments */
1499           { /* no arguments */
1500             struct t_sim_command *lptr;
1501             callback->printf_filtered(callback,"List of MIPS simulator commands:\n");
1502             for (lptr = sim_commands; lptr->name; lptr++)
1503               callback->printf_filtered(callback,"%s %s\n",lptr->name,lptr->help);
1504             sim_args_command (sd, "help");
1505           }
1506         break;
1507
1508         case e_setmemsize: /* memory size argument */
1509           {
1510             unsigned int newsize = (unsigned int)getnum(cmd);
1511             sim_size(newsize);
1512           }
1513         break;
1514
1515         case e_reset: /* no arguments */
1516           ColdReset();
1517           /* NOTE: See the comments in sim_open() relating to device
1518              initialisation. */
1519           break;
1520
1521         default:
1522           callback->printf_filtered(callback,"FATAL: Matched \"%s\", but failed to match command id %d.\n",cmd,cptr->id);
1523           break;
1524         }
1525         break;
1526       }
1527
1528   if (!(cptr->name))
1529     {
1530       /* try for a common command when the sim specific lookup fails */
1531       if (sim_args_command (sd, cmd) != SIM_RC_OK)
1532         callback->printf_filtered(callback,"Error: \"%s\" is not a valid MIPS simulator command.\n",cmd);
1533     }
1534
1535   return;
1536 }
1537
1538 /*---------------------------------------------------------------------------*/
1539 /* NOTE: The following routines do not seem to be used by GDB at the
1540    moment. However, they may be useful to the standalone simulator
1541    world. */
1542
1543
1544 /* The profiling format is described in the "gmon_out.h" header file */
1545 void
1546 sim_set_profile (n)
1547      int n;
1548 {
1549 #if defined(PROFILE)
1550   profile_frequency = n;
1551   state |= simPROFILE;
1552 #endif /* PROFILE */
1553   return;
1554 }
1555
1556 void
1557 sim_set_profile_size (n)
1558      int n;
1559 {
1560   SIM_DESC sd = &simulator;
1561 #if defined(PROFILE)
1562   if (state & simPROFILE) {
1563     int bsize;
1564
1565     /* Since we KNOW that the memory banks are a power-of-2 in size: */
1566     profile_nsamples = power2(n);
1567     profile_minpc = STATE_MEM_BASE (sd);
1568     profile_maxpc = (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd));
1569
1570     /* Just in-case we are sampling every address: NOTE: The shift
1571        right of 2 is because we only have word-aligned PC addresses. */
1572     if (profile_nsamples > (STATE_MEM_SIZE (sd) >> 2))
1573      profile_nsamples = (STATE_MEM_SIZE (sd) >> 2);
1574
1575     /* Since we are dealing with power-of-2 values: */
1576     profile_shift = (((STATE_MEM_SIZE (sd) >> 2) / profile_nsamples) - 1);
1577
1578     bsize = (profile_nsamples * sizeof(unsigned short));
1579     if (profile_hist == NULL)
1580      profile_hist = (unsigned short *)calloc(64,(bsize / 64));
1581     else
1582      profile_hist = (unsigned short *)realloc(profile_hist,bsize);
1583     if (profile_hist == NULL) {
1584       sim_warning("Failed to allocate VM for profiling buffer (0x%08X bytes)",bsize);
1585       state &= ~simPROFILE;
1586     }
1587   }
1588 #endif /* PROFILE */
1589
1590   return;
1591 }
1592
1593 void
1594 sim_size(newsize)
1595      int newsize;
1596 {
1597   SIM_DESC sd = &simulator;
1598   char *new;
1599   /* Used by "run", and internally, to set the simulated memory size */
1600   if (newsize == 0) {
1601     callback->printf_filtered(callback,"Zero not valid: Memory size still 0x%08X bytes\n",STATE_MEM_SIZE (sd));
1602     return;
1603   }
1604   newsize = power2(newsize);
1605   if (STATE_MEMORY (sd) == NULL)
1606    new = (char *)calloc(64,(STATE_MEM_SIZE (sd) / 64));
1607   else
1608    new = (char *)realloc(STATE_MEMORY (sd),newsize);
1609   if (new == NULL) {
1610     if (STATE_MEMORY (sd) == NULL)
1611      sim_error("Not enough VM for simulation memory of 0x%08X bytes",STATE_MEM_SIZE (sd));
1612     else
1613      sim_warning("Failed to resize memory (still 0x%08X bytes)",STATE_MEM_SIZE (sd));
1614   } else {
1615     STATE_MEM_SIZE (sd) = (unsigned)newsize;
1616     STATE_MEMORY (sd) = new;
1617 #if defined(PROFILE)
1618     /* Ensure that we sample across the new memory range */
1619     sim_set_profile_size(profile_nsamples);
1620 #endif /* PROFILE */
1621   }
1622
1623   return;
1624 }
1625
1626 int
1627 sim_trace(sd)
1628      SIM_DESC sd;
1629 {
1630   sim_io_eprintf (sd, "Sim trace not supported");
1631 #if 0
1632   /* This routine is called by the "run" program, when detailed
1633      execution information is required. Rather than executing a single
1634      instruction, and looping around externally... we just start
1635      simulating, returning TRUE when the simulator stops (for whatever
1636      reason). */
1637
1638 #if defined(TRACE)
1639   /* Ensure tracing is enabled, if available */
1640   if (tracefh == NULL)
1641     {
1642       open_trace();
1643       state |= simTRACE;
1644     }
1645 #endif /* TRACE */
1646
1647 #if 0
1648   state &= ~(simSTOP | simSTEP); /* execute until event */
1649 #endif
1650   state |= (simHALTEX | simHALTIN); /* treat interrupt event as exception */
1651   /* Start executing instructions from the current state (set
1652      explicitly by register updates, or by sim_create_inferior): */
1653   simulate();
1654
1655 #endif
1656   return(1);
1657 }
1658
1659 /*---------------------------------------------------------------------------*/
1660 /*-- Private simulator support interface ------------------------------------*/
1661 /*---------------------------------------------------------------------------*/
1662
1663 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1664 static void
1665 sim_monitor(reason)
1666      unsigned int reason;
1667 {
1668   SIM_DESC sd = &simulator;
1669 #ifdef DEBUG
1670   printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1671 #endif /* DEBUG */
1672
1673   /* The IDT monitor actually allows two instructions per vector
1674      slot. However, the simulator currently causes a trap on each
1675      individual instruction. We cheat, and lose the bottom bit. */
1676   reason >>= 1;
1677
1678   /* The following callback functions are available, however the
1679      monitor we are simulating does not make use of them: get_errno,
1680      isatty, lseek, rename, system, time and unlink */
1681   switch (reason) {
1682     case 6: /* int open(char *path,int flags) */
1683       {
1684         uword64 paddr;
1685         int cca;
1686         if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
1687          V0 = callback->open(callback,(char *)((int)paddr),(int)A1);
1688         else
1689          sim_error("Attempt to pass pointer that does not reference simulated memory");
1690       }
1691       break;
1692
1693     case 7: /* int read(int file,char *ptr,int len) */
1694       {
1695         uword64 paddr;
1696         int cca;
1697         if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
1698          V0 = callback->read(callback,(int)A0,(char *)((int)paddr),(int)A2);
1699         else
1700          sim_error("Attempt to pass pointer that does not reference simulated memory");
1701       }
1702       break;
1703
1704     case 8: /* int write(int file,char *ptr,int len) */
1705       {
1706         uword64 paddr;
1707         int cca;
1708         if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
1709          V0 = callback->write(callback,(int)A0,(const char *)((int)paddr),(int)A2);
1710         else
1711          sim_error("Attempt to pass pointer that does not reference simulated memory");
1712       }
1713       break;
1714
1715     case 10: /* int close(int file) */
1716       V0 = callback->close(callback,(int)A0);
1717       break;
1718
1719     case 11: /* char inbyte(void) */
1720       {
1721         char tmp;
1722         if (callback->read_stdin(callback,&tmp,sizeof(char)) != sizeof(char)) {
1723           sim_error("Invalid return from character read");
1724           V0 = (ut_reg)-1;
1725         }
1726         else
1727          V0 = (ut_reg)tmp;
1728       }
1729       break;
1730
1731     case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1732       {
1733         char tmp = (char)(A0 & 0xFF);
1734         callback->write_stdout(callback,&tmp,sizeof(char));
1735       }
1736       break;
1737
1738     case 17: /* void _exit() */
1739       sim_warning("sim_monitor(17): _exit(int reason) to be coded");
1740       sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_exited,
1741                        (unsigned int)(A0 & 0xFFFFFFFF));
1742       break;
1743
1744     case 28 : /* PMON flush_cache */
1745       break;
1746
1747     case 55: /* void get_mem_info(unsigned int *ptr) */
1748       /* in:  A0 = pointer to three word memory location */
1749       /* out: [A0 + 0] = size */
1750       /*      [A0 + 4] = instruction cache size */
1751       /*      [A0 + 8] = data cache size */
1752       {
1753         uword64 vaddr = A0;
1754         uword64 paddr, value;
1755         int cca;
1756         int failed = 0;
1757
1758         /* NOTE: We use RAW memory writes here, but since we are not
1759            gathering statistics for the monitor calls we are simulating,
1760            it is not an issue. */
1761
1762         /* Memory size */
1763         if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL)) {
1764           value = (uword64)STATE_MEM_SIZE (sd);
1765           StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1766           /* We re-do the address translations, in-case the block
1767              overlaps a memory boundary: */
1768           value = 0;
1769           vaddr += (AccessLength_WORD + 1);
1770           if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL)) {
1771             StoreMemory(cca,AccessLength_WORD,0,value,paddr,vaddr,isRAW);
1772             vaddr += (AccessLength_WORD + 1);
1773             if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL))
1774              StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1775             else
1776              failed = -1;
1777           } else
1778            failed = -1;
1779         } else
1780          failed = -1;
1781
1782         if (failed)
1783          sim_error("Invalid pointer passed into monitor call");
1784       }
1785       break;
1786
1787     case 158 : /* PMON printf */
1788       /* in:  A0 = pointer to format string */
1789       /*      A1 = optional argument 1 */
1790       /*      A2 = optional argument 2 */
1791       /*      A3 = optional argument 3 */
1792       /* out: void */
1793       /* The following is based on the PMON printf source */
1794       {
1795         uword64 paddr;
1796         int cca;
1797         /* This isn't the quickest way, since we call the host print
1798            routine for every character almost. But it does avoid
1799            having to allocate and manage a temporary string buffer. */
1800         if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) {
1801           char *s = (char *)((int)paddr);
1802           ut_reg *ap = &A1; /* 1st argument */
1803           /* TODO: Include check that we only use three arguments (A1, A2 and A3) */
1804           for (; *s;) {
1805             if (*s == '%') {
1806               char tmp[40];
1807               enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1808               int width = 0, trunc = 0, haddot = 0, longlong = 0;
1809               s++;
1810               for (; *s; s++) {
1811                 if (strchr ("dobxXulscefg%", *s))
1812                   break;
1813                 else if (*s == '-')
1814                   fmt = FMT_LJUST;
1815                 else if (*s == '0')
1816                   fmt = FMT_RJUST0;
1817                 else if (*s == '~')
1818                   fmt = FMT_CENTER;
1819                 else if (*s == '*') {
1820                   if (haddot)
1821                     trunc = (int)*ap++;
1822                   else
1823                     width = (int)*ap++;
1824                 } else if (*s >= '1' && *s <= '9') {
1825                   char *t;
1826                   unsigned int n;
1827                   for (t = s; isdigit (*s); s++);
1828                   strncpy (tmp, t, s - t);
1829                   tmp[s - t] = '\0';
1830                   n = (unsigned int)strtol(tmp,NULL,10);
1831                   if (haddot)
1832                    trunc = n;
1833                   else
1834                    width = n;
1835                   s--;
1836                 } else if (*s == '.')
1837                   haddot = 1;
1838               }
1839               if (*s == '%') {
1840                 callback->printf_filtered(callback,"%%");
1841               } else if (*s == 's') {
1842                 if ((int)*ap != 0) {
1843                   if (AddressTranslation(*ap++,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) {
1844                     char *p = (char *)((int)paddr);;
1845                     callback->printf_filtered(callback,p);
1846                   } else {
1847                     ap++;
1848                     sim_error("Attempt to pass pointer that does not reference simulated memory");
1849                   }
1850                 }
1851                 else
1852                   callback->printf_filtered(callback,"(null)");
1853               } else if (*s == 'c') {
1854                 int n = (int)*ap++;
1855                 callback->printf_filtered(callback,"%c",n);
1856               } else {
1857                 if (*s == 'l') {
1858                   if (*++s == 'l') {
1859                     longlong = 1;
1860                     ++s;
1861                   }
1862                 }
1863                 if (strchr ("dobxXu", *s)) {
1864                   word64 lv = (word64) *ap++;
1865                   if (*s == 'b')
1866                     callback->printf_filtered(callback,"<binary not supported>");
1867                   else {
1868                     sprintf(tmp,"%%%s%c",longlong ? "ll" : "",*s);
1869                     if (longlong)
1870                       callback->printf_filtered(callback,tmp,lv);
1871                     else
1872                       callback->printf_filtered(callback,tmp,(int)lv);
1873                   }
1874                 } else if (strchr ("eEfgG", *s)) {
1875 #ifdef _MSC_VER /* MSVC version 2.x can't convert from uword64 directly */
1876                   double dbl = (double)((word64)*ap++);
1877 #else
1878                   double dbl = (double)*ap++;
1879 #endif
1880                   sprintf(tmp,"%%%d.%d%c",width,trunc,*s);
1881                   callback->printf_filtered(callback,tmp,dbl);
1882                   trunc = 0;
1883                 }
1884               }
1885               s++;
1886             } else
1887              callback->printf_filtered(callback,"%c",*s++);
1888           }
1889         } else
1890          sim_error("Attempt to pass pointer that does not reference simulated memory");
1891       }
1892       break;
1893
1894     default:
1895       sim_warning("TODO: sim_monitor(%d) : PC = 0x%s",reason,pr_addr(IPC));
1896       sim_warning("(Arguments : A0 = 0x%s : A1 = 0x%s : A2 = 0x%s : A3 = 0x%s)",pr_addr(A0),pr_addr(A1),pr_addr(A2),pr_addr(A3));
1897       break;
1898   }
1899   return;
1900 }
1901
1902 /* Store a word into memory.  */
1903
1904 static void
1905 store_word (vaddr, val)
1906      uword64 vaddr;
1907      t_reg val;
1908 {
1909   uword64 paddr;
1910   int uncached;
1911
1912   if ((vaddr & 3) != 0)
1913     SignalException (AddressStore);
1914   else
1915     {
1916       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1917                               isTARGET, isREAL))
1918         {
1919           const uword64 mask = 7;
1920           uword64 memval;
1921           unsigned int byte;
1922
1923           paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1924           byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1925           memval = ((uword64) val) << (8 * byte);
1926           StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1927                        isREAL);
1928         }
1929     }
1930 }
1931
1932 /* Load a word from memory.  */
1933
1934 static t_reg
1935 load_word (vaddr)
1936      uword64 vaddr;
1937 {
1938   if ((vaddr & 3) != 0)
1939     SignalException (AddressLoad);
1940   else
1941     {
1942       uword64 paddr;
1943       int uncached;
1944
1945       if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1946                               isTARGET, isREAL))
1947         {
1948           const uword64 mask = 0x7;
1949           const unsigned int reverse = ReverseEndian ? 1 : 0;
1950           const unsigned int bigend = BigEndianCPU ? 1 : 0;
1951           uword64 memval;
1952           unsigned int byte;
1953
1954           paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1955           LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1956                                isDATA, isREAL);
1957           byte = (vaddr & mask) ^ (bigend << 2);
1958           return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
1959         }
1960     }
1961
1962   return 0;
1963 }
1964
1965 /* Simulate the mips16 entry and exit pseudo-instructions.  These
1966    would normally be handled by the reserved instruction exception
1967    code, but for ease of simulation we just handle them directly.  */
1968
1969 static void
1970 mips16_entry (insn)
1971      unsigned int insn;
1972 {
1973   int aregs, sregs, rreg;
1974
1975 #ifdef DEBUG
1976   printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1977 #endif /* DEBUG */
1978
1979   aregs = (insn & 0x700) >> 8;
1980   sregs = (insn & 0x0c0) >> 6;
1981   rreg =  (insn & 0x020) >> 5;
1982
1983   /* This should be checked by the caller.  */
1984   if (sregs == 3)
1985     abort ();
1986
1987   if (aregs < 5)
1988     {
1989       int i;
1990       t_reg tsp;
1991
1992       /* This is the entry pseudo-instruction.  */
1993
1994       for (i = 0; i < aregs; i++)
1995         store_word ((uword64) (SP + 4 * i), registers[i + 4]);
1996
1997       tsp = SP;
1998       SP -= 32;
1999
2000       if (rreg)
2001         {
2002           tsp -= 4;
2003           store_word ((uword64) tsp, RA);
2004         }
2005
2006       for (i = 0; i < sregs; i++)
2007         {
2008           tsp -= 4;
2009           store_word ((uword64) tsp, registers[16 + i]);
2010         }
2011     }
2012   else
2013     {
2014       int i;
2015       t_reg tsp;
2016
2017       /* This is the exit pseudo-instruction.  */
2018
2019       tsp = SP + 32;
2020
2021       if (rreg)
2022         {
2023           tsp -= 4;
2024           RA = load_word ((uword64) tsp);
2025         }
2026
2027       for (i = 0; i < sregs; i++)
2028         {
2029           tsp -= 4;
2030           registers[i + 16] = load_word ((uword64) tsp);
2031         }
2032
2033       SP += 32;
2034
2035       if (aregs == 5)
2036         {
2037           FGR[0] = WORD64LO (GPR[4]);
2038           fpr_state[0] = fmt_uninterpreted;
2039         }
2040       else if (aregs == 6)
2041         {
2042           FGR[0] = WORD64LO (GPR[5]);
2043           FGR[1] = WORD64LO (GPR[4]);
2044           fpr_state[0] = fmt_uninterpreted;
2045           fpr_state[1] = fmt_uninterpreted;
2046         }
2047
2048       PC = RA;
2049     }
2050 }
2051
2052 void
2053 sim_warning(char *fmt,...)
2054 {
2055   char buf[256];
2056   va_list ap;
2057
2058   va_start (ap,fmt);
2059   vsprintf (buf, fmt, ap);
2060   va_end (ap);
2061   
2062   if (logfh != NULL) {
2063     fprintf(logfh,"SIM Warning: %s\n", buf);
2064   } else {
2065     callback->printf_filtered(callback,"SIM Warning: %s\n", buf);
2066   }
2067   /* This used to call SignalException with a SimulatorFault, but that causes
2068      the simulator to exit, and that is inappropriate for a warning.  */
2069   return;
2070 }
2071
2072 void
2073 sim_error(char *fmt,...)
2074 {
2075   char buf[256];
2076   va_list ap;
2077
2078   va_start (ap,fmt);
2079   vsprintf (buf, fmt, ap);
2080   va_end (ap);
2081
2082   callback->printf_filtered(callback,"SIM Error: %s", buf);
2083   SignalException (SimulatorFault, buf);
2084   return;
2085 }
2086
2087 static unsigned int
2088 power2(value)
2089      unsigned int value;
2090 {
2091   int loop,tmp;
2092
2093   /* Round *UP* to the nearest power-of-2 if not already one */
2094   if (value != (value & ~(value - 1))) {
2095     for (tmp = value, loop = 0; (tmp != 0); loop++)
2096      tmp >>= 1;
2097     value = (1 << loop);
2098   }
2099
2100   return(value);
2101 }
2102
2103 static long
2104 getnum(value)
2105      char *value;
2106 {
2107   long num;
2108   char *end;
2109
2110   num = strtol(value,&end,10);
2111   if (end == value)
2112    callback->printf_filtered(callback,"Warning: Invalid number \"%s\" ignored, using zero\n",value);
2113   else {
2114     if (*end && ((tolower(*end) == 'k') || (tolower(*end) == 'm'))) {
2115       if (tolower(*end) == 'k')
2116        num *= (1 << 10);
2117       else
2118        num *= (1 << 20);
2119       end++;
2120     }
2121     if (*end)
2122      callback->printf_filtered(callback,"Warning: Spurious characters \"%s\" at end of number ignored\n",end);
2123   }
2124
2125   return(num);
2126 }
2127
2128 /*-- trace support ----------------------------------------------------------*/
2129
2130 /* The TRACE support is provided (if required) in the memory accessing
2131    routines. Since we are also providing the architecture specific
2132    features, the architecture simulation code can also deal with
2133    notifying the TRACE world of cache flushes, etc. Similarly we do
2134    not need to provide profiling support in the simulator engine,
2135    since we can sample in the instruction fetch control loop. By
2136    defining the TRACE manifest, we add tracing as a run-time
2137    option. */
2138
2139 #if defined(TRACE)
2140 /* Tracing by default produces "din" format (as required by
2141    dineroIII). Each line of such a trace file *MUST* have a din label
2142    and address field. The rest of the line is ignored, so comments can
2143    be included if desired. The first field is the label which must be
2144    one of the following values:
2145
2146         0       read data
2147         1       write data
2148         2       instruction fetch
2149         3       escape record (treated as unknown access type)
2150         4       escape record (causes cache flush)
2151
2152    The address field is a 32bit (lower-case) hexadecimal address
2153    value. The address should *NOT* be preceded by "0x".
2154
2155    The size of the memory transfer is not important when dealing with
2156    cache lines (as long as no more than a cache line can be
2157    transferred in a single operation :-), however more information
2158    could be given following the dineroIII requirement to allow more
2159    complete memory and cache simulators to provide better
2160    results. i.e. the University of Pisa has a cache simulator that can
2161    also take bus size and speed as (variable) inputs to calculate
2162    complete system performance (a much more useful ability when trying
2163    to construct an end product, rather than a processor). They
2164    currently have an ARM version of their tool called ChARM. */
2165
2166
2167 static
2168 void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
2169 {
2170   if (state & simTRACE) {
2171     va_list ap;
2172     fprintf(tracefh,"%d %s ; width %d ; ", 
2173                 type,
2174                 pr_addr(address),
2175                 width);
2176     va_start(ap,comment);
2177     vfprintf(tracefh,comment,ap);
2178     va_end(ap);
2179     fprintf(tracefh,"\n");
2180   }
2181   /* NOTE: Since the "din" format will only accept 32bit addresses, and
2182      we may be generating 64bit ones, we should put the hi-32bits of the
2183      address into the comment field. */
2184
2185   /* TODO: Provide a buffer for the trace lines. We can then avoid
2186      performing writes until the buffer is filled, or the file is
2187      being closed. */
2188
2189   /* NOTE: We could consider adding a comment field to the "din" file
2190      produced using type 3 markers (unknown access). This would then
2191      allow information about the program that the "din" is for, and
2192      the MIPs world that was being simulated, to be placed into the
2193      trace file. */
2194
2195   return;
2196 }
2197 #endif /* TRACE */
2198
2199 /*---------------------------------------------------------------------------*/
2200 /*-- simulator engine -------------------------------------------------------*/
2201 /*---------------------------------------------------------------------------*/
2202
2203 static void
2204 ColdReset()
2205 {
2206   /* RESET: Fixed PC address: */
2207   PC = (((uword64)0xFFFFFFFF<<32) | 0xBFC00000);
2208   /* The reset vector address is in the unmapped, uncached memory space. */
2209
2210   SR &= ~(status_SR | status_TS | status_RP);
2211   SR |= (status_ERL | status_BEV);
2212
2213 #if defined(HASFPU) && (GPRLEN == (64))
2214   /* Cheat and allow access to the complete register set immediately: */
2215   SR |= status_FR; /* 64bit registers */
2216 #endif /* HASFPU and 64bit FP registers */
2217
2218   /* Ensure that any instructions with pending register updates are
2219      cleared: */
2220   {
2221     int loop;
2222     for (loop = 0; (loop < PSLOTS); loop++)
2223      pending_slot_reg[loop] = (LAST_EMBED_REGNUM + 1);
2224     pending_in = pending_out = pending_total = 0;
2225   }
2226
2227 #if defined(HASFPU)
2228   /* Initialise the FPU registers to the unknown state */
2229   {
2230     int rn;
2231     for (rn = 0; (rn < 32); rn++)
2232      fpr_state[rn] = fmt_uninterpreted;
2233   }
2234 #endif /* HASFPU */
2235
2236   return;
2237 }
2238
2239 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2240 /* Translate a virtual address to a physical address and cache
2241    coherence algorithm describing the mechanism used to resolve the
2242    memory reference. Given the virtual address vAddr, and whether the
2243    reference is to Instructions ot Data (IorD), find the corresponding
2244    physical address (pAddr) and the cache coherence algorithm (CCA)
2245    used to resolve the reference. If the virtual address is in one of
2246    the unmapped address spaces the physical address and the CCA are
2247    determined directly by the virtual address. If the virtual address
2248    is in one of the mapped address spaces then the TLB is used to
2249    determine the physical address and access type; if the required
2250    translation is not present in the TLB or the desired access is not
2251    permitted the function fails and an exception is taken.
2252
2253    NOTE: This function is extended to return an exception state. This,
2254    along with the exception generation is used to notify whether a
2255    valid address translation occured */
2256
2257 static int
2258 AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw)
2259      uword64 vAddr;
2260      int IorD;
2261      int LorS;
2262      uword64 *pAddr;
2263      int *CCA;
2264      int host;
2265      int raw;
2266 {
2267   SIM_DESC sd = &simulator;
2268   int res = -1; /* TRUE : Assume good return */
2269
2270 #ifdef DEBUG
2271   callback->printf_filtered(callback,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
2272 #endif
2273
2274   /* Check that the address is valid for this memory model */
2275
2276   /* For a simple (flat) memory model, we simply pass virtual
2277      addressess through (mostly) unchanged. */
2278   vAddr &= 0xFFFFFFFF;
2279
2280   /* Treat the kernel memory spaces identically for the moment: */
2281   if ((STATE_MEM_BASE (sd) == K1BASE) && (vAddr >= K0BASE) && (vAddr < (K0BASE + K0SIZE)))
2282     vAddr += (K1BASE - K0BASE);
2283
2284   /* Also assume that the K1BASE memory wraps. This is required to
2285      allow the PMON run-time __sizemem() routine to function (without
2286      having to provide exception simulation). NOTE: A kludge to work
2287      around the fact that the monitor memory is currently held in the
2288      K1BASE space. */
2289   if (((vAddr < monitor_base) || (vAddr >= (monitor_base + monitor_size))) && (vAddr >= K1BASE && vAddr < (K1BASE + K1SIZE)))
2290     vAddr = (K1BASE | (vAddr & (STATE_MEM_SIZE (sd) - 1)));
2291
2292   *pAddr = vAddr; /* default for isTARGET */
2293   *CCA = Uncached; /* not used for isHOST */
2294
2295   /* NOTE: This is a duplicate of the code that appears in the
2296      LoadMemory and StoreMemory functions. They should be merged into
2297      a single function (that can be in-lined if required). */
2298   if ((vAddr >= STATE_MEM_BASE (sd)) && (vAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2299     if (host)
2300      *pAddr = (int)&STATE_MEMORY (sd)[((unsigned int)(vAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1))];
2301   } else if ((vAddr >= monitor_base) && (vAddr < (monitor_base + monitor_size))) {
2302     if (host)
2303      *pAddr = (int)&monitor[((unsigned int)(vAddr - monitor_base) & (monitor_size - 1))];
2304   } else {
2305 #ifdef DEBUG
2306     sim_warning("Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC));
2307 #endif /* DEBUG */
2308     res = 0; /* AddressTranslation has failed */
2309     *pAddr = (SIM_ADDR)-1;
2310     if (!raw) /* only generate exceptions on real memory transfers */
2311      SignalException((LorS == isSTORE) ? AddressStore : AddressLoad);
2312 #ifdef DEBUG
2313     else
2314      /* This is a normal occurance during gdb operation, for instance trying
2315         to print parameters at function start before they have been setup,
2316         and hence we should not print a warning except when debugging the
2317         simulator.  */
2318      sim_warning("AddressTranslation for %s %s from 0x%s failed",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
2319 #endif
2320   }
2321
2322   return(res);
2323 }
2324
2325 /* Description from page A-23 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2326 /* Prefetch data from memory. Prefetch is an advisory instruction for
2327    which an implementation specific action is taken. The action taken
2328    may increase performance, but must not change the meaning of the
2329    program, or alter architecturally-visible state. */
2330
2331 static void UNUSED
2332 Prefetch(CCA,pAddr,vAddr,DATA,hint)
2333      int CCA;
2334      uword64 pAddr;
2335      uword64 vAddr;
2336      int DATA;
2337      int hint;
2338 {
2339 #ifdef DEBUG
2340   callback->printf_filtered(callback,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
2341 #endif /* DEBUG */
2342
2343   /* For our simple memory model we do nothing */
2344   return;
2345 }
2346
2347 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2348 /* Load a value from memory. Use the cache and main memory as
2349    specified in the Cache Coherence Algorithm (CCA) and the sort of
2350    access (IorD) to find the contents of AccessLength memory bytes
2351    starting at physical location pAddr. The data is returned in the
2352    fixed width naturally-aligned memory element (MemElem). The
2353    low-order two (or three) bits of the address and the AccessLength
2354    indicate which of the bytes within MemElem needs to be given to the
2355    processor. If the memory access type of the reference is uncached
2356    then only the referenced bytes are read from memory and valid
2357    within the memory element. If the access type is cached, and the
2358    data is not present in cache, an implementation specific size and
2359    alignment block of memory is read and loaded into the cache to
2360    satisfy a load reference. At a minimum, the block is the entire
2361    memory element. */
2362 static void
2363 LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
2364      uword64* memvalp;
2365      uword64* memval1p;
2366      int CCA;
2367      int AccessLength;
2368      uword64 pAddr;
2369      uword64 vAddr;
2370      int IorD;
2371      int raw;
2372 {
2373   SIM_DESC sd = &simulator;
2374   uword64 value = 0;
2375   uword64 value1 = 0;
2376
2377 #ifdef DEBUG
2378   if (STATE_MEMORY (sd) == NULL)
2379    callback->printf_filtered(callback,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(raw ? "isRAW" : "isREAL"));
2380 #endif /* DEBUG */
2381
2382 #if defined(WARN_MEM)
2383   if (CCA != uncached)
2384    sim_warning("LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
2385
2386   if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) {
2387     /* In reality this should be a Bus Error */
2388     sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
2389   }
2390 #endif /* WARN_MEM */
2391
2392   /* Decide which physical memory locations are being dealt with. At
2393      this point we should be able to split the pAddr bits into the
2394      relevant address map being simulated. If the "raw" variable is
2395      set, the memory read being performed should *NOT* update any I/O
2396      state or affect the CPU state. This also includes avoiding
2397      affecting statistics gathering. */
2398
2399   /* If instruction fetch then we need to check that the two lo-order
2400      bits are zero, otherwise raise a InstructionFetch exception: */
2401   if ((IorD == isINSTRUCTION)
2402       && ((pAddr & 0x3) != 0)
2403       && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
2404    SignalException(InstructionFetch);
2405   else {
2406     unsigned int index = 0;
2407     unsigned char *mem = NULL;
2408
2409 #if defined(TRACE)
2410     if (!raw)
2411      dotrace(tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
2412 #endif /* TRACE */
2413
2414     /* NOTE: Quicker methods of decoding the address space can be used
2415        when a real memory map is being simulated (i.e. using hi-order
2416        address bits to select device). */
2417     if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2418       index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1));
2419       mem = STATE_MEMORY (sd);
2420     } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) {
2421       index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1));
2422       mem = monitor;
2423     }
2424     if (mem == NULL)
2425      sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
2426     else {
2427       /* If we obtained the endianness of the host, and it is the same
2428          as the target memory system we can optimise the memory
2429          accesses. However, without that information we must perform
2430          slow transfer, and hope that the compiler optimisation will
2431          merge successive loads. */
2432
2433       /* In reality we should always be loading a doubleword value (or
2434          word value in 32bit memory worlds). The external code then
2435          extracts the required bytes. However, to keep performance
2436          high we only load the required bytes into the relevant
2437          slots. */
2438       if (BigEndianMem)
2439        switch (AccessLength) { /* big-endian memory */
2440          case AccessLength_QUADWORD :
2441           value1 |= ((uword64)mem[index++] << 56);
2442          case 14:   /* AccessLength is one less than datalen */
2443           value1 |= ((uword64)mem[index++] << 48);
2444          case 13:
2445           value1 |= ((uword64)mem[index++] << 40);
2446          case 12:
2447           value1 |= ((uword64)mem[index++] << 32);
2448          case 11:
2449           value1 |= ((unsigned int)mem[index++] << 24);
2450          case 10:
2451           value1 |= ((unsigned int)mem[index++] << 16);
2452          case 9:
2453           value1 |= ((unsigned int)mem[index++] << 8);
2454          case 8:
2455           value1 |= mem[index];
2456
2457          case AccessLength_DOUBLEWORD :
2458           value |= ((uword64)mem[index++] << 56);
2459          case AccessLength_SEPTIBYTE :
2460           value |= ((uword64)mem[index++] << 48);
2461          case AccessLength_SEXTIBYTE :
2462           value |= ((uword64)mem[index++] << 40);
2463          case AccessLength_QUINTIBYTE :
2464           value |= ((uword64)mem[index++] << 32);
2465          case AccessLength_WORD :
2466           value |= ((unsigned int)mem[index++] << 24);
2467          case AccessLength_TRIPLEBYTE :
2468           value |= ((unsigned int)mem[index++] << 16);
2469          case AccessLength_HALFWORD :
2470           value |= ((unsigned int)mem[index++] << 8);
2471          case AccessLength_BYTE :
2472           value |= mem[index];
2473           break;
2474        }
2475       else {
2476         index += (AccessLength + 1);
2477         switch (AccessLength) { /* little-endian memory */
2478           case AccessLength_QUADWORD :
2479            value1 |= ((uword64)mem[--index] << 56);
2480          case 14:   /* AccessLength is one less than datalen */
2481            value1 |= ((uword64)mem[--index] << 48);
2482          case 13:
2483            value1 |= ((uword64)mem[--index] << 40);
2484          case 12:
2485            value1 |= ((uword64)mem[--index] << 32);
2486          case 11:
2487            value1 |= ((uword64)mem[--index] << 24);
2488          case 10:
2489            value1 |= ((uword64)mem[--index] << 16);
2490          case 9:
2491            value1 |= ((uword64)mem[--index] << 8);
2492          case 8:
2493            value1 |= ((uword64)mem[--index] << 0);
2494
2495           case AccessLength_DOUBLEWORD :
2496            value |= ((uword64)mem[--index] << 56);
2497           case AccessLength_SEPTIBYTE :
2498            value |= ((uword64)mem[--index] << 48);
2499           case AccessLength_SEXTIBYTE :
2500            value |= ((uword64)mem[--index] << 40);
2501           case AccessLength_QUINTIBYTE :
2502            value |= ((uword64)mem[--index] << 32);
2503           case AccessLength_WORD :
2504            value |= ((uword64)mem[--index] << 24);
2505           case AccessLength_TRIPLEBYTE :
2506            value |= ((uword64)mem[--index] << 16);
2507           case AccessLength_HALFWORD :
2508            value |= ((uword64)mem[--index] << 8);
2509           case AccessLength_BYTE :
2510            value |= ((uword64)mem[--index] << 0);
2511            break;
2512         }
2513       }
2514
2515 #ifdef DEBUG
2516       printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
2517              (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
2518 #endif /* DEBUG */
2519
2520       /* TODO: We could try and avoid the shifts when dealing with raw
2521          memory accesses. This would mean updating the LoadMemory and
2522          StoreMemory routines to avoid shifting the data before
2523          returning or using it. */
2524       if (AccessLength <= AccessLength_DOUBLEWORD) {
2525         if (!raw) { /* do nothing for raw accessess */
2526           if (BigEndianMem)
2527             value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
2528           else /* little-endian only needs to be shifted up to the correct byte offset */
2529             value <<= ((pAddr & LOADDRMASK) * 8);
2530         }
2531       }
2532
2533 #ifdef DEBUG
2534       printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
2535              pr_uword64(value1),pr_uword64(value));
2536 #endif /* DEBUG */
2537     }
2538   }
2539
2540 *memvalp = value;
2541 if (memval1p) *memval1p = value1;
2542 }
2543
2544
2545 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
2546    (revision 3.1) */
2547 /* Store a value to memory. The specified data is stored into the
2548    physical location pAddr using the memory hierarchy (data caches and
2549    main memory) as specified by the Cache Coherence Algorithm
2550    (CCA). The MemElem contains the data for an aligned, fixed-width
2551    memory element (word for 32-bit processors, doubleword for 64-bit
2552    processors), though only the bytes that will actually be stored to
2553    memory need to be valid. The low-order two (or three) bits of pAddr
2554    and the AccessLength field indicates which of the bytes within the
2555    MemElem data should actually be stored; only these bytes in memory
2556    will be changed. */
2557
2558 static void
2559 StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
2560      int CCA;
2561      int AccessLength;
2562      uword64 MemElem;
2563      uword64 MemElem1;   /* High order 64 bits */
2564      uword64 pAddr;
2565      uword64 vAddr;
2566      int raw;
2567 {
2568   SIM_DESC sd = &simulator;
2569 #ifdef DEBUG
2570   callback->printf_filtered(callback,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s,%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr),(raw ? "isRAW" : "isREAL"));
2571 #endif /* DEBUG */
2572
2573 #if defined(WARN_MEM)
2574   if (CCA != uncached)
2575    sim_warning("StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
2576  
2577   if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
2578    sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
2579 #endif /* WARN_MEM */
2580
2581 #if defined(TRACE)
2582   if (!raw)
2583    dotrace(tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
2584 #endif /* TRACE */
2585
2586   /* See the comments in the LoadMemory routine about optimising
2587      memory accesses. Also if we wanted to make the simulator smaller,
2588      we could merge a lot of this code with the LoadMemory
2589      routine. However, this would slow the simulator down with
2590      run-time conditionals. */
2591   {
2592     unsigned int index = 0;
2593     unsigned char *mem = NULL;
2594
2595     if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2596       index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1));
2597       mem = STATE_MEMORY (sd);
2598     } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) {
2599       index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1));
2600       mem = monitor;
2601     }
2602
2603     if (mem == NULL)
2604      sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
2605     else {
2606       int shift = 0;
2607
2608 #ifdef DEBUG
2609       printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
2610 #endif /* DEBUG */
2611
2612       if (AccessLength <= AccessLength_DOUBLEWORD) {
2613         if (BigEndianMem) {
2614           if (raw)
2615             shift = ((7 - AccessLength) * 8);
2616           else /* real memory access */
2617             shift = ((pAddr & LOADDRMASK) * 8);
2618           MemElem <<= shift;
2619         } else {
2620           /* no need to shift raw little-endian data */
2621           if (!raw)
2622             MemElem >>= ((pAddr & LOADDRMASK) * 8);
2623         }
2624       }
2625
2626 #ifdef DEBUG
2627       printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
2628 #endif /* DEBUG */
2629
2630       if (BigEndianMem) {
2631         switch (AccessLength) { /* big-endian memory */
2632           case AccessLength_QUADWORD :
2633            mem[index++] = (unsigned char)(MemElem1 >> 56);
2634            MemElem1 <<= 8;
2635           case 14 :
2636            mem[index++] = (unsigned char)(MemElem1 >> 56);
2637            MemElem1 <<= 8;
2638           case 13 :
2639            mem[index++] = (unsigned char)(MemElem1 >> 56);
2640            MemElem1 <<= 8;
2641           case 12 :
2642            mem[index++] = (unsigned char)(MemElem1 >> 56);
2643            MemElem1 <<= 8;
2644           case 11 :
2645            mem[index++] = (unsigned char)(MemElem1 >> 56);
2646            MemElem1 <<= 8;
2647           case 10 :
2648            mem[index++] = (unsigned char)(MemElem1 >> 56);
2649            MemElem1 <<= 8;
2650           case 9 :
2651            mem[index++] = (unsigned char)(MemElem1 >> 56);
2652            MemElem1 <<= 8;
2653           case 8 :
2654            mem[index++] = (unsigned char)(MemElem1 >> 56);
2655
2656           case AccessLength_DOUBLEWORD :
2657            mem[index++] = (unsigned char)(MemElem >> 56);
2658            MemElem <<= 8;
2659           case AccessLength_SEPTIBYTE :
2660            mem[index++] = (unsigned char)(MemElem >> 56);
2661            MemElem <<= 8;
2662           case AccessLength_SEXTIBYTE :
2663            mem[index++] = (unsigned char)(MemElem >> 56);
2664            MemElem <<= 8;
2665           case AccessLength_QUINTIBYTE :
2666            mem[index++] = (unsigned char)(MemElem >> 56);
2667            MemElem <<= 8;
2668           case AccessLength_WORD :
2669            mem[index++] = (unsigned char)(MemElem >> 56);
2670            MemElem <<= 8;
2671           case AccessLength_TRIPLEBYTE :
2672            mem[index++] = (unsigned char)(MemElem >> 56);
2673            MemElem <<= 8;
2674           case AccessLength_HALFWORD :
2675            mem[index++] = (unsigned char)(MemElem >> 56);
2676            MemElem <<= 8;
2677           case AccessLength_BYTE :
2678            mem[index++] = (unsigned char)(MemElem >> 56);
2679            break;
2680         }
2681       } else {
2682         index += (AccessLength + 1);
2683         switch (AccessLength) { /* little-endian memory */
2684           case AccessLength_QUADWORD :
2685            mem[--index] = (unsigned char)(MemElem1 >> 56);
2686           case 14 :
2687            mem[--index] = (unsigned char)(MemElem1 >> 48);
2688           case 13 :
2689            mem[--index] = (unsigned char)(MemElem1 >> 40);
2690           case 12 :
2691            mem[--index] = (unsigned char)(MemElem1 >> 32);
2692           case 11 :
2693            mem[--index] = (unsigned char)(MemElem1 >> 24);
2694           case 10 :
2695            mem[--index] = (unsigned char)(MemElem1 >> 16);
2696           case 9 :
2697            mem[--index] = (unsigned char)(MemElem1 >> 8);
2698           case 8 :
2699            mem[--index] = (unsigned char)(MemElem1 >> 0);
2700
2701           case AccessLength_DOUBLEWORD :
2702            mem[--index] = (unsigned char)(MemElem >> 56);
2703           case AccessLength_SEPTIBYTE :
2704            mem[--index] = (unsigned char)(MemElem >> 48);
2705           case AccessLength_SEXTIBYTE :
2706            mem[--index] = (unsigned char)(MemElem >> 40);
2707           case AccessLength_QUINTIBYTE :
2708            mem[--index] = (unsigned char)(MemElem >> 32);
2709           case AccessLength_WORD :
2710            mem[--index] = (unsigned char)(MemElem >> 24);
2711           case AccessLength_TRIPLEBYTE :
2712            mem[--index] = (unsigned char)(MemElem >> 16);
2713           case AccessLength_HALFWORD :
2714            mem[--index] = (unsigned char)(MemElem >> 8);
2715           case AccessLength_BYTE :
2716            mem[--index] = (unsigned char)(MemElem >> 0);
2717            break;
2718         }
2719       }
2720     }
2721   }
2722
2723   return;
2724 }
2725
2726
2727 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2728 /* Order loads and stores to synchronise shared memory. Perform the
2729    action necessary to make the effects of groups of synchronizable
2730    loads and stores indicated by stype occur in the same order for all
2731    processors. */
2732 static void
2733 SyncOperation(stype)
2734      int stype;
2735 {
2736 #ifdef DEBUG
2737   callback->printf_filtered(callback,"SyncOperation(%d) : TODO\n",stype);
2738 #endif /* DEBUG */
2739   return;
2740 }
2741
2742 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2743 /* Signal an exception condition. This will result in an exception
2744    that aborts the instruction. The instruction operation pseudocode
2745    will never see a return from this function call. */
2746
2747 static void
2748 SignalException (int exception,...)
2749 {
2750   int vector;
2751   SIM_DESC sd = &simulator;
2752   /* Ensure that any active atomic read/modify/write operation will fail: */
2753   LLBIT = 0;
2754
2755   switch (exception) {
2756     /* TODO: For testing purposes I have been ignoring TRAPs. In
2757        reality we should either simulate them, or allow the user to
2758        ignore them at run-time. */
2759     case Trap :
2760      sim_warning("Ignoring instruction TRAP (PC 0x%s)",pr_addr(IPC));
2761      break;
2762
2763     case ReservedInstruction :
2764      {
2765        va_list ap;
2766        unsigned int instruction;
2767        va_start(ap,exception);
2768        instruction = va_arg(ap,unsigned int);
2769        va_end(ap);
2770        /* Provide simple monitor support using ReservedInstruction
2771           exceptions. The following code simulates the fixed vector
2772           entry points into the IDT monitor by causing a simulator
2773           trap, performing the monitor operation, and returning to
2774           the address held in the $ra register (standard PCS return
2775           address). This means we only need to pre-load the vector
2776           space with suitable instruction values. For systems were
2777           actual trap instructions are used, we would not need to
2778           perform this magic. */
2779        if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) {
2780          sim_monitor( ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
2781          PC = RA; /* simulate the return from the vector entry */
2782          /* NOTE: This assumes that a branch-and-link style
2783             instruction was used to enter the vector (which is the
2784             case with the current IDT monitor). */
2785          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
2786        }
2787        /* Look for the mips16 entry and exit instructions, and
2788           simulate a handler for them.  */
2789        else if ((IPC & 1) != 0
2790                 && (instruction & 0xf81f) == 0xe809
2791                 && (instruction & 0x0c0) != 0x0c0) {
2792          mips16_entry (instruction);
2793          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
2794        } /* else fall through to normal exception processing */
2795        sim_warning("ReservedInstruction 0x%08X at IPC = 0x%s",instruction,pr_addr(IPC));
2796      }
2797
2798     default:
2799 #ifdef DEBUG
2800      if (exception != BreakPoint)
2801       callback->printf_filtered(callback,"DBG: SignalException(%d) IPC = 0x%s\n",exception,pr_addr(IPC));
2802 #endif /* DEBUG */
2803      /* Store exception code into current exception id variable (used
2804         by exit code): */
2805
2806      /* TODO: If not simulating exceptions then stop the simulator
2807         execution. At the moment we always stop the simulation. */
2808      /* state |= (simSTOP | simEXCEPTION); */
2809
2810      /* Keep a copy of the current A0 in-case this is the program exit
2811         breakpoint:  */
2812      if (exception == BreakPoint) {
2813        va_list ap;
2814        unsigned int instruction;
2815        va_start(ap,exception);
2816        instruction = va_arg(ap,unsigned int);
2817        va_end(ap);
2818        /* Check for our special terminating BREAK: */
2819        if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
2820          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2821                           sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
2822        }
2823      }
2824
2825      /* See figure 5-17 for an outline of the code below */
2826      if (! (SR & status_EXL))
2827        {
2828          CAUSE = (exception << 2);
2829          if (state & simDELAYSLOT)
2830            {
2831              state &= ~simDELAYSLOT;
2832              CAUSE |= cause_BD;
2833              EPC = (IPC - 4); /* reference the branch instruction */
2834            }
2835          else
2836            EPC = IPC;
2837          /* FIXME: TLB et.al. */
2838          vector = 0x180;
2839        }
2840      else
2841        {
2842          CAUSE = 0;
2843          vector = 0x180;
2844        }
2845      SR |= status_EXL;
2846      /* Store exception code into current exception id variable (used
2847         by exit code): */
2848      if (SR & status_BEV)
2849        PC = (signed)0xBFC00200 + 0x180;
2850      else
2851        PC = (signed)0x80000000 + 0x180;
2852
2853      switch ((CAUSE >> 2) & 0x1F)
2854        {
2855        case Interrupt:
2856          /* Interrupts arrive during event processing, no need to
2857             restart */
2858          return;
2859          
2860        case TLBModification:
2861        case TLBLoad:
2862        case TLBStore:
2863        case AddressLoad:
2864        case AddressStore:
2865        case InstructionFetch:
2866        case DataReference:
2867          /* The following is so that the simulator will continue from the
2868             exception address on breakpoint operations. */
2869          PC = EPC;
2870          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2871                           sim_stopped, SIGBUS);
2872
2873        case ReservedInstruction:
2874        case CoProcessorUnusable:
2875          PC = EPC;
2876          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2877                           sim_stopped, SIGILL);
2878
2879        case IntegerOverflow:
2880        case FPE:
2881          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2882                           sim_stopped, SIGFPE);
2883
2884        case Trap:
2885        case Watch:
2886        case SystemCall:
2887        case BreakPoint:
2888          PC = EPC;
2889          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2890                           sim_stopped, SIGTRAP);
2891
2892        default : /* Unknown internal exception */
2893          PC = EPC;
2894          sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2895                           sim_stopped, SIGQUIT);
2896
2897        }
2898
2899     case SimulatorFault:
2900      {
2901        va_list ap;
2902        char *msg;
2903        va_start(ap,exception);
2904        msg = va_arg(ap,char *);
2905        va_end(ap);
2906        sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
2907                          "FATAL: Simulator error \"%s\"\n",msg);
2908      }
2909    }
2910
2911   return;
2912 }
2913
2914 #if defined(WARN_RESULT)
2915 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2916 /* This function indicates that the result of the operation is
2917    undefined. However, this should not affect the instruction
2918    stream. All that is meant to happen is that the destination
2919    register is set to an undefined result. To keep the simulator
2920    simple, we just don't bother updating the destination register, so
2921    the overall result will be undefined. If desired we can stop the
2922    simulator by raising a pseudo-exception. */
2923 static void
2924 UndefinedResult()
2925 {
2926   sim_warning("UndefinedResult: IPC = 0x%s",pr_addr(IPC));
2927 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2928   state |= simSTOP;
2929 #endif
2930   return;
2931 }
2932 #endif /* WARN_RESULT */
2933
2934 static void UNUSED
2935 CacheOp(op,pAddr,vAddr,instruction)
2936      int op;
2937      uword64 pAddr;
2938      uword64 vAddr;
2939      unsigned int instruction;
2940 {
2941 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2942   static int icache_warning = 1;
2943   static int dcache_warning = 1;
2944 #else
2945   static int icache_warning = 0;
2946   static int dcache_warning = 0;
2947 #endif
2948
2949   /* If CP0 is not useable (User or Supervisor mode) and the CP0
2950      enable bit in the Status Register is clear - a coprocessor
2951      unusable exception is taken. */
2952 #if 0
2953   callback->printf_filtered(callback,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(IPC));
2954 #endif
2955
2956   switch (op & 0x3) {
2957     case 0: /* instruction cache */
2958       switch (op >> 2) {
2959         case 0: /* Index Invalidate */
2960         case 1: /* Index Load Tag */
2961         case 2: /* Index Store Tag */
2962         case 4: /* Hit Invalidate */
2963         case 5: /* Fill */
2964         case 6: /* Hit Writeback */
2965           if (!icache_warning)
2966             {
2967               sim_warning("Instruction CACHE operation %d to be coded",(op >> 2));
2968               icache_warning = 1;
2969             }
2970           break;
2971
2972         default:
2973           SignalException(ReservedInstruction,instruction);
2974           break;
2975       }
2976       break;
2977
2978     case 1: /* data cache */
2979       switch (op >> 2) {
2980         case 0: /* Index Writeback Invalidate */
2981         case 1: /* Index Load Tag */
2982         case 2: /* Index Store Tag */
2983         case 3: /* Create Dirty */
2984         case 4: /* Hit Invalidate */
2985         case 5: /* Hit Writeback Invalidate */
2986         case 6: /* Hit Writeback */ 
2987           if (!dcache_warning)
2988             {
2989               sim_warning("Data CACHE operation %d to be coded",(op >> 2));
2990               dcache_warning = 1;
2991             }
2992           break;
2993
2994         default:
2995           SignalException(ReservedInstruction,instruction);
2996           break;
2997       }
2998       break;
2999
3000     default: /* unrecognised cache ID */
3001       SignalException(ReservedInstruction,instruction);
3002       break;
3003   }
3004
3005   return;
3006 }
3007
3008 /*-- FPU support routines ---------------------------------------------------*/
3009
3010 #if defined(HASFPU) /* Only needed when building FPU aware simulators */
3011
3012 #if 1
3013 #define SizeFGR() (GPRLEN)
3014 #else
3015 /* They depend on the CPU being simulated */
3016 #define SizeFGR() ((PROCESSOR_64BIT && ((SR & status_FR) == 1)) ? 64 : 32)
3017 #endif
3018
3019 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
3020    formats conform to ANSI/IEEE Std 754-1985. */
3021 /* SINGLE precision floating:
3022  *    seeeeeeeefffffffffffffffffffffff
3023  *      s =  1bit  = sign
3024  *      e =  8bits = exponent
3025  *      f = 23bits = fraction
3026  */
3027 /* SINGLE precision fixed:
3028  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
3029  *      s =  1bit  = sign
3030  *      i = 31bits = integer
3031  */
3032 /* DOUBLE precision floating:
3033  *    seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
3034  *      s =  1bit  = sign
3035  *      e = 11bits = exponent
3036  *      f = 52bits = fraction
3037  */
3038 /* DOUBLE precision fixed:
3039  *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
3040  *      s =  1bit  = sign
3041  *      i = 63bits = integer
3042  */
3043
3044 /* Extract sign-bit: */
3045 #define FP_S_s(v)    (((v) & ((unsigned)1 << 31)) ? 1 : 0)
3046 #define FP_D_s(v)    (((v) & ((uword64)1 << 63)) ? 1 : 0)
3047 /* Extract biased exponent: */
3048 #define FP_S_be(v)   (((v) >> 23) & 0xFF)
3049 #define FP_D_be(v)   (((v) >> 52) & 0x7FF)
3050 /* Extract unbiased Exponent: */
3051 #define FP_S_e(v)    (FP_S_be(v) - 0x7F)
3052 #define FP_D_e(v)    (FP_D_be(v) - 0x3FF)
3053 /* Extract complete fraction field: */
3054 #define FP_S_f(v)    ((v) & ~((unsigned)0x1FF << 23))
3055 #define FP_D_f(v)    ((v) & ~((uword64)0xFFF << 52))
3056 /* Extract numbered fraction bit: */
3057 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
3058 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
3059
3060 /* Explicit QNaN values used when value required: */
3061 #define FPQNaN_SINGLE   (0x7FBFFFFF)
3062 #define FPQNaN_WORD     (0x7FFFFFFF)
3063 #define FPQNaN_DOUBLE   (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
3064 #define FPQNaN_LONG     (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
3065
3066 /* Explicit Infinity values used when required: */
3067 #define FPINF_SINGLE    (0x7F800000)
3068 #define FPINF_DOUBLE    (((uword64)0x7FF00000 << 32) | 0x00000000)
3069
3070 #if 1 /* def DEBUG */
3071 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
3072 #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>" : "<format error>"))))))
3073 #endif /* DEBUG */
3074
3075 static uword64
3076 ValueFPR(fpr,fmt)
3077          int fpr;
3078          FP_formats fmt;
3079 {
3080   uword64 value = 0;
3081   int err = 0;
3082
3083   /* Treat unused register values, as fixed-point 64bit values: */
3084   if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
3085 #if 1
3086    /* If request to read data as "uninterpreted", then use the current
3087       encoding: */
3088    fmt = fpr_state[fpr];
3089 #else
3090    fmt = fmt_long;
3091 #endif
3092
3093   /* For values not yet accessed, set to the desired format: */
3094   if (fpr_state[fpr] == fmt_uninterpreted) {
3095     fpr_state[fpr] = fmt;
3096 #ifdef DEBUG
3097     printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
3098 #endif /* DEBUG */
3099   }
3100   if (fmt != fpr_state[fpr]) {
3101     sim_warning("FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)",fpr,DOFMT(fpr_state[fpr]),DOFMT(fmt),pr_addr(IPC));
3102     fpr_state[fpr] = fmt_unknown;
3103   }
3104
3105   if (fpr_state[fpr] == fmt_unknown) {
3106    /* Set QNaN value: */
3107    switch (fmt) {
3108     case fmt_single:
3109      value = FPQNaN_SINGLE;
3110      break;
3111
3112     case fmt_double:
3113      value = FPQNaN_DOUBLE;
3114      break;
3115
3116     case fmt_word:
3117      value = FPQNaN_WORD;
3118      break;
3119
3120     case fmt_long:
3121      value = FPQNaN_LONG;
3122      break;
3123
3124     default:
3125      err = -1;
3126      break;
3127    }
3128   } else if (SizeFGR() == 64) {
3129     switch (fmt) {
3130      case fmt_single:
3131      case fmt_word:
3132       value = (FGR[fpr] & 0xFFFFFFFF);
3133       break;
3134
3135      case fmt_uninterpreted:
3136      case fmt_double:
3137      case fmt_long:
3138       value = FGR[fpr];
3139       break;
3140
3141      default :
3142       err = -1;
3143       break;
3144     }
3145   } else {
3146     switch (fmt) {
3147      case fmt_single:
3148      case fmt_word:
3149       value = (FGR[fpr] & 0xFFFFFFFF);
3150       break;
3151
3152      case fmt_uninterpreted:
3153      case fmt_double:
3154      case fmt_long:
3155       if ((fpr & 1) == 0) { /* even registers only */
3156         value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
3157       } else {
3158         SignalException (ReservedInstruction, 0);
3159       }
3160       break;
3161
3162      default :
3163       err = -1;
3164       break;
3165     }
3166   }
3167
3168   if (err)
3169    SignalException(SimulatorFault,"Unrecognised FP format in ValueFPR()");
3170
3171 #ifdef DEBUG
3172   printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(IPC),SizeFGR());
3173 #endif /* DEBUG */
3174
3175   return(value);
3176 }
3177
3178 static void
3179 StoreFPR(fpr,fmt,value)
3180      int fpr;
3181      FP_formats fmt;
3182      uword64 value;
3183 {
3184   int err = 0;
3185
3186 #ifdef DEBUG
3187   printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(IPC),SizeFGR());
3188 #endif /* DEBUG */
3189
3190   if (SizeFGR() == 64) {
3191     switch (fmt) {
3192       case fmt_single :
3193       case fmt_word :
3194        FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
3195        fpr_state[fpr] = fmt;
3196        break;
3197
3198       case fmt_uninterpreted:
3199       case fmt_double :
3200       case fmt_long :
3201        FGR[fpr] = value;
3202        fpr_state[fpr] = fmt;
3203        break;
3204
3205       default :
3206        fpr_state[fpr] = fmt_unknown;
3207        err = -1;
3208        break;
3209     }
3210   } else {
3211     switch (fmt) {
3212       case fmt_single :
3213       case fmt_word :
3214        FGR[fpr] = (value & 0xFFFFFFFF);
3215        fpr_state[fpr] = fmt;
3216        break;
3217
3218       case fmt_uninterpreted:
3219       case fmt_double :
3220       case fmt_long :
3221         if ((fpr & 1) == 0) { /* even register number only */
3222           FGR[fpr+1] = (value >> 32);
3223           FGR[fpr] = (value & 0xFFFFFFFF);
3224           fpr_state[fpr + 1] = fmt;
3225           fpr_state[fpr] = fmt;
3226         } else {
3227           fpr_state[fpr] = fmt_unknown;
3228           fpr_state[fpr + 1] = fmt_unknown;
3229           SignalException (ReservedInstruction, 0);
3230         }
3231        break;
3232
3233       default :
3234        fpr_state[fpr] = fmt_unknown;
3235        err = -1;
3236        break;
3237     }
3238   }
3239 #if defined(WARN_RESULT)
3240   else
3241     UndefinedResult();
3242 #endif /* WARN_RESULT */
3243
3244   if (err)
3245    SignalException(SimulatorFault,"Unrecognised FP format in StoreFPR()");
3246
3247 #ifdef DEBUG
3248   printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
3249 #endif /* DEBUG */
3250
3251   return;
3252 }
3253
3254 static int
3255 NaN(op,fmt)
3256      uword64 op;
3257      FP_formats fmt; 
3258 {
3259   int boolean = 0;
3260
3261   /* Check if (((E - bias) == (E_max + 1)) && (fraction != 0)). We
3262      know that the exponent field is biased... we we cheat and avoid
3263      removing the bias value. */
3264   switch (fmt) {
3265    case fmt_single:
3266     boolean = ((FP_S_be(op) == 0xFF) && (FP_S_f(op) != 0));
3267     /* We could use "FP_S_fb(1,op)" to ascertain whether we are
3268        dealing with a SNaN or QNaN */
3269     break;
3270    case fmt_double:
3271     boolean = ((FP_D_be(op) == 0x7FF) && (FP_D_f(op) != 0));
3272     /* We could use "FP_S_fb(1,op)" to ascertain whether we are
3273        dealing with a SNaN or QNaN */
3274     break;
3275    case fmt_word:
3276     boolean = (op == FPQNaN_WORD);
3277     break;
3278    case fmt_long:
3279     boolean = (op == FPQNaN_LONG);
3280     break;
3281    default:
3282     fprintf (stderr, "Bad switch\n");
3283     abort ();
3284   }
3285
3286 #ifdef DEBUG
3287 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
3288 #endif /* DEBUG */
3289
3290   return(boolean);
3291 }
3292
3293 static int
3294 Infinity(op,fmt)
3295      uword64 op;
3296      FP_formats fmt; 
3297 {
3298   int boolean = 0;
3299
3300 #ifdef DEBUG
3301   printf("DBG: Infinity: format %s 0x%s (PC = 0x%s)\n",DOFMT(fmt),pr_addr(op),pr_addr(IPC));
3302 #endif /* DEBUG */
3303
3304   /* Check if (((E - bias) == (E_max + 1)) && (fraction == 0)). We
3305      know that the exponent field is biased... we we cheat and avoid
3306      removing the bias value. */
3307   switch (fmt) {
3308    case fmt_single:
3309     boolean = ((FP_S_be(op) == 0xFF) && (FP_S_f(op) == 0));
3310     break;
3311    case fmt_double:
3312     boolean = ((FP_D_be(op) == 0x7FF) && (FP_D_f(op) == 0));
3313     break;
3314    default:
3315     printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
3316     break;
3317   }
3318
3319 #ifdef DEBUG
3320   printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
3321 #endif /* DEBUG */
3322
3323   return(boolean);
3324 }
3325
3326 static int
3327 Less(op1,op2,fmt)
3328      uword64 op1;
3329      uword64 op2;
3330      FP_formats fmt; 
3331 {
3332   int boolean = 0;
3333
3334   /* Argument checking already performed by the FPCOMPARE code */
3335
3336 #ifdef DEBUG
3337   printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3338 #endif /* DEBUG */
3339
3340   /* The format type should already have been checked: */
3341   switch (fmt) {
3342    case fmt_single:
3343     {
3344       unsigned int wop1 = (unsigned int)op1;
3345       unsigned int wop2 = (unsigned int)op2;
3346       boolean = (*(float *)&wop1 < *(float *)&wop2);
3347     }
3348     break;
3349    case fmt_double:
3350     boolean = (*(double *)&op1 < *(double *)&op2);
3351     break;
3352    default:
3353     fprintf (stderr, "Bad switch\n");
3354     abort ();
3355   }
3356
3357 #ifdef DEBUG
3358   printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
3359 #endif /* DEBUG */
3360
3361   return(boolean);
3362 }
3363
3364 static int
3365 Equal(op1,op2,fmt)
3366      uword64 op1;
3367      uword64 op2;
3368      FP_formats fmt; 
3369 {
3370   int boolean = 0;
3371
3372   /* Argument checking already performed by the FPCOMPARE code */
3373
3374 #ifdef DEBUG
3375   printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3376 #endif /* DEBUG */
3377
3378   /* The format type should already have been checked: */
3379   switch (fmt) {
3380    case fmt_single:
3381     boolean = ((op1 & 0xFFFFFFFF) == (op2 & 0xFFFFFFFF));
3382     break;
3383    case fmt_double:
3384     boolean = (op1 == op2);
3385     break;
3386    default:
3387     fprintf (stderr, "Bad switch\n");
3388     abort ();
3389   }
3390
3391 #ifdef DEBUG
3392   printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
3393 #endif /* DEBUG */
3394
3395   return(boolean);
3396 }
3397
3398 static uword64
3399 AbsoluteValue(op,fmt)
3400      uword64 op;
3401      FP_formats fmt; 
3402 {
3403   uword64 result = 0;
3404
3405 #ifdef DEBUG
3406   printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3407 #endif /* DEBUG */
3408
3409   /* The format type should already have been checked: */
3410   switch (fmt) {
3411    case fmt_single:
3412     {
3413       unsigned int wop = (unsigned int)op;
3414       float tmp = ((float)fabs((double)*(float *)&wop));
3415       result = (uword64)*(unsigned int *)&tmp;
3416     }
3417     break;
3418    case fmt_double:
3419     {
3420       double tmp = (fabs(*(double *)&op));
3421       result = *(uword64 *)&tmp;
3422     }
3423    default:
3424     fprintf (stderr, "Bad switch\n");
3425     abort ();
3426   }
3427
3428   return(result);
3429 }
3430
3431 static uword64
3432 Negate(op,fmt)
3433      uword64 op;
3434      FP_formats fmt; 
3435 {
3436   uword64 result = 0;
3437
3438 #ifdef DEBUG
3439   printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3440 #endif /* DEBUG */
3441
3442   /* The format type should already have been checked: */
3443   switch (fmt) {
3444    case fmt_single:
3445     {
3446       unsigned int wop = (unsigned int)op;
3447       float tmp = ((float)0.0 - *(float *)&wop);
3448       result = (uword64)*(unsigned int *)&tmp;
3449     }
3450     break;
3451    case fmt_double:
3452     {
3453       double tmp = ((double)0.0 - *(double *)&op);
3454       result = *(uword64 *)&tmp;
3455     }
3456     break;
3457    default:
3458     fprintf (stderr, "Bad switch\n");
3459     abort ();
3460   }
3461
3462   return(result);
3463 }
3464
3465 static uword64
3466 Add(op1,op2,fmt)
3467      uword64 op1;
3468      uword64 op2;
3469      FP_formats fmt; 
3470 {
3471   uword64 result = 0;
3472
3473 #ifdef DEBUG
3474   printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3475 #endif /* DEBUG */
3476
3477   /* The registers must specify FPRs valid for operands of type
3478      "fmt". If they are not valid, the result is undefined. */
3479
3480   /* The format type should already have been checked: */
3481   switch (fmt) {
3482    case fmt_single:
3483     {
3484       unsigned int wop1 = (unsigned int)op1;
3485       unsigned int wop2 = (unsigned int)op2;
3486       float tmp = (*(float *)&wop1 + *(float *)&wop2);
3487       result = (uword64)*(unsigned int *)&tmp;
3488     }
3489     break;
3490    case fmt_double:
3491     {
3492       double tmp = (*(double *)&op1 + *(double *)&op2);
3493       result = *(uword64 *)&tmp;
3494     }
3495     break;
3496    default:
3497     fprintf (stderr, "Bad switch\n");
3498     abort ();
3499   }
3500
3501 #ifdef DEBUG
3502   printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3503 #endif /* DEBUG */
3504
3505   return(result);
3506 }
3507
3508 static uword64
3509 Sub(op1,op2,fmt)
3510      uword64 op1;
3511      uword64 op2;
3512      FP_formats fmt; 
3513 {
3514   uword64 result = 0;
3515
3516 #ifdef DEBUG
3517   printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3518 #endif /* DEBUG */
3519
3520   /* The registers must specify FPRs valid for operands of type
3521      "fmt". If they are not valid, the result is undefined. */
3522
3523   /* The format type should already have been checked: */
3524   switch (fmt) {
3525    case fmt_single:
3526     {
3527       unsigned int wop1 = (unsigned int)op1;
3528       unsigned int wop2 = (unsigned int)op2;
3529       float tmp = (*(float *)&wop1 - *(float *)&wop2);
3530       result = (uword64)*(unsigned int *)&tmp;
3531     }
3532     break;
3533    case fmt_double:
3534     {
3535       double tmp = (*(double *)&op1 - *(double *)&op2);
3536       result = *(uword64 *)&tmp;
3537     }
3538     break;
3539    default:
3540     fprintf (stderr, "Bad switch\n");
3541     abort ();
3542   }
3543
3544 #ifdef DEBUG
3545   printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3546 #endif /* DEBUG */
3547
3548   return(result);
3549 }
3550
3551 static uword64
3552 Multiply(op1,op2,fmt)
3553      uword64 op1;
3554      uword64 op2;
3555      FP_formats fmt; 
3556 {
3557   uword64 result = 0;
3558
3559 #ifdef DEBUG
3560   printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3561 #endif /* DEBUG */
3562
3563   /* The registers must specify FPRs valid for operands of type
3564      "fmt". If they are not valid, the result is undefined. */
3565
3566   /* The format type should already have been checked: */
3567   switch (fmt) {
3568    case fmt_single:
3569     {
3570       unsigned int wop1 = (unsigned int)op1;
3571       unsigned int wop2 = (unsigned int)op2;
3572       float tmp = (*(float *)&wop1 * *(float *)&wop2);
3573       result = (uword64)*(unsigned int *)&tmp;
3574     }
3575     break;
3576    case fmt_double:
3577     {
3578       double tmp = (*(double *)&op1 * *(double *)&op2);
3579       result = *(uword64 *)&tmp;
3580     }
3581     break;
3582    default:
3583     fprintf (stderr, "Bad switch\n");
3584     abort ();
3585   }
3586
3587 #ifdef DEBUG
3588   printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3589 #endif /* DEBUG */
3590
3591   return(result);
3592 }
3593
3594 static uword64
3595 Divide(op1,op2,fmt)
3596      uword64 op1;
3597      uword64 op2;
3598      FP_formats fmt; 
3599 {
3600   uword64 result = 0;
3601
3602 #ifdef DEBUG
3603   printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3604 #endif /* DEBUG */
3605
3606   /* The registers must specify FPRs valid for operands of type
3607      "fmt". If they are not valid, the result is undefined. */
3608
3609   /* The format type should already have been checked: */
3610   switch (fmt) {
3611    case fmt_single:
3612     {
3613       unsigned int wop1 = (unsigned int)op1;
3614       unsigned int wop2 = (unsigned int)op2;
3615       float tmp = (*(float *)&wop1 / *(float *)&wop2);
3616       result = (uword64)*(unsigned int *)&tmp;
3617     }
3618     break;
3619    case fmt_double:
3620     {
3621       double tmp = (*(double *)&op1 / *(double *)&op2);
3622       result = *(uword64 *)&tmp;
3623     }
3624     break;
3625    default:
3626     fprintf (stderr, "Bad switch\n");
3627     abort ();
3628   }
3629
3630 #ifdef DEBUG
3631   printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3632 #endif /* DEBUG */
3633
3634   return(result);
3635 }
3636
3637 static uword64 UNUSED
3638 Recip(op,fmt)
3639      uword64 op;
3640      FP_formats fmt; 
3641 {
3642   uword64 result = 0;
3643
3644 #ifdef DEBUG
3645   printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3646 #endif /* DEBUG */
3647
3648   /* The registers must specify FPRs valid for operands of type
3649      "fmt". If they are not valid, the result is undefined. */
3650
3651   /* The format type should already have been checked: */
3652   switch (fmt) {
3653    case fmt_single:
3654     {
3655       unsigned int wop = (unsigned int)op;
3656       float tmp = ((float)1.0 / *(float *)&wop);
3657       result = (uword64)*(unsigned int *)&tmp;
3658     }
3659     break;
3660    case fmt_double:
3661     {
3662       double tmp = ((double)1.0 / *(double *)&op);
3663       result = *(uword64 *)&tmp;
3664     }
3665     break;
3666    default:
3667     fprintf (stderr, "Bad switch\n");
3668     abort ();
3669   }
3670
3671 #ifdef DEBUG
3672   printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3673 #endif /* DEBUG */
3674
3675   return(result);
3676 }
3677
3678 static uword64
3679 SquareRoot(op,fmt)
3680      uword64 op;
3681      FP_formats fmt; 
3682 {
3683   uword64 result = 0;
3684
3685 #ifdef DEBUG
3686   printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3687 #endif /* DEBUG */
3688
3689   /* The registers must specify FPRs valid for operands of type
3690      "fmt". If they are not valid, the result is undefined. */
3691
3692   /* The format type should already have been checked: */
3693   switch (fmt) {
3694    case fmt_single:
3695     {
3696       unsigned int wop = (unsigned int)op;
3697 #ifdef HAVE_SQRT
3698       float tmp = ((float)sqrt((double)*(float *)&wop));
3699       result = (uword64)*(unsigned int *)&tmp;
3700 #else
3701       /* TODO: Provide square-root */
3702       result = (uword64)0;
3703 #endif
3704     }
3705     break;
3706    case fmt_double:
3707     {
3708 #ifdef HAVE_SQRT
3709       double tmp = (sqrt(*(double *)&op));
3710       result = *(uword64 *)&tmp;
3711 #else
3712       /* TODO: Provide square-root */
3713       result = (uword64)0;
3714 #endif
3715     }
3716     break;
3717    default:
3718     fprintf (stderr, "Bad switch\n");
3719     abort ();
3720   }
3721
3722 #ifdef DEBUG
3723   printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3724 #endif /* DEBUG */
3725
3726   return(result);
3727 }
3728
3729 static uword64
3730 Convert(rm,op,from,to)
3731      int rm;
3732      uword64 op;
3733      FP_formats from; 
3734      FP_formats to; 
3735 {
3736   uword64 result = 0;
3737
3738 #ifdef DEBUG
3739   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));
3740 #endif /* DEBUG */
3741
3742   /* The value "op" is converted to the destination format, rounding
3743      using mode "rm". When the destination is a fixed-point format,
3744      then a source value of Infinity, NaN or one which would round to
3745      an integer outside the fixed point range then an IEEE Invalid
3746      Operation condition is raised. */
3747   switch (to) {
3748    case fmt_single:
3749     {
3750       float tmp;
3751       switch (from) {
3752        case fmt_double:
3753         tmp = (float)(*(double *)&op);
3754         break;
3755
3756        case fmt_word:
3757         tmp = (float)((int)(op & 0xFFFFFFFF));
3758         break;
3759
3760        case fmt_long:
3761         tmp = (float)((word64)op);
3762         break;
3763        default:
3764         fprintf (stderr, "Bad switch\n");
3765         abort ();
3766       }
3767
3768 #if 0
3769       /* FIXME: This code is incorrect.  The rounding mode does not
3770          round to integral values; it rounds to the nearest
3771          representable value in the format.  */
3772
3773       switch (rm) {
3774        case FP_RM_NEAREST:
3775         /* Round result to nearest representable value. When two
3776            representable values are equally near, round to the value
3777            that has a least significant bit of zero (i.e. is even). */
3778 #ifdef HAVE_ANINT
3779         tmp = (float)anint((double)tmp);
3780 #else
3781         /* TODO: Provide round-to-nearest */
3782 #endif
3783         break;
3784
3785        case FP_RM_TOZERO:
3786         /* Round result to the value closest to, and not greater in
3787            magnitude than, the result. */
3788 #ifdef HAVE_AINT
3789         tmp = (float)aint((double)tmp);
3790 #else
3791         /* TODO: Provide round-to-zero */
3792 #endif
3793         break;
3794
3795        case FP_RM_TOPINF:
3796         /* Round result to the value closest to, and not less than,
3797            the result. */
3798         tmp = (float)ceil((double)tmp);
3799         break;
3800
3801        case FP_RM_TOMINF:
3802         /* Round result to the value closest to, and not greater than,
3803            the result. */
3804         tmp = (float)floor((double)tmp);
3805         break;
3806       }
3807 #endif /* 0 */
3808
3809       result = (uword64)*(unsigned int *)&tmp;
3810     }
3811     break;
3812
3813    case fmt_double:
3814     {
3815       double tmp;
3816       word64 xxx;
3817
3818       switch (from) {
3819        case fmt_single:
3820         {
3821           unsigned int wop = (unsigned int)op;
3822           tmp = (double)(*(float *)&wop);
3823         }
3824         break;
3825
3826        case fmt_word:
3827         xxx = SIGNEXTEND((op & 0xFFFFFFFF),32);
3828         tmp = (double)xxx;
3829         break;
3830
3831        case fmt_long:
3832         tmp = (double)((word64)op);
3833         break;
3834
3835        default:
3836         fprintf (stderr, "Bad switch\n");
3837         abort ();
3838       }
3839
3840 #if 0
3841       /* FIXME: This code is incorrect.  The rounding mode does not
3842          round to integral values; it rounds to the nearest
3843          representable value in the format.  */
3844
3845       switch (rm) {
3846        case FP_RM_NEAREST:
3847 #ifdef HAVE_ANINT
3848         tmp = anint(*(double *)&tmp);
3849 #else
3850         /* TODO: Provide round-to-nearest */
3851 #endif
3852         break;
3853
3854        case FP_RM_TOZERO:
3855 #ifdef HAVE_AINT
3856         tmp = aint(*(double *)&tmp);
3857 #else
3858         /* TODO: Provide round-to-zero */
3859 #endif
3860         break;
3861
3862        case FP_RM_TOPINF:
3863         tmp = ceil(*(double *)&tmp);
3864         break;
3865
3866        case FP_RM_TOMINF:
3867         tmp = floor(*(double *)&tmp);
3868         break;
3869       }
3870 #endif /* 0 */
3871
3872       result = *(uword64 *)&tmp;
3873     }
3874     break;
3875
3876    case fmt_word:
3877    case fmt_long:
3878     if (Infinity(op,from) || NaN(op,from) || (1 == 0/*TODO: check range */)) {
3879       printf("DBG: TODO: update FCSR\n");
3880       SignalException(FPE);
3881     } else {
3882       if (to == fmt_word) {
3883         int tmp = 0;
3884         switch (from) {
3885          case fmt_single:
3886           {
3887             unsigned int wop = (unsigned int)op;
3888             tmp = (int)*((float *)&wop);
3889           }
3890           break;
3891          case fmt_double:
3892           tmp = (int)*((double *)&op);
3893 #ifdef DEBUG
3894           printf("DBG: from double %.30f (0x%s) to word: 0x%08X\n",*((double *)&op),pr_addr(op),tmp);
3895 #endif /* DEBUG */
3896           break;
3897          default:
3898           fprintf (stderr, "Bad switch\n");
3899           abort ();
3900         }
3901         result = (uword64)tmp;
3902       } else { /* fmt_long */
3903         word64 tmp = 0;
3904         switch (from) {
3905          case fmt_single:
3906           {
3907             unsigned int wop = (unsigned int)op;
3908             tmp = (word64)*((float *)&wop);
3909           }
3910           break;
3911          case fmt_double:
3912           tmp = (word64)*((double *)&op);
3913           break;
3914          default:
3915           fprintf (stderr, "Bad switch\n");
3916           abort ();
3917         }
3918         result = (uword64)tmp;
3919       }
3920     }
3921     break;
3922    default:
3923     fprintf (stderr, "Bad switch\n");
3924     abort ();
3925   }
3926
3927 #ifdef DEBUG
3928   printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result),DOFMT(to));
3929 #endif /* DEBUG */
3930
3931   return(result);
3932 }
3933 #endif /* HASFPU */
3934
3935 /*-- co-processor support routines ------------------------------------------*/
3936
3937 static int UNUSED
3938 CoProcPresent(coproc_number)
3939      unsigned int coproc_number;
3940 {
3941   /* Return TRUE if simulator provides a model for the given co-processor number */
3942   return(0);
3943 }
3944
3945 static void
3946 COP_LW(coproc_num,coproc_reg,memword)
3947      int coproc_num, coproc_reg;
3948      unsigned int memword;
3949 {
3950   switch (coproc_num) {
3951 #if defined(HASFPU)
3952     case 1:
3953 #ifdef DEBUG
3954     printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
3955 #endif
3956      StoreFPR(coproc_reg,fmt_word,(uword64)memword);
3957      fpr_state[coproc_reg] = fmt_uninterpreted;
3958      break;
3959 #endif /* HASFPU */
3960
3961     default:
3962 #if 0 /* this should be controlled by a configuration option */
3963      callback->printf_filtered(callback,"COP_LW(%d,%d,0x%08X) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(IPC));
3964 #endif
3965      break;
3966   }
3967
3968   return;
3969 }
3970
3971 static void
3972 COP_LD(coproc_num,coproc_reg,memword)
3973      int coproc_num, coproc_reg;
3974      uword64 memword;
3975 {
3976   switch (coproc_num) {
3977 #if defined(HASFPU)
3978     case 1:
3979      StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3980      break;
3981 #endif /* HASFPU */
3982
3983     default:
3984 #if 0 /* this message should be controlled by a configuration option */
3985      callback->printf_filtered(callback,"COP_LD(%d,%d,0x%s) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(IPC));
3986 #endif
3987      break;
3988   }
3989
3990   return;
3991 }
3992
3993 static unsigned int
3994 COP_SW(coproc_num,coproc_reg)
3995      int coproc_num, coproc_reg;
3996 {
3997   unsigned int value = 0;
3998   FP_formats hold;
3999
4000   switch (coproc_num) {
4001 #if defined(HASFPU)
4002     case 1:
4003 #if 1
4004      hold = fpr_state[coproc_reg];
4005      fpr_state[coproc_reg] = fmt_word;
4006      value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
4007      fpr_state[coproc_reg] = hold;
4008 #else
4009 #if 1
4010      value = (unsigned int)ValueFPR(coproc_reg,fpr_state[coproc_reg]);
4011 #else
4012 #ifdef DEBUG
4013      printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(fpr_state[coproc_reg])); 
4014 #endif /* DEBUG */
4015      value = (unsigned int)ValueFPR(coproc_reg,fmt_single);
4016 #endif
4017 #endif
4018      break;
4019 #endif /* HASFPU */
4020
4021     default:
4022 #if 0 /* should be controlled by configuration option */
4023      callback->printf_filtered(callback,"COP_SW(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
4024 #endif
4025      break;
4026   }
4027
4028   return(value);
4029 }
4030
4031 static uword64
4032 COP_SD(coproc_num,coproc_reg)
4033      int coproc_num, coproc_reg;
4034 {
4035   uword64 value = 0;
4036   switch (coproc_num) {
4037 #if defined(HASFPU)
4038     case 1:
4039 #if 1
4040      value = ValueFPR(coproc_reg,fmt_uninterpreted);
4041 #else
4042 #if 1
4043      value = ValueFPR(coproc_reg,fpr_state[coproc_reg]);
4044 #else
4045 #ifdef DEBUG
4046      printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(fpr_state[coproc_reg]));
4047 #endif /* DEBUG */
4048      value = ValueFPR(coproc_reg,fmt_double);
4049 #endif
4050 #endif
4051      break;
4052 #endif /* HASFPU */
4053
4054     default:
4055 #if 0 /* should be controlled by configuration option */
4056      callback->printf_filtered(callback,"COP_SD(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
4057 #endif
4058      break;
4059   }
4060
4061   return(value);
4062 }
4063
4064 static void
4065 decode_coproc(instruction)
4066      unsigned int instruction;
4067 {
4068   int coprocnum = ((instruction >> 26) & 3);
4069
4070   switch (coprocnum)
4071     {
4072     case 0: /* standard CPU control and cache registers */
4073       {
4074         int code = ((instruction >> 21) & 0x1F);
4075         /* R4000 Users Manual (second edition) lists the following CP0
4076            instructions:
4077            DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
4078            DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
4079            MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
4080            MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
4081            TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
4082            TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
4083            TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
4084            TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
4085            CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
4086            ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
4087            */
4088         if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
4089           {
4090             int rt = ((instruction >> 16) & 0x1F);
4091             int rd = ((instruction >> 11) & 0x1F);
4092             
4093             switch (rd)  /* NOTEs: Standard CP0 registers */
4094               {
4095                 /* 0 = Index               R4000   VR4100  VR4300 */
4096                 /* 1 = Random              R4000   VR4100  VR4300 */
4097                 /* 2 = EntryLo0            R4000   VR4100  VR4300 */
4098                 /* 3 = EntryLo1            R4000   VR4100  VR4300 */
4099                 /* 4 = Context             R4000   VR4100  VR4300 */
4100                 /* 5 = PageMask            R4000   VR4100  VR4300 */
4101                 /* 6 = Wired               R4000   VR4100  VR4300 */
4102                 /* 8 = BadVAddr            R4000   VR4100  VR4300 */
4103                 /* 9 = Count               R4000   VR4100  VR4300 */
4104                 /* 10 = EntryHi            R4000   VR4100  VR4300 */
4105                 /* 11 = Compare            R4000   VR4100  VR4300 */
4106                 /* 12 = SR                 R4000   VR4100  VR4300 */
4107               case 12:
4108                 if (code == 0x00)
4109                   GPR[rt] = SR;
4110                 else
4111                   SR = GPR[rt];
4112                 break;
4113                 /* 13 = Cause              R4000   VR4100  VR4300 */
4114                 /* 14 = EPC                R4000   VR4100  VR4300 */
4115                 /* 15 = PRId               R4000   VR4100  VR4300 */
4116                 /* 16 = Config             R4000   VR4100  VR4300 */
4117                 /* 17 = LLAddr             R4000   VR4100  VR4300 */
4118                 /* 18 = WatchLo            R4000   VR4100  VR4300 */
4119                 /* 19 = WatchHi            R4000   VR4100  VR4300 */
4120                 /* 20 = XContext           R4000   VR4100  VR4300 */
4121                 /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
4122                 /* 27 = CacheErr           R4000   VR4100 */
4123                 /* 28 = TagLo              R4000   VR4100  VR4300 */
4124                 /* 29 = TagHi              R4000   VR4100  VR4300 */
4125                 /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
4126                 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
4127                 /* CPR[0,rd] = GPR[rt]; */
4128               default:
4129                 if (code == 0x00)
4130                   callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
4131                 else
4132                   callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
4133               }
4134           }
4135         else if (code == 0x10 && (instruction & 0x3f) == 0x18)
4136           {
4137             /* ERET */
4138             if (SR & status_ERL)
4139               {
4140                 /* Oops, not yet available */
4141                 callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
4142                 PC = EPC;
4143                 SR &= ~status_ERL;
4144               }
4145             else
4146               {
4147                 PC = EPC;
4148                 SR &= ~status_EXL;
4149               }
4150           }
4151         else
4152           sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
4153         /* TODO: When executing an ERET or RFE instruction we should
4154            clear LLBIT, to ensure that any out-standing atomic
4155            read/modify/write sequence fails. */
4156       }
4157     break;
4158     
4159     case 2: /* undefined co-processor */
4160       sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
4161       break;
4162       
4163     case 1: /* should not occur (FPU co-processor) */
4164     case 3: /* should not occur (FPU co-processor) */
4165       SignalException(ReservedInstruction,instruction);
4166       break;
4167     }
4168   
4169   return;
4170 }
4171
4172 /*-- instruction simulation -------------------------------------------------*/
4173
4174 void
4175 sim_engine_run (sd, next_cpu_nr, siggnal)
4176      SIM_DESC sd;
4177      int next_cpu_nr; /* ignore */
4178      int siggnal; /* ignore */
4179 {
4180 #if !defined(FASTSIM)
4181   unsigned int pipeline_count = 1;
4182 #endif
4183
4184 #ifdef DEBUG
4185   if (STATE_MEMORY (sd) == NULL) {
4186     printf("DBG: simulate() entered with no memory\n");
4187     exit(1);
4188   }
4189 #endif /* DEBUG */
4190
4191 #if 0 /* Disabled to check that everything works OK */
4192   /* The VR4300 seems to sign-extend the PC on its first
4193      access. However, this may just be because it is currently
4194      configured in 32bit mode. However... */
4195   PC = SIGNEXTEND(PC,32);
4196 #endif
4197
4198   /* main controlling loop */
4199   while (1) {
4200     /* Fetch the next instruction from the simulator memory: */
4201     uword64 vaddr = (uword64)PC;
4202     uword64 paddr;
4203     int cca;
4204     unsigned int instruction;   /* uword64? what's this used for?  FIXME! */
4205     int dsstate = (state & simDELAYSLOT);
4206
4207 #ifdef DEBUG
4208     {
4209       printf("DBG: state = 0x%08X :",state);
4210 #if 0
4211       if (state & simSTOP) printf(" simSTOP");
4212       if (state & simSTEP) printf(" simSTEP");
4213 #endif
4214       if (state & simHALTEX) printf(" simHALTEX");
4215       if (state & simHALTIN) printf(" simHALTIN");
4216 #if 0
4217       if (state & simBE) printf(" simBE");
4218 #endif
4219       printf("\n");
4220     }
4221 #endif /* DEBUG */
4222
4223 #ifdef DEBUG
4224     if (dsstate)
4225      callback->printf_filtered(callback,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
4226 #endif /* DEBUG */
4227
4228     if (AddressTranslation(PC,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
4229       if ((vaddr & 1) == 0) {
4230         /* Copy the action of the LW instruction */
4231         unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
4232         unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
4233         uword64 value;
4234         unsigned int byte;
4235         paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
4236         LoadMemory(&value,NULL,cca,AccessLength_WORD,paddr,vaddr,isINSTRUCTION,isREAL);
4237         byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
4238         instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
4239       } else {
4240         /* Copy the action of the LH instruction */
4241         unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 1) : 0);
4242         unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 1) : 0);
4243         uword64 value;
4244         unsigned int byte;
4245         paddr = (((paddr & ~ (uword64) 1) & ~LOADDRMASK)
4246                  | (((paddr & ~ (uword64) 1) & LOADDRMASK) ^ (reverse << 1)));
4247         LoadMemory(&value,NULL,cca, AccessLength_HALFWORD,
4248                            paddr & ~ (uword64) 1,
4249                            vaddr, isINSTRUCTION, isREAL);
4250         byte = (((vaddr &~ (uword64) 1) & LOADDRMASK) ^ (bigend << 1));
4251         instruction = ((value >> (8 * byte)) & 0xFFFF);
4252       }
4253     } else {
4254       fprintf(stderr,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC));
4255       exit(1);
4256     }
4257
4258 #ifdef DEBUG
4259     callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
4260 #endif /* DEBUG */
4261
4262 #if !defined(FASTSIM) || defined(PROFILE)
4263     instruction_fetches++;
4264     /* Since we increment above, the value should only ever be zero if
4265        we have just overflowed: */
4266     if (instruction_fetches == 0)
4267       instruction_fetch_overflow++;
4268 #if defined(PROFILE)
4269     if ((state & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
4270       unsigned n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
4271       if (n < profile_nsamples) {
4272         /* NOTE: The counts for the profiling bins are only 16bits wide */
4273         if (profile_hist[n] != USHRT_MAX)
4274          (profile_hist[n])++;
4275       }
4276     }
4277 #endif /* PROFILE */
4278 #endif /* !FASTSIM && PROFILE */
4279
4280     IPC = PC; /* copy PC for this instruction */
4281     /* This is required by exception processing, to ensure that we can
4282        cope with exceptions in the delay slots of branches that may
4283        already have changed the PC. */
4284     if ((vaddr & 1) == 0)
4285       PC += 4; /* increment ready for the next fetch */
4286     else
4287       PC += 2;
4288     /* NOTE: If we perform a delay slot change to the PC, this
4289        increment is not requuired. However, it would make the
4290        simulator more complicated to try and avoid this small hit. */
4291
4292     /* Currently this code provides a simple model. For more
4293        complicated models we could perform exception status checks at
4294        this point, and set the simSTOP state as required. This could
4295        also include processing any hardware interrupts raised by any
4296        I/O model attached to the simulator context.
4297
4298        Support for "asynchronous" I/O events within the simulated world
4299        could be providing by managing a counter, and calling a I/O
4300        specific handler when a particular threshold is reached. On most
4301        architectures a decrement and check for zero operation is
4302        usually quicker than an increment and compare. However, the
4303        process of managing a known value decrement to zero, is higher
4304        than the cost of using an explicit value UINT_MAX into the
4305        future. Which system is used will depend on how complicated the
4306        I/O model is, and how much it is likely to affect the simulator
4307        bandwidth.
4308
4309        If events need to be scheduled further in the future than
4310        UINT_MAX event ticks, then the I/O model should just provide its
4311        own counter, triggered from the event system. */
4312
4313     /* MIPS pipeline ticks. To allow for future support where the
4314        pipeline hit of individual instructions is known, this control
4315        loop manages a "pipeline_count" variable. It is initialised to
4316        1 (one), and will only be changed by the simulator engine when
4317        executing an instruction. If the engine does not have access to
4318        pipeline cycle count information then all instructions will be
4319        treated as using a single cycle. NOTE: A standard system is not
4320        provided by the default simulator because different MIPS
4321        architectures have different cycle counts for the same
4322        instructions.
4323
4324        [NOTE: pipeline_count has been replaced the event queue] */
4325
4326 #if defined(HASFPU)
4327     /* Set previous flag, depending on current: */
4328     if (state & simPCOC0)
4329      state |= simPCOC1;
4330     else
4331      state &= ~simPCOC1;
4332     /* and update the current value: */
4333     if (GETFCC(0))
4334      state |= simPCOC0;
4335     else
4336      state &= ~simPCOC0;
4337 #endif /* HASFPU */
4338
4339 /* NOTE: For multi-context simulation environments the "instruction"
4340    variable should be local to this routine. */
4341
4342 /* Shorthand accesses for engine. Note: If we wanted to use global
4343    variables (and a single-threaded simulator engine), then we can
4344    create the actual variables with these names. */
4345
4346     if (!(state & simSKIPNEXT)) {
4347       /* Include the simulator engine */
4348 #include "engine.c"
4349 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
4350 #error "Mismatch between run-time simulator code and simulation engine"
4351 #endif
4352
4353 #if defined(WARN_LOHI)
4354       /* Decrement the HI/LO validity ticks */
4355       if (HIACCESS > 0)
4356        HIACCESS--;
4357       if (LOACCESS > 0)
4358        LOACCESS--;
4359       if (HI1ACCESS > 0)
4360        HI1ACCESS--;
4361       if (LO1ACCESS > 0)
4362        LO1ACCESS--;
4363 #endif /* WARN_LOHI */
4364
4365 #if defined(WARN_ZERO)
4366       /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
4367          should check for it being changed. It is better doing it here,
4368          than within the simulator, since it will help keep the simulator
4369          small. */
4370       if (ZERO != 0) {
4371         sim_warning("The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)",pr_addr(ZERO),pr_addr(IPC));
4372         ZERO = 0; /* reset back to zero before next instruction */
4373       }
4374 #endif /* WARN_ZERO */
4375     } else /* simSKIPNEXT check */
4376      state &= ~simSKIPNEXT;
4377
4378     /* If the delay slot was active before the instruction is
4379        executed, then update the PC to its new value: */
4380     if (dsstate) {
4381 #ifdef DEBUG
4382       printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
4383 #endif /* DEBUG */
4384       PC = DSPC;
4385       state &= ~(simDELAYSLOT | simJALDELAYSLOT);
4386     }
4387
4388     if (MIPSISA < 4) { /* The following is only required on pre MIPS IV processors: */
4389       /* Deal with pending register updates: */
4390 #ifdef DEBUG
4391       printf("DBG: EMPTY BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
4392 #endif /* DEBUG */
4393       if (pending_out != pending_in) {
4394         int loop;
4395         int index = pending_out;
4396         int total = pending_total;
4397         if (pending_total == 0) {
4398           fprintf(stderr,"FATAL: Mis-match on pending update pointers\n");
4399           exit(1);
4400         }
4401         for (loop = 0; (loop < total); loop++) {
4402 #ifdef DEBUG
4403           printf("DBG: BEFORE index = %d, loop = %d\n",index,loop);
4404 #endif /* DEBUG */
4405           if (pending_slot_reg[index] != (LAST_EMBED_REGNUM + 1)) {
4406 #ifdef DEBUG
4407             printf("pending_slot_count[%d] = %d\n",index,pending_slot_count[index]);
4408 #endif /* DEBUG */
4409             if (--(pending_slot_count[index]) == 0) {
4410 #ifdef DEBUG
4411               printf("pending_slot_reg[%d] = %d\n",index,pending_slot_reg[index]);
4412               printf("pending_slot_value[%d] = 0x%s\n",index,pr_addr(pending_slot_value[index]));
4413 #endif /* DEBUG */
4414               if (pending_slot_reg[index] == COCIDX) {
4415                 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
4416               } else {
4417                 registers[pending_slot_reg[index]] = pending_slot_value[index];
4418 #if defined(HASFPU)
4419                 /* The only time we have PENDING updates to FPU
4420                    registers, is when performing binary transfers. This
4421                    means we should update the register type field.  */
4422                 if ((pending_slot_reg[index] >= FGRIDX) && (pending_slot_reg[index] < (FGRIDX + 32)))
4423                  fpr_state[pending_slot_reg[index] - FGRIDX] = fmt_uninterpreted;
4424 #endif /* HASFPU */
4425               }
4426 #ifdef DEBUG
4427               printf("registers[%d] = 0x%s\n",pending_slot_reg[index],pr_addr(registers[pending_slot_reg[index]]));
4428 #endif /* DEBUG */
4429               pending_slot_reg[index] = (LAST_EMBED_REGNUM + 1);
4430               pending_out++;
4431               if (pending_out == PSLOTS)
4432                pending_out = 0;
4433               pending_total--;
4434             }
4435           }
4436 #ifdef DEBUG
4437           printf("DBG: AFTER  index = %d, loop = %d\n",index,loop);
4438 #endif /* DEBUG */
4439           index++;
4440           if (index == PSLOTS)
4441            index = 0;
4442         }
4443       }
4444 #ifdef DEBUG
4445       printf("DBG: EMPTY AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
4446 #endif /* DEBUG */
4447     }
4448
4449 #if !defined(FASTSIM)
4450     if (sim_events_tickn (sd, pipeline_count))
4451       {
4452         /* cpu->cia = cia; */
4453         sim_events_process (sd);
4454       }
4455 #else
4456     if (sim_events_tick (sd))
4457       {
4458         /* cpu->cia = cia; */
4459         sim_events_process (sd);
4460       }
4461 #endif /* FASTSIM */
4462   }
4463 }
4464
4465 /* This code copied from gdb's utils.c.  Would like to share this code,
4466    but don't know of a common place where both could get to it. */
4467
4468 /* Temporary storage using circular buffer */
4469 #define NUMCELLS 16
4470 #define CELLSIZE 32
4471 static char*
4472 get_cell()
4473 {
4474   static char buf[NUMCELLS][CELLSIZE];
4475   static int cell=0;
4476   if (++cell>=NUMCELLS) cell=0;
4477   return buf[cell];
4478 }     
4479
4480 /* Print routines to handle variable size regs, etc */
4481
4482 /* Eliminate warning from compiler on 32-bit systems */
4483 static int thirty_two = 32;     
4484
4485 char* 
4486 pr_addr(addr)
4487   SIM_ADDR addr;
4488 {
4489   char *paddr_str=get_cell();
4490   switch (sizeof(addr))
4491     {
4492       case 8:
4493         sprintf(paddr_str,"%08lx%08lx",
4494                 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4495         break;
4496       case 4:
4497         sprintf(paddr_str,"%08lx",(unsigned long)addr);
4498         break;
4499       case 2:
4500         sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
4501         break;
4502       default:
4503         sprintf(paddr_str,"%x",addr);
4504     }
4505   return paddr_str;
4506 }
4507
4508 char* 
4509 pr_uword64(addr)
4510   uword64 addr;
4511 {
4512   char *paddr_str=get_cell();
4513   sprintf(paddr_str,"%08lx%08lx",
4514           (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4515   return paddr_str;
4516 }
4517
4518
4519 /*---------------------------------------------------------------------------*/
4520 /*> EOF interp.c <*/
This page took 0.278575 seconds and 4 git commands to generate.