2 /* Simulator for the MIPS architecture.
4 This file is part of the MIPS sim
6 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
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
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
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,
38 #if 1 /* 0 to allow user build selection, 1 to force inclusion */
64 #include "libiberty.h"
66 #include "callback.h" /* GDB simulator callback interface */
67 #include "remote-sim.h" /* GDB simulator interface */
69 #include "support.h" /* internal support manifests */
74 #define SIGBUS SIGSEGV
77 /* Get the simulator engine description, without including the code: */
82 /* This variable holds the GDB view of the target endianness: */
83 extern int target_byte_order
;
85 /* The following reserved instruction value is used when a simulator
86 trap is required. NOTE: Care must be taken, since this value may be
87 used in later revisions of the MIPS ISA. */
88 #define RSVD_INSTRUCTION (0x7C000000)
89 #define RSVD_INSTRUCTION_AMASK (0x03FFFFFF)
91 /* NOTE: These numbers depend on the processor architecture being
94 #define TLBModification (1)
97 #define AddressLoad (4)
98 #define AddressStore (5)
99 #define InstructionFetch (6)
100 #define DataReference (7)
101 #define SystemCall (8)
102 #define BreakPoint (9)
103 #define ReservedInstruction (10)
104 #define CoProcessorUnusable (11)
105 #define IntegerOverflow (12) /* Arithmetic overflow (IDT monitor raises SIGFPE) */
110 /* The following exception code is actually private to the simulator
111 world. It is *NOT* a processor feature, and is used to signal
112 run-time errors in the simulator. */
113 #define SimulatorFault (0xFFFFFFFF)
115 /* The following are generic to all versions of the MIPS architecture
117 /* Memory Access Types (for CCA): */
119 #define CachedNoncoherent (1)
120 #define CachedCoherent (2)
123 #define isINSTRUCTION (1 == 0) /* FALSE */
124 #define isDATA (1 == 1) /* TRUE */
126 #define isLOAD (1 == 0) /* FALSE */
127 #define isSTORE (1 == 1) /* TRUE */
129 #define isREAL (1 == 0) /* FALSE */
130 #define isRAW (1 == 1) /* TRUE */
132 #define isTARGET (1 == 0) /* FALSE */
133 #define isHOST (1 == 1) /* TRUE */
135 /* The "AccessLength" specifications for Loads and Stores. NOTE: This
136 is the number of bytes minus 1. */
137 #define AccessLength_BYTE (0)
138 #define AccessLength_HALFWORD (1)
139 #define AccessLength_TRIPLEBYTE (2)
140 #define AccessLength_WORD (3)
141 #define AccessLength_QUINTIBYTE (4)
142 #define AccessLength_SEXTIBYTE (5)
143 #define AccessLength_SEPTIBYTE (6)
144 #define AccessLength_DOUBLEWORD (7)
147 /* FPU registers must be one of the following types. All other values
148 are reserved (and undefined). */
154 /* The following are well outside the normal acceptable format
155 range, and are used in the register status vector. */
156 fmt_unknown
= 0x10000000,
157 fmt_uninterpreted
= 0x20000000,
161 /* NOTE: We cannot avoid globals, since the GDB "sim_" interface does
162 not allow a private variable to be passed around. This means that
163 simulators under GDB can only be single-threaded. However, it would
164 be possible for the simulators to be multi-threaded if GDB allowed
165 for a private pointer to be maintained. i.e. a general "void **ptr"
166 variable that GDB passed around in the argument list to all of
167 sim_xxx() routines. It could be initialised to NULL by GDB, and
168 then updated by sim_open() and used by the other sim_xxx() support
169 functions. This would allow new features in the simulator world,
170 like storing a context - continuing execution to gather a result,
171 and then going back to the point where the context was saved and
172 changing some state before continuing. i.e. the ability to perform
173 UNDOs on simulations. It would also allow the simulation of
174 shared-memory multi-processor systems. */
176 static host_callback
*callback
= NULL
; /* handle onto the current callback structure */
178 /* This is nasty, since we have to rely on matching the register
179 numbers used by GDB. Unfortunately, depending on the MIPS target
180 GDB uses different register numbers. We cannot just include the
181 relevant "gdb/tm.h" link, since GDB may not be configured before
182 the sim world, and also the GDB header file requires too much other
184 /* TODO: Sort out a scheme for *KNOWING* the mapping between real
185 registers, and the numbers that GDB uses. At the moment due to the
186 order that the tools are built, we cannot rely on a configured GDB
187 world whilst constructing the simulator. This means we have to
188 assume the GDB register number mapping. */
190 #define LAST_EMBED_REGNUM (89)
193 /* To keep this default simulator simple, and fast, we use a direct
194 vector of registers. The internal simulator engine then uses
195 manifests to access the correct slot. */
196 static ut_reg registers
[LAST_EMBED_REGNUM
+ 1];
197 static int register_widths
[LAST_EMBED_REGNUM
+ 1];
199 #define GPR (®isters[0])
202 #define FGR (®isters[FGRIDX])
204 #define LO (registers[33])
205 #define HI (registers[34])
206 #define PC (registers[37])
207 #define CAUSE (registers[36])
209 #define SR (registers[SRIDX]) /* CPU status register */
211 #define FCR0 (registers[FCR0IDX]) /* really a 32bit register */
212 #define FCR31IDX (70)
213 #define FCR31 (registers[FCR31IDX]) /* really a 32bit register */
215 #define COCIDX (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
217 /* The following are pseudonyms for standard registers */
218 #define ZERO (registers[0])
219 #define V0 (registers[2])
220 #define A0 (registers[4])
221 #define A1 (registers[5])
222 #define A2 (registers[6])
223 #define A3 (registers[7])
224 #define SP (registers[29])
225 #define RA (registers[31])
227 static ut_reg EPC
= 0; /* Exception PC */
230 /* Keep the current format state for each register: */
231 static FP_formats fpr_state
[32];
234 /* VR4300 CP0 configuration register: */
235 static unsigned int CONFIG
= 0;
237 /* The following are internal simulator state variables: */
238 static ut_reg IPC
= 0; /* internal Instruction PC */
239 static ut_reg DSPC
= 0; /* delay-slot PC */
242 /* TODO : these should be the bitmasks for these bits within the
243 status register. At the moment the following are VR4300
245 #define status_KSU_mask (0x3) /* mask for KSU bits */
246 #define status_KSU_shift (3) /* shift for field */
247 #define ksu_kernel (0x0)
248 #define ksu_supervisor (0x1)
249 #define ksu_user (0x2)
250 #define ksu_unknown (0x3)
252 #define status_RE (1 << 25) /* Reverse Endian in user mode */
253 #define status_FR (1 << 26) /* enables MIPS III additional FP registers */
254 #define status_SR (1 << 20) /* soft reset or NMI */
255 #define status_BEV (1 << 22) /* Location of general exception vectors */
256 #define status_TS (1 << 21) /* TLB shutdown has occurred */
257 #define status_ERL (1 << 2) /* Error level */
258 #define status_RP (1 << 27) /* Reduced Power mode */
260 #define config_EP_mask (0xF)
261 #define config_EP_shift (27)
262 #define config_EP_D (0x0)
263 #define config_EP_DxxDxx (0x6)
265 #define config_BE (1 << 15)
267 #define cause_BD ((unsigned)1 << 31) /* Exception in branch delay slot */
270 /* Macro to update FPSR condition-code field. This is complicated by
271 the fact that there is a hole in the index range of the bits within
272 the FCSR register. Also, the number of bits visible depends on the
273 MIPS ISA version being supported. */
274 #define SETFCC(cc,v) {\
275 int bit = ((cc == 0) ? 23 : (24 + (cc)));\
276 FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
278 #define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1 : 0)
280 /* This should be the COC1 value at the start of the preceding
282 #define PREVCOC1() ((state & simPCOC1) ? 1 : 0)
285 /* Standard FCRS bits: */
286 #define IR (0) /* Inexact Result */
287 #define UF (1) /* UnderFlow */
288 #define OF (2) /* OverFlow */
289 #define DZ (3) /* Division by Zero */
290 #define IO (4) /* Invalid Operation */
291 #define UO (5) /* Unimplemented Operation */
293 /* Get masks for individual flags: */
294 #if 1 /* SAFE version */
295 #define FP_FLAGS(b) (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
296 #define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
297 #define FP_CAUSE(b) (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
299 #define FP_FLAGS(b) (1 << ((b) + 2))
300 #define FP_ENABLE(b) (1 << ((b) + 7))
301 #define FP_CAUSE(b) (1 << ((b) + 12))
304 #define FP_FS (1 << 24) /* MIPS III onwards : Flush to Zero */
306 #define FP_MASK_RM (0x3)
308 #define FP_RM_NEAREST (0) /* Round to nearest (Round) */
309 #define FP_RM_TOZERO (1) /* Round to zero (Trunc) */
310 #define FP_RM_TOPINF (2) /* Round to Plus infinity (Ceil) */
311 #define FP_RM_TOMINF (3) /* Round to Minus infinity (Floor) */
312 #define GETRM() (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
314 /* Slots for delayed register updates. For the moment we just have a
315 fixed number of slots (rather than a more generic, dynamic
316 system). This keeps the simulator fast. However, we only allow for
317 the register update to be delayed for a single instruction
319 #define PSLOTS (5) /* Maximum number of instruction cycles */
320 static int pending_in
;
321 static int pending_out
;
322 static int pending_total
;
323 static int pending_slot_count
[PSLOTS
];
324 static int pending_slot_reg
[PSLOTS
];
325 static ut_reg pending_slot_value
[PSLOTS
];
327 /*---------------------------------------------------------------------------*/
328 /*-- GDB simulator interface ------------------------------------------------*/
329 /*---------------------------------------------------------------------------*/
331 static void dotrace
PARAMS((FILE *tracefh
,int type
,SIM_ADDR address
,int width
,char *comment
,...));
332 static void sim_warning
PARAMS((char *fmt
,...));
333 extern void sim_error
PARAMS((char *fmt
,...));
334 static void ColdReset
PARAMS((void));
335 static int AddressTranslation
PARAMS((uword64 vAddr
,int IorD
,int LorS
,uword64
*pAddr
,int *CCA
,int host
,int raw
));
336 static void StoreMemory
PARAMS((int CCA
,int AccessLength
,uword64 MemElem
,uword64 pAddr
,uword64 vAddr
,int raw
));
337 static uword64 LoadMemory
PARAMS((int CCA
,int AccessLength
,uword64 pAddr
,uword64 vAddr
,int IorD
,int raw
));
338 static void SignalException
PARAMS((int exception
,...));
339 static void simulate
PARAMS((void));
340 static long getnum
PARAMS((char *value
));
341 extern void sim_size
PARAMS((unsigned int newsize
));
342 extern void sim_set_profile
PARAMS((int frequency
));
343 static unsigned int power2
PARAMS((unsigned int value
));
345 /*---------------------------------------------------------------------------*/
347 /* The following are not used for MIPS IV onwards: */
348 #define PENDING_FILL(r,v) {\
349 /* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total); */\
350 if (pending_slot_reg[pending_in] != (LAST_EMBED_REGNUM + 1))\
351 sim_warning("Attempt to over-write pending value");\
352 pending_slot_count[pending_in] = 2;\
353 pending_slot_reg[pending_in] = (r);\
354 pending_slot_value[pending_in] = (uword64)(v);\
355 /*printf("DBG: FILL reg %d value = 0x%08X%08X\n",(r),WORD64HI(v),WORD64LO(v));*/\
358 if (pending_in == PSLOTS)\
360 /*printf("DBG: FILL AFTER pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);*/\
363 static int LLBIT
= 0;
364 /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
365 read-write instructions. It is set when a linked load occurs. It is
366 tested and cleared by the conditional store. It is cleared (during
367 other CPU operations) when a store to the location would no longer
368 be atomic. In particular, it is cleared by exception return
371 static int HIACCESS
= 0;
372 static int LOACCESS
= 0;
373 /* The HIACCESS and LOACCESS counts are used to ensure that
374 corruptions caused by using the HI or LO register to close to a
375 following operation are spotted. */
376 static ut_reg HLPC
= 0;
378 /* TODO: The 4300 has interlocks so we should not need to warn of the possible over-write (CHECK THIS) */
379 /* If either of the preceding two instructions have accessed the HI or
380 LO registers, then the values they see should be
381 undefined. However, to keep the simulator world simple, we just let
382 them use the value read and raise a warning to notify the user: */
383 #define CHECKHILO(s) {\
384 if ((HIACCESS != 0) || (LOACCESS != 0))\
385 sim_warning("%s over-writing HI and LO registers values (PC = 0x%08X%08X HLPC = 0x%08X%08X)\n",(s),(unsigned int)(PC>>32),(unsigned int)(PC&0xFFFFFFFF),(unsigned int)(HLPC>>32),(unsigned int)(HLPC&0xFFFFFFFF));\
388 /* NOTE: We keep the following status flags as bit values (1 for true,
389 0 for false). This allows them to be used in binary boolean
390 operations without worrying about what exactly the non-zero true
394 #define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
397 /* Hardware configuration. Affects endianness of LoadMemory and
398 StoreMemory and the endianness of Kernel and Supervisor mode
399 execution. The value is 0 for little-endian; 1 for big-endian. */
400 #define BigEndianMem ((CONFIG & config_BE) ? 1 : 0)
401 /* NOTE: Problems will occur if the simulator memory model does not
402 match the host program expectation. i.e. if the host is writing
403 big-endian values to a little-endian memory model. */
406 /* This mode is selected if in User mode with the RE bit being set in
407 SR (Status Register). It reverses the endianness of load and store
409 #define ReverseEndian (((SR & status_RE) && UserMode) ? 1 : 0)
412 /* The endianness for load and store instructions (0=little;1=big). In
413 User mode this endianness may be switched by setting the state_RE
414 bit in the SR register. Thus, BigEndianCPU may be computed as
415 (BigEndienMem EOR ReverseEndian). */
416 #define BigEndianCPU (BigEndianMem ^ ReverseEndian) /* Already bits */
418 #if !defined(FASTSIM) || defined(PROFILE)
419 /* At the moment these values will be the same, since we do not have
420 access to the pipeline cycle count information from the simulator
422 static unsigned int instruction_fetches
= 0;
423 static unsigned int instruction_fetch_overflow
= 0;
424 static unsigned int pipeline_ticks
= 0;
427 /* Flags in the "state" variable: */
428 #define simSTOP (1 << 0) /* 0 = execute; 1 = stop simulation */
429 #define simSTEP (1 << 1) /* 0 = run; 1 = single-step */
430 #define simHALTEX (1 << 2) /* 0 = run; 1 = halt on exception */
431 #define simHALTIN (1 << 3) /* 0 = run; 1 = halt on interrupt */
432 #define simTRACE (1 << 8) /* 0 = do nothing; 1 = trace address activity */
433 #define simPROFILE (1 << 9) /* 0 = do nothing; 1 = gather profiling samples */
434 #define simHOSTBE (1 << 10) /* 0 = little-endian; 1 = big-endian (host endianness) */
435 /* Whilst simSTOP is not set, the simulator control loop should just
436 keep simulating instructions. The simSTEP flag is used to force
437 single-step execution. */
438 #define simBE (1 << 16) /* 0 = little-endian; 1 = big-endian (target endianness) */
439 #define simPCOC0 (1 << 17) /* COC[1] from current */
440 #define simPCOC1 (1 << 18) /* COC[1] from previous */
441 #define simDELAYSLOT (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */
442 #define simSKIPNEXT (1 << 25) /* 0 = do nothing; 1 = skip instruction */
443 #define simEXCEPTION (1 << 26) /* 0 = no exception; 1 = exception has occurred */
444 #define simEXIT (1 << 27) /* 0 = do nothing; 1 = run-time exit() processing */
446 static unsigned int state
= 0;
447 static unsigned int rcexit
= 0; /* _exit() reason code holder */
449 #define DELAYSLOT() {\
450 if (state & simDELAYSLOT)\
451 sim_warning("Delay slot already activated (branch in delay slot?)");\
452 state |= simDELAYSLOT;\
456 state &= ~simDELAYSLOT;\
457 state |= simSKIPNEXT;\
460 #define K0BASE (0x80000000)
461 #define K0SIZE (0x20000000)
462 #define K1BASE (0xA0000000)
463 #define K1SIZE (0x20000000)
465 /* Very simple memory model to start with: */
466 static unsigned char *membank
= NULL
;
467 static ut_reg membank_base
= K1BASE
;
468 static unsigned membank_size
= (1 << 20); /* (16 << 20); */ /* power-of-2 */
470 /* Simple run-time monitor support */
471 static unsigned char *monitor
= NULL
;
472 static ut_reg monitor_base
= 0xBFC00000;
473 static unsigned monitor_size
= (1 << 11); /* power-of-2 */
475 static char *logfile
= NULL
; /* logging disabled by default */
476 static FILE *logfh
= NULL
;
479 static char *tracefile
= "trace.din"; /* default filename for trace log */
480 static FILE *tracefh
= NULL
;
484 static unsigned profile_frequency
= 256;
485 static unsigned profile_nsamples
= (128 << 10);
486 static unsigned short *profile_hist
= NULL
;
487 static ut_reg profile_minpc
;
488 static ut_reg profile_maxpc
;
489 static int profile_shift
= 0; /* address shift amount */
492 /* The following are used to provide shortcuts to the required version
493 of host<->target copying. This avoids run-time conditionals, which
494 would slow the simulator throughput. */
495 typedef unsigned int (*fnptr_read_word
) PARAMS((unsigned char *memory
));
496 typedef unsigned int (*fnptr_swap_word
) PARAMS((unsigned int data
));
497 typedef uword64 (*fnptr_read_long
) PARAMS((unsigned char *memory
));
498 typedef uword64 (*fnptr_swap_long
) PARAMS((uword64 data
));
500 static fnptr_read_word host_read_word
;
501 static fnptr_read_long host_read_long
;
502 static fnptr_swap_word host_swap_word
;
503 static fnptr_swap_long host_swap_long
;
505 /*---------------------------------------------------------------------------*/
506 /*-- GDB simulator interface ------------------------------------------------*/
507 /*---------------------------------------------------------------------------*/
513 if (callback
== NULL
) {
514 fprintf(stderr
,"SIM Error: sim_open() called without callbacks attached\n");
518 /* The following ensures that the standard file handles for stdin,
519 stdout and stderr are initialised: */
520 callback
->init(callback
);
524 if (state
& simEXCEPTION
) {
525 fprintf(stderr
,"This simulator is not suitable for this host configuration\n");
531 if (*((char *)&data
) != 0x12)
532 state
|= simHOSTBE
; /* big-endian host */
536 /* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
537 and DOUBLE binary formats. This is a bit nasty, requiring that we
538 trust the explicit manifests held in the source: */
541 s
[state
& simHOSTBE
? 0 : 1] = 0x40805A5A;
542 s
[state
& simHOSTBE
? 1 : 0] = 0x00000000;
544 /* TODO: We need to cope with the simulated target and the host
545 not having the same endianness. This will require the high and
546 low words of a (double) to be swapped when converting between
547 the host and the simulated target. */
549 if (((float)4.01102924346923828125 != *(float *)(s
+ ((state
& simHOSTBE
) ? 0 : 1))) || ((double)523.2939453125 != *(double *)s
)) {
550 fprintf(stderr
,"The host executing the simulator does not seem to have IEEE 754-1985 std FP\n");
551 fprintf(stderr
,"*(float *)s = %.20f (4.01102924346923828125)\n",*(float *)s
);
552 fprintf(stderr
,"*(double *)s = %.20f (523.2939453125)\n",*(double *)s
);
558 /* This is NASTY, in that we are assuming the size of specific
562 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++) {
564 register_widths
[rn
] = GPRLEN
;
565 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ 32)))
566 register_widths
[rn
] = GPRLEN
;
567 else if ((rn
>= 33) && (rn
<= 37))
568 register_widths
[rn
] = GPRLEN
;
569 else if ((rn
== SRIDX
) || (rn
== FCR0IDX
) || (rn
== FCR31IDX
) || ((rn
>= 72) && (rn
<= 89)))
570 register_widths
[rn
] = 32;
572 register_widths
[rn
] = 0;
576 /* It would be good if we could select particular named MIPS
577 architecture simulators. However, having a pre-built, fixed
578 engine would mean including multiple engines. If the simulator is
579 changed to a run-time conditional version, then the ability to
580 select a particular architecture would be straightforward. */
586 static struct option cmdline
[] = {
590 {"profile", 0,0,'p'},
593 {"tracefile",1,0,'z'},
594 {"frequency",1,0,'y'},
595 {"samples", 1,0,'x'},
599 /* Unfortunately, getopt_long() is designed to be used with
600 vectors, where the first option is normally program name (and
601 ignored). We cheat by creating a dummy first argument, so that
602 we can use the standard argument processing. */
603 #define DUMMYARG "simulator "
604 cline
= (char *)malloc(strlen(args
) + strlen(DUMMYARG
) + 1);
606 fprintf(stderr
,"Failed to allocate memory for command line buffer\n");
609 sprintf(cline
,"%s%s",DUMMYARG
,args
);
610 argv
= buildargv(cline
);
611 for (argc
= 0; argv
[argc
]; argc
++);
613 /* Unfortunately, getopt_long() assumes that it is ignoring the
614 first argument (normally the program name). This means it
615 ignores the first option on our "args" line. */
616 optind
= 0; /* Force reset of argument processing */
618 int option_index
= 0;
620 c
= getopt_long(argc
,argv
,"hn:s:tp",cmdline
,&option_index
);
626 callback
->printf_filtered(callback
,"Usage:\n\t\
627 target sim [-h] [--log=<file>] [--name=<model>] [--size=<amount>]");
629 callback
->printf_filtered(callback
," [-t [--tracefile=<name>]]");
632 callback
->printf_filtered(callback
," [-p [--frequency=<count>] [--samples=<count>]]");
634 callback
->printf_filtered(callback
,"\n");
638 if (optarg
!= NULL
) {
640 tmp
= (char *)malloc(strlen(optarg
) + 1);
642 callback
->printf_filtered(callback
,"Failed to allocate buffer for logfile name \"%s\"\n",optarg
);
651 callback
->printf_filtered(callback
,"Explicit model selection not yet available (Ignoring \"%s\")\n",optarg
);
655 membank_size
= (unsigned)getnum(optarg
);
660 /* Eventually the simTRACE flag could be treated as a toggle, to
661 allow external control of the program points being traced
662 (i.e. only from main onwards, excluding the run-time setup,
667 Simulator constructed without tracing support (for performance).\n\
668 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
674 if (optarg
!= NULL
) {
676 tmp
= (char *)malloc(strlen(optarg
) + 1);
678 callback
->printf_filtered(callback
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
682 callback
->printf_filtered(callback
,"Placing trace information into file \"%s\"\n",tracefile
);
693 Simulator constructed without profiling support (for performance).\n\
694 Re-compile simulator with \"-DPROFILE\" to enable this option.\n");
695 #endif /* !PROFILE */
700 profile_nsamples
= (unsigned)getnum(optarg
);
706 sim_set_profile((int)getnum(optarg
));
711 callback
->printf_filtered(callback
,"Warning: Simulator getopt returned unrecognised code 0x%08X\n",c
);
719 callback
->printf_filtered(callback
,"Warning: Ignoring spurious non-option arguments ");
720 while (optind
< argc
)
721 callback
->printf_filtered(callback
,"\"%s\" ",argv
[optind
++]);
722 callback
->printf_filtered(callback
,"\n");
729 if (logfile
!= NULL
) {
730 if (strcmp(logfile
,"-") == 0)
733 logfh
= fopen(logfile
,"wb+");
735 callback
->printf_filtered(callback
,"Failed to create file \"%s\", writing log information to stderr.\n",tracefile
);
741 /* If the host has "mmap" available we could use it to provide a
742 very large virtual address space for the simulator, since memory
743 would only be allocated within the "mmap" space as it is
744 accessed. This can also be linked to the architecture specific
745 support, required to simulate the MMU. */
746 sim_size(membank_size
);
747 /* NOTE: The above will also have enabled any profiling state */
750 /* If we were providing a more complete I/O, co-processor or memory
751 simulation, we should perform any "device" initialisation at this
752 point. This can include pre-loading memory areas with particular
753 patterns (e.g. simulating ROM monitors). */
755 /* We can start writing to the memory, now that the processor has
757 monitor
= (unsigned char *)calloc(1,monitor_size
);
759 fprintf(stderr
,"Not enough VM for monitor simulation (%d bytes)\n",monitor_size
);
762 /* Entry into the IDT monitor is via fixed address vectors, and
763 not using machine instructions. To avoid clashing with use of
764 the MIPS TRAP system, we place our own (simulator specific)
765 "undefined" instructions into the relevant vector slots. */
766 for (loop
= 0; (loop
< monitor_size
); loop
+= 4) {
767 uword64 vaddr
= (monitor_base
+ loop
);
770 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
))
771 StoreMemory(cca
,AccessLength_WORD
,(RSVD_INSTRUCTION
| ((loop
>> 2) & RSVD_INSTRUCTION_AMASK
)),paddr
,vaddr
,isRAW
);
773 /* The PMON monitor uses the same address space, but rather than
774 branching into it the address of a routine is loaded. We can
775 cheat for the moment, and direct the PMON routine to IDT style
776 instructions within the monitor space. This relies on the IDT
777 monitor not using the locations from 0xBFC00500 onwards as its
779 for (loop
= 0; (loop
< 24); loop
++)
781 uword64 vaddr
= (monitor_base
+ 0x500 + (loop
* 4));
784 unsigned int value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
804 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
807 case 8: /* cliexit */
811 /* FIXME - should monitor_base be SIM_ADDR?? */
812 value
= ((unsigned int)monitor_base
+ (value
* 8));
813 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
))
814 StoreMemory(cca
,AccessLength_WORD
,value
,paddr
,vaddr
,isRAW
);
816 sim_error("Failed to write to monitor space 0x%08X%08X",WORD64HI(vaddr
),WORD64LO(vaddr
));
821 if (state
& simTRACE
) {
822 tracefh
= fopen(tracefile
,"wb+");
823 if (tracefh
== NULL
) {
824 sim_warning("Failed to create file \"%s\", writing trace information to stderr.",tracefile
);
833 /* For the profile writing, we write the data in the host
834 endianness. This unfortunately means we are assuming that the
835 profile file we create is processed on the same host executing the
836 simulator. The gmon.out file format should either have an explicit
837 endianness, or a method of encoding the endianness in the file
847 if (state
& simHOSTBE
) {
848 buff
[3] = ((val
>> 0) & 0xFF);
849 buff
[2] = ((val
>> 8) & 0xFF);
850 buff
[1] = ((val
>> 16) & 0xFF);
851 buff
[0] = ((val
>> 24) & 0xFF);
853 buff
[0] = ((val
>> 0) & 0xFF);
854 buff
[1] = ((val
>> 8) & 0xFF);
855 buff
[2] = ((val
>> 16) & 0xFF);
856 buff
[3] = ((val
>> 24) & 0xFF);
858 if (fwrite(buff
,4,1,fh
) != 1) {
859 sim_warning("Failed to write 4bytes to the profile file");
872 if (state
& simHOSTBE
) {
873 buff
[1] = ((val
>> 0) & 0xFF);
874 buff
[0] = ((val
>> 8) & 0xFF);
876 buff
[0] = ((val
>> 0) & 0xFF);
877 buff
[1] = ((val
>> 8) & 0xFF);
879 if (fwrite(buff
,2,1,fh
) != 1) {
880 sim_warning("Failed to write 2bytes to the profile file");
891 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
894 /* Cannot assume sim_kill() has been called */
895 /* "quitting" is non-zero if we cannot hang on errors */
897 /* Ensure that any resources allocated through the callback
898 mechanism are released: */
899 callback
->shutdown(callback
);
902 if ((state
& simPROFILE
) && (profile_hist
!= NULL
)) {
903 unsigned short *p
= profile_hist
;
904 FILE *pf
= fopen("gmon.out","wb");
908 sim_warning("Failed to open \"gmon.out\" profile file");
912 printf("DBG: minpc = 0x%08X\n",(unsigned int)profile_minpc
);
913 printf("DBG: maxpc = 0x%08X\n",(unsigned int)profile_maxpc
);
915 ok
= writeout32(pf
,(unsigned int)profile_minpc
);
917 ok
= writeout32(pf
,(unsigned int)profile_maxpc
);
919 ok
= writeout32(pf
,(profile_nsamples
* 2) + 12); /* size of sample buffer (+ header) */
921 printf("DBG: nsamples = %d (size = 0x%08X)\n",profile_nsamples
,((profile_nsamples
* 2) + 12));
923 for (loop
= 0; (ok
&& (loop
< profile_nsamples
)); loop
++) {
924 ok
= writeout16(pf
,profile_hist
[loop
]);
934 state
&= ~simPROFILE
;
939 if (tracefh
!= NULL
&& tracefh
!= stderr
)
945 if (logfh
!= NULL
&& logfh
!= stdout
&& logfh
!= stderr
)
950 free(membank
); /* cfree not available on all hosts */
957 sim_resume (step
,signal
)
961 printf("DBG: sim_resume entered: step = %d, signal = %d (membank = 0x%08X)\n",step
,signal
,membank
);
965 state
|= simSTEP
; /* execute only a single instruction */
967 state
&= ~(simSTOP
| simSTEP
); /* execute until event */
969 state
|= (simHALTEX
| simHALTIN
); /* treat interrupt event as exception */
971 /* Start executing instructions from the current state (set
972 explicitly by register updates, or by sim_create_inferior): */
979 sim_write (addr
,buffer
,size
)
981 unsigned char *buffer
;
985 uword64 vaddr
= (uword64
)addr
;
987 /* Return the number of bytes written, or zero if error. */
989 callback
->printf_filtered(callback
,"sim_write(0x%08X%08X,buffer,%d);\n",WORD64HI(addr
),WORD64LO(addr
),size
);
992 /* We provide raw read and write routines, since we do not want to
993 count the GDB memory accesses in our statistics gathering. */
995 /* There is a lot of code duplication in the individual blocks
996 below, but the variables are declared locally to a block to give
997 the optimiser the best chance of improving the code. We have to
998 perform slow byte reads from the host memory, to ensure that we
999 get the data into the correct endianness for the (simulated)
1000 target memory world. */
1002 /* Mask count to get odd byte, odd halfword, and odd word out of the
1003 way. We can then perform doubleword transfers to and from the
1004 simulator memory for optimum performance. */
1005 if (index
&& (index
& 1)) {
1008 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
)) {
1009 uword64 value
= ((uword64
)(*buffer
++));
1010 StoreMemory(cca
,AccessLength_BYTE
,value
,paddr
,vaddr
,isRAW
);
1013 index
&= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
1015 if (index
&& (index
& 2)) {
1018 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
)) {
1020 /* We need to perform the following magic to ensure that that
1021 bytes are written into same byte positions in the target memory
1022 world, regardless of the endianness of the host. */
1024 value
= ((uword64
)(*buffer
++) << 8);
1025 value
|= ((uword64
)(*buffer
++) << 0);
1027 value
= ((uword64
)(*buffer
++) << 0);
1028 value
|= ((uword64
)(*buffer
++) << 8);
1030 StoreMemory(cca
,AccessLength_HALFWORD
,value
,paddr
,vaddr
,isRAW
);
1035 if (index
&& (index
& 4)) {
1038 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
)) {
1041 value
= ((uword64
)(*buffer
++) << 24);
1042 value
|= ((uword64
)(*buffer
++) << 16);
1043 value
|= ((uword64
)(*buffer
++) << 8);
1044 value
|= ((uword64
)(*buffer
++) << 0);
1046 value
= ((uword64
)(*buffer
++) << 0);
1047 value
|= ((uword64
)(*buffer
++) << 8);
1048 value
|= ((uword64
)(*buffer
++) << 16);
1049 value
|= ((uword64
)(*buffer
++) << 24);
1051 StoreMemory(cca
,AccessLength_WORD
,value
,paddr
,vaddr
,isRAW
);
1056 for (;index
; index
-= 8) {
1059 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isRAW
)) {
1062 value
= ((uword64
)(*buffer
++) << 56);
1063 value
|= ((uword64
)(*buffer
++) << 48);
1064 value
|= ((uword64
)(*buffer
++) << 40);
1065 value
|= ((uword64
)(*buffer
++) << 32);
1066 value
|= ((uword64
)(*buffer
++) << 24);
1067 value
|= ((uword64
)(*buffer
++) << 16);
1068 value
|= ((uword64
)(*buffer
++) << 8);
1069 value
|= ((uword64
)(*buffer
++) << 0);
1071 value
= ((uword64
)(*buffer
++) << 0);
1072 value
|= ((uword64
)(*buffer
++) << 8);
1073 value
|= ((uword64
)(*buffer
++) << 16);
1074 value
|= ((uword64
)(*buffer
++) << 24);
1075 value
|= ((uword64
)(*buffer
++) << 32);
1076 value
|= ((uword64
)(*buffer
++) << 40);
1077 value
|= ((uword64
)(*buffer
++) << 48);
1078 value
|= ((uword64
)(*buffer
++) << 56);
1080 StoreMemory(cca
,AccessLength_DOUBLEWORD
,value
,paddr
,vaddr
,isRAW
);
1089 sim_read (addr
,buffer
,size
)
1091 unsigned char *buffer
;
1096 /* Return the number of bytes read, or zero if error. */
1098 callback
->printf_filtered(callback
,"sim_read(0x%08X%08X,buffer,%d);\n",WORD64HI(addr
),WORD64LO(addr
),size
);
1101 /* TODO: Perform same optimisation as the sim_write() code
1102 above. NOTE: This will require a bit more work since we will need
1103 to ensure that the source physical address is doubleword aligned
1104 before, and then deal with trailing bytes. */
1105 for (index
= 0; (index
< size
); index
++) {
1106 uword64 vaddr
,paddr
,value
;
1108 vaddr
= (uword64
)addr
+ index
;
1109 if (AddressTranslation(vaddr
,isDATA
,isLOAD
,&paddr
,&cca
,isTARGET
,isRAW
)) {
1110 value
= LoadMemory(cca
,AccessLength_BYTE
,paddr
,vaddr
,isDATA
,isRAW
);
1111 buffer
[index
] = (unsigned char)(value
&0xFF);
1120 sim_store_register (rn
,memory
)
1122 unsigned char *memory
;
1125 callback
->printf_filtered(callback
,"sim_store_register(%d,*memory=0x%08X%08X);\n",rn
,*((unsigned int *)memory
),*((unsigned int *)(memory
+ 4)));
1128 /* Unfortunately this suffers from the same problem as the register
1129 numbering one. We need to know what the width of each logical
1130 register number is for the architecture being simulated. */
1131 if (register_widths
[rn
] == 0)
1132 sim_warning("Invalid register width for %d (register store ignored)",rn
);
1134 if (register_widths
[rn
] == 32)
1135 registers
[rn
] = host_read_word(memory
);
1137 registers
[rn
] = host_read_long(memory
);
1144 sim_fetch_register (rn
,memory
)
1146 unsigned char *memory
;
1149 callback
->printf_filtered(callback
,"sim_fetch_register(%d=0x%08X%08X,mem) : place simulator registers into memory\n",rn
,WORD64HI(registers
[rn
]),WORD64LO(registers
[rn
]));
1152 if (register_widths
[rn
] == 0)
1153 sim_warning("Invalid register width for %d (register fetch ignored)",rn
);
1155 if (register_widths
[rn
] == 32)
1156 *((unsigned int *)memory
) = host_swap_word((unsigned int)(registers
[rn
] & 0xFFFFFFFF));
1157 else /* 64bit register */
1158 *((uword64
*)memory
) = host_swap_long(registers
[rn
]);
1164 sim_stop_reason (reason
,sigrc
)
1165 enum sim_stop
*reason
;
1168 /* We can have "*reason = {sim_exited, sim_stopped, sim_signalled}", so
1169 sim_exited *sigrc = argument to exit()
1170 sim_stopped *sigrc = exception number
1171 sim_signalled *sigrc = signal number
1173 if (state
& simEXCEPTION
) {
1174 /* If "sim_signalled" is used, GDB expects normal SIGNAL numbers,
1175 and not the MIPS specific exception codes. */
1177 /* For some reason, sending GDB a sim_signalled reason cause it to
1179 *reason
= sim_stopped
;
1181 *reason
= sim_signalled
;
1183 switch ((CAUSE
>> 2) & 0x1F) {
1185 *sigrc
= SIGINT
; /* wrong type of interrupt, but it will do for the moment */
1188 case TLBModification
:
1193 case InstructionFetch
:
1198 case ReservedInstruction
:
1199 case CoProcessorUnusable
:
1203 case IntegerOverflow
:
1215 default : /* Unknown internal exception */
1219 } else if (state
& simEXIT
) {
1221 printf("DBG: simEXIT (%d)\n",rcexit
);
1223 *reason
= sim_exited
;
1225 } else { /* assume single-stepping */
1226 *reason
= sim_stopped
;
1229 state
&= ~(simEXCEPTION
| simEXIT
);
1237 /* Accessed from the GDB "info files" command: */
1239 callback
->printf_filtered(callback
,"MIPS %d-bit simulator\n",(PROCESSOR_64BIT
? 64 : 32));
1241 callback
->printf_filtered(callback
,"%s endian memory model\n",(BigEndianMem
? "Big" : "Little"));
1243 callback
->printf_filtered(callback
,"0x%08X bytes of memory at 0x%08X%08X\n",(unsigned int)membank_size
,WORD64HI(membank_base
),WORD64LO(membank_base
));
1245 #if !defined(FASTSIM)
1246 if (instruction_fetch_overflow
!= 0)
1247 callback
->printf_filtered(callback
,"Instruction fetches = 0x%08X%08X\n",instruction_fetch_overflow
,instruction_fetches
);
1249 callback
->printf_filtered(callback
,"Instruction fetches = %d\n",instruction_fetches
);
1250 callback
->printf_filtered(callback
,"Pipeline ticks = %d\n",pipeline_ticks
);
1251 /* It would be a useful feature, if when performing multi-cycle
1252 simulations (rather than single-stepping) we keep the start and
1253 end times of the execution, so that we can give a performance
1254 figure for the simulator. */
1255 #endif /* !FASTSIM */
1257 /* print information pertaining to MIPS ISA and architecture being simulated */
1258 /* things that may be interesting */
1259 /* instructions executed - if available */
1260 /* cycles executed - if available */
1261 /* pipeline stalls - if available */
1262 /* virtual time taken */
1263 /* profiling size */
1264 /* profiling frequency */
1272 sim_load (prog
,from_tty
)
1276 /* Return non-zero if the caller should handle the load. Zero if
1277 we have loaded the image. */
1282 sim_create_inferior (start_address
,argv
,env
)
1283 SIM_ADDR start_address
;
1288 printf("DBG: sim_create_inferior entered: start_address = 0x%08X\n",start_address
);
1291 /* Prepare to execute the program to be simulated */
1292 /* argv and env are NULL terminated lists of pointers */
1295 PC
= (uword64
)start_address
;
1297 /* TODO: Sort this properly. SIM_ADDR may already be a 64bit value: */
1298 PC
= SIGNEXTEND(start_address
,32);
1300 /* NOTE: GDB normally sets the PC explicitly. However, this call is
1301 used by other clients of the simulator. */
1304 #if 0 /* def DEBUG */
1305 callback
->printf_filtered(callback
,"sim_create_inferior() : passed arguments ignored\n");
1308 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1309 printf("DBG: arg \"%s\"\n",*cptr
);
1312 /* We should really place the argv slot values into the argument
1313 registers, and onto the stack as required. However, this
1314 assumes that we have a stack defined, which is not necessarily
1315 true at the moment. */
1325 /* This routine should be for terminating any existing simulation
1326 thread. Since we are single-threaded only at the moment, this is
1327 not an issue. It should *NOT* be used to terminate the
1329 #else /* do *NOT* call sim_close */
1330 sim_close(1); /* Do not hang on errors */
1331 /* This would also be the point where any memory mapped areas used
1332 by the simulator should be released. */
1338 sim_get_quit_code ()
1340 /* The standard MIPS PCS (Procedure Calling Standard) uses V0(r2) as
1341 the function return value. However, it may be more correct for
1342 this to return the argument to the exit() function (if
1348 sim_set_callbacks (p
)
1355 typedef enum {e_terminate
,e_help
,e_setmemsize
,e_reset
} e_cmds
;
1357 static struct t_sim_command
{
1361 } sim_commands
[] = {
1362 {e_help
, "help", ": Show MIPS simulator private commands"},
1363 {e_setmemsize
,"set-memory-size","<n> : Specify amount of memory simulated"},
1364 {e_reset
, "reset-system", ": Reset the simulated processor"},
1369 sim_do_command (cmd
)
1372 struct t_sim_command
*cptr
;
1374 if (callback
== NULL
) {
1375 fprintf(stderr
,"Simulator not enabled: \"target sim\" should be used to activate\n");
1379 if (!(cmd
&& *cmd
!= '\0'))
1382 /* NOTE: Accessed from the GDB "sim" commmand: */
1383 for (cptr
= sim_commands
; cptr
&& cptr
->name
; cptr
++)
1384 if (strncmp(cmd
,cptr
->name
,strlen(cptr
->name
)) == 0) {
1385 cmd
+= strlen(cptr
->name
);
1387 case e_help
: /* no arguments */
1388 { /* no arguments */
1389 struct t_sim_command
*lptr
;
1390 callback
->printf_filtered(callback
,"List of MIPS simulator commands:\n");
1391 for (lptr
= sim_commands
; lptr
->name
; lptr
++)
1392 callback
->printf_filtered(callback
,"%s %s\n",lptr
->name
,lptr
->help
);
1396 case e_setmemsize
: /* memory size argument */
1398 unsigned int newsize
= (unsigned int)getnum(cmd
);
1403 case e_reset
: /* no arguments */
1405 /* NOTE: See the comments in sim_open() relating to device
1410 callback
->printf_filtered(callback
,"FATAL: Matched \"%s\", but failed to match command id %d.\n",cmd
,cptr
->id
);
1417 callback
->printf_filtered(callback
,"Error: \"%s\" is not a valid MIPS simulator command.\n",cmd
);
1422 /*---------------------------------------------------------------------------*/
1423 /* NOTE: The following routines do not seem to be used by GDB at the
1424 moment. However, they may be useful to the standalone simulator
1428 /* The profiling format is described in the "gmon_out.h" header file */
1433 #if defined(PROFILE)
1434 profile_frequency
= n
;
1435 state
|= simPROFILE
;
1436 #endif /* PROFILE */
1441 sim_set_profile_size (n
)
1444 #if defined(PROFILE)
1445 if (state
& simPROFILE
) {
1448 /* Since we KNOW that the memory banks are a power-of-2 in size: */
1449 profile_nsamples
= power2(n
);
1450 profile_minpc
= membank_base
;
1451 profile_maxpc
= (membank_base
+ membank_size
);
1453 /* Just in-case we are sampling every address: NOTE: The shift
1454 right of 2 is because we only have word-aligned PC addresses. */
1455 if (profile_nsamples
> (membank_size
>> 2))
1456 profile_nsamples
= (membank_size
>> 2);
1458 /* Since we are dealing with power-of-2 values: */
1459 profile_shift
= (((membank_size
>> 2) / profile_nsamples
) - 1);
1461 bsize
= (profile_nsamples
* sizeof(unsigned short));
1462 if (profile_hist
== NULL
)
1463 profile_hist
= (unsigned short *)calloc(64,(bsize
/ 64));
1465 profile_hist
= (unsigned short *)realloc(profile_hist
,bsize
);
1466 if (profile_hist
== NULL
) {
1467 sim_warning("Failed to allocate VM for profiling buffer (0x%08X bytes)",bsize
);
1468 state
&= ~simPROFILE
;
1471 #endif /* PROFILE */
1478 unsigned int newsize
;
1481 /* Used by "run", and internally, to set the simulated memory size */
1483 callback
->printf_filtered(callback
,"Zero not valid: Memory size still 0x%08X bytes\n",membank_size
);
1486 newsize
= power2(newsize
);
1487 if (membank
== NULL
)
1488 new = (char *)calloc(64,(membank_size
/ 64));
1490 new = (char *)realloc(membank
,newsize
);
1492 if (membank
== NULL
)
1493 sim_error("Not enough VM for simulation memory of 0x%08X bytes",membank_size
);
1495 sim_warning("Failed to resize memory (still 0x%08X bytes)",membank_size
);
1497 membank_size
= (unsigned)newsize
;
1499 #if defined(PROFILE)
1500 /* Ensure that we sample across the new memory range */
1501 sim_set_profile_size(profile_nsamples
);
1502 #endif /* PROFILE */
1511 /* This routine is called by the "run" program, when detailed
1512 execution information is required. Rather than executing a single
1513 instruction, and looping around externally... we just start
1514 simulating, returning TRUE when the simulator stops (for whatever
1518 /* Ensure tracing is enabled, if available */
1519 if (tracefh
!= NULL
)
1523 state
&= ~(simSTOP
| simSTEP
); /* execute until event */
1524 state
|= (simHALTEX
| simHALTIN
); /* treat interrupt event as exception */
1525 /* Start executing instructions from the current state (set
1526 explicitly by register updates, or by sim_create_inferior): */
1532 /*---------------------------------------------------------------------------*/
1533 /*-- Private simulator support interface ------------------------------------*/
1534 /*---------------------------------------------------------------------------*/
1536 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1539 unsigned int reason
;
1541 /* The IDT monitor actually allows two instructions per vector
1542 slot. However, the simulator currently causes a trap on each
1543 individual instruction. We cheat, and lose the bottom bit. */
1546 /* The following callback functions are available, however the
1547 monitor we are simulating does not make use of them: get_errno,
1548 isatty, lseek, rename, system, time and unlink */
1550 case 6: /* int open(char *path,int flags) */
1554 if (AddressTranslation(A0
,isDATA
,isLOAD
,&paddr
,&cca
,isHOST
,isREAL
))
1555 V0
= callback
->open(callback
,(char *)((int)paddr
),(int)A1
);
1557 sim_error("Attempt to pass pointer that does not reference simulated memory");
1561 case 7: /* int read(int file,char *ptr,int len) */
1565 if (AddressTranslation(A1
,isDATA
,isLOAD
,&paddr
,&cca
,isHOST
,isREAL
))
1566 V0
= callback
->read(callback
,(int)A0
,(char *)((int)paddr
),(int)A2
);
1568 sim_error("Attempt to pass pointer that does not reference simulated memory");
1572 case 8: /* int write(int file,char *ptr,int len) */
1576 if (AddressTranslation(A1
,isDATA
,isLOAD
,&paddr
,&cca
,isHOST
,isREAL
))
1577 V0
= callback
->write(callback
,(int)A0
,(const char *)((int)paddr
),(int)A2
);
1579 sim_error("Attempt to pass pointer that does not reference simulated memory");
1583 case 10: /* int close(int file) */
1584 V0
= callback
->close(callback
,(int)A0
);
1587 case 11: /* char inbyte(void) */
1590 if (callback
->read_stdin(callback
,&tmp
,sizeof(char)) != sizeof(char)) {
1591 sim_error("Invalid return from character read");
1599 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1601 char tmp
= (char)(A0
& 0xFF);
1602 callback
->write_stdout(callback
,&tmp
,sizeof(char));
1606 case 17: /* void _exit() */
1607 sim_warning("sim_monitor(17): _exit(int reason) to be coded");
1608 state
|= (simSTOP
| simEXIT
); /* stop executing code */
1609 rcexit
= (unsigned int)(A0
& 0xFFFFFFFF);
1612 case 55: /* void get_mem_info(unsigned int *ptr) */
1613 /* in: A0 = pointer to three word memory location */
1614 /* out: [A0 + 0] = size */
1615 /* [A0 + 4] = instruction cache size */
1616 /* [A0 + 8] = data cache size */
1619 uword64 paddr
, value
;
1623 /* NOTE: We use RAW memory writes here, but since we are not
1624 gathering statistics for the monitor calls we are simulating,
1625 it is not an issue. */
1628 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isREAL
)) {
1629 value
= (uword64
)membank_size
;
1630 StoreMemory(cca
,AccessLength_WORD
,value
,paddr
,vaddr
,isRAW
);
1631 /* We re-do the address translations, in-case the block
1632 overlaps a memory boundary: */
1634 vaddr
+= (AccessLength_WORD
+ 1);
1635 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isREAL
)) {
1636 StoreMemory(cca
,AccessLength_WORD
,value
,paddr
,vaddr
,isRAW
);
1637 vaddr
+= (AccessLength_WORD
+ 1);
1638 if (AddressTranslation(vaddr
,isDATA
,isSTORE
,&paddr
,&cca
,isTARGET
,isREAL
))
1639 StoreMemory(cca
,AccessLength_WORD
,value
,paddr
,vaddr
,isRAW
);
1648 sim_error("Invalid pointer passed into monitor call");
1652 case 158 : /* PMON printf */
1653 /* in: A0 = pointer to format string */
1654 /* A1 = optional argument 1 */
1655 /* A2 = optional argument 2 */
1656 /* A3 = optional argument 3 */
1658 /* The following is based on the PMON printf source */
1662 /* This isn't the quickest way, since we call the host print
1663 routine for every character almost. But it does avoid
1664 having to allocate and manage a temporary string buffer. */
1665 if (AddressTranslation(A0
,isDATA
,isLOAD
,&paddr
,&cca
,isHOST
,isREAL
)) {
1666 char *s
= (char *)((int)paddr
);
1667 ut_reg
*ap
= &A1
; /* 1st argument */
1668 /* TODO: Include check that we only use three arguments (A1, A2 and A3) */
1672 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1673 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1677 if (strchr ("dobxXulscefg%", *s
))
1685 else if (*s
== '*') {
1690 } else if (*s
>= '1' && *s
<= '9') {
1693 for (t
= s
; isdigit (*s
); s
++);
1694 strncpy (tmp
, t
, s
- t
);
1696 n
= (unsigned int)strtol(tmp
,NULL
,10);
1702 } else if (*s
== '.')
1706 callback
->printf_filtered(callback
,"%%");
1707 } else if (*s
== 's') {
1708 if ((int)*ap
!= 0) {
1709 if (AddressTranslation(*ap
++,isDATA
,isLOAD
,&paddr
,&cca
,isHOST
,isREAL
)) {
1710 char *p
= (char *)((int)paddr
);;
1711 callback
->printf_filtered(callback
,p
);
1714 sim_error("Attempt to pass pointer that does not reference simulated memory");
1718 callback
->printf_filtered(callback
,"(null)");
1719 } else if (*s
== 'c') {
1721 callback
->printf_filtered(callback
,"%c",n
);
1729 if (strchr ("dobxXu", *s
)) {
1730 word64 lv
= (word64
) *ap
++;
1732 callback
->printf_filtered(callback
,"<binary not supported>");
1734 sprintf(tmp
,"%%%s%c",longlong
? "ll" : "",*s
);
1736 callback
->printf_filtered(callback
,tmp
,lv
);
1738 callback
->printf_filtered(callback
,tmp
,(int)lv
);
1740 } else if (strchr ("eEfgG", *s
)) {
1741 #ifdef _MSC_VER /* MSVC version 2.x can't convert from uword64 directly */
1742 double dbl
= (double)((word64
)*ap
++);
1744 double dbl
= (double)*ap
++;
1746 sprintf(tmp
,"%%%d.%d%c",width
,trunc
,*s
);
1747 callback
->printf_filtered(callback
,tmp
,dbl
);
1753 callback
->printf_filtered(callback
,"%c",*s
++);
1756 sim_error("Attempt to pass pointer that does not reference simulated memory");
1761 sim_warning("TODO: sim_monitor(%d) : PC = 0x%08X%08X",reason
,WORD64HI(IPC
),WORD64LO(IPC
));
1762 sim_warning("(Arguments : A0 = 0x%08X%08X : A1 = 0x%08X%08X : A2 = 0x%08X%08X : A3 = 0x%08X%08X)",WORD64HI(A0
),WORD64LO(A0
),WORD64HI(A1
),WORD64LO(A1
),WORD64HI(A2
),WORD64LO(A2
),WORD64HI(A3
),WORD64LO(A3
));
1770 sim_warning(char *fmt
,...)
1778 if (logfh
!= NULL
) {
1780 fprintf(logfh
,"SIM Warning: ");
1781 fprintf(logfh
,fmt
,ap
);
1782 fprintf(logfh
,"\n");
1783 #else /* we should provide a method of routing log messages to the simulator output stream */
1784 callback
->printf_filtered(callback
,"SIM Warning: ");
1785 callback
->printf_filtered(callback
,fmt
,ap
);
1789 SignalException(SimulatorFault
,"");
1795 sim_error(char *fmt
,...)
1803 callback
->printf_filtered(callback
,"SIM Error: ");
1804 callback
->printf_filtered(callback
,fmt
,ap
);
1806 SignalException(SimulatorFault
,"");
1816 /* Round *UP* to the nearest power-of-2 if not already one */
1817 if (value
!= (value
& ~(value
- 1))) {
1818 for (tmp
= value
, loop
= 0; (tmp
!= 0); loop
++)
1820 value
= (1 << loop
);
1833 num
= strtol(value
,&end
,10);
1835 callback
->printf_filtered(callback
,"Warning: Invalid number \"%s\" ignored, using zero\n",value
);
1837 if (*end
&& ((tolower(*end
) == 'k') || (tolower(*end
) == 'm'))) {
1838 if (tolower(*end
) == 'k')
1845 callback
->printf_filtered(callback
,"Warning: Spurious characters \"%s\" at end of number ignored\n",end
);
1851 /*-- trace support ----------------------------------------------------------*/
1853 /* The TRACE support is provided (if required) in the memory accessing
1854 routines. Since we are also providing the architecture specific
1855 features, the architecture simulation code can also deal with
1856 notifying the TRACE world of cache flushes, etc. Similarly we do
1857 not need to provide profiling support in the simulator engine,
1858 since we can sample in the instruction fetch control loop. By
1859 defining the TRACE manifest, we add tracing as a run-time
1863 /* Tracing by default produces "din" format (as required by
1864 dineroIII). Each line of such a trace file *MUST* have a din label
1865 and address field. The rest of the line is ignored, so comments can
1866 be included if desired. The first field is the label which must be
1867 one of the following values:
1872 3 escape record (treated as unknown access type)
1873 4 escape record (causes cache flush)
1875 The address field is a 32bit (lower-case) hexadecimal address
1876 value. The address should *NOT* be preceded by "0x".
1878 The size of the memory transfer is not important when dealing with
1879 cache lines (as long as no more than a cache line can be
1880 transferred in a single operation :-), however more information
1881 could be given following the dineroIII requirement to allow more
1882 complete memory and cache simulators to provide better
1883 results. i.e. the University of Pisa has a cache simulator that can
1884 also take bus size and speed as (variable) inputs to calculate
1885 complete system performance (a much more useful ability when trying
1886 to construct an end product, rather than a processor). They
1887 currently have an ARM version of their tool called ChARM. */
1892 void dotrace(FILE *tracefh
,int type
,SIM_ADDR address
,int width
,char *comment
,...)
1894 void dotrace(tracefh
,type
,address
,width
,comment
)
1902 if (state
& simTRACE
) {
1904 fprintf(tracefh
,"%d %08x%08x ; width %d ; ",
1905 type
,(unsigned long)(address
>>32),(unsigned long)(address
&0xffffffff),width
);
1906 va_start(ap
,comment
);
1907 fprintf(tracefh
,comment
,ap
);
1909 fprintf(tracefh
,"\n");
1911 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1912 we may be generating 64bit ones, we should put the hi-32bits of the
1913 address into the comment field. */
1915 /* TODO: Provide a buffer for the trace lines. We can then avoid
1916 performing writes until the buffer is filled, or the file is
1919 /* NOTE: We could consider adding a comment field to the "din" file
1920 produced using type 3 markers (unknown access). This would then
1921 allow information about the program that the "din" is for, and
1922 the MIPs world that was being simulated, to be placed into the
1929 /*---------------------------------------------------------------------------*/
1930 /*-- host<->target transfers ------------------------------------------------*/
1931 /*---------------------------------------------------------------------------*/
1932 /* The following routines allow conditionals to be avoided during the
1933 simulation, at the cost of increasing the image and source size. */
1937 xfer_direct_word(unsigned char *memory
)
1939 xfer_direct_word(memory
)
1940 unsigned char *memory
;
1943 return *((unsigned int *)memory
);
1948 xfer_direct_long(unsigned char *memory
)
1950 xfer_direct_long(memory
)
1951 unsigned char *memory
;
1954 return *((uword64
*)memory
);
1959 swap_direct_word(unsigned int data
)
1961 swap_direct_word(data
)
1970 swap_direct_long(uword64 data
)
1972 swap_direct_long(data
)
1981 xfer_big_word(unsigned char *memory
)
1983 xfer_big_word(memory
)
1984 unsigned char *memory
;
1987 return ((memory
[0] << 24) | (memory
[1] << 16) | (memory
[2] << 8) | memory
[3]);
1992 xfer_big_long(unsigned char *memory
)
1994 xfer_big_long(memory
)
1995 unsigned char *memory
;
1998 return (((uword64
)memory
[0] << 56) | ((uword64
)memory
[1] << 48)
1999 | ((uword64
)memory
[2] << 40) | ((uword64
)memory
[3] << 32)
2000 | ((uword64
)memory
[4] << 24) | ((uword64
)memory
[5] << 16)
2001 | ((uword64
)memory
[6] << 8) | ((uword64
)memory
[7]));
2006 xfer_little_word(unsigned char *memory
)
2008 xfer_little_word(memory
)
2009 unsigned char *memory
;
2012 return ((memory
[3] << 24) | (memory
[2] << 16) | (memory
[1] << 8) | memory
[0]);
2017 xfer_little_long(unsigned char *memory
)
2019 xfer_little_long(memory
)
2020 unsigned char *memory
;
2023 return (((uword64
)memory
[7] << 56) | ((uword64
)memory
[6] << 48)
2024 | ((uword64
)memory
[5] << 40) | ((uword64
)memory
[4] << 32)
2025 | ((uword64
)memory
[3] << 24) | ((uword64
)memory
[2] << 16)
2026 | ((uword64
)memory
[1] << 8) | (uword64
)memory
[0]);
2031 swap_word(unsigned int data
)
2037 unsigned int result
;
2038 result
= data
^ ((data
<< 16) | (data
>> 16));
2039 result
&= ~0x00FF0000;
2040 data
= (data
<< 24) | (data
>> 8);
2041 return data
^ (result
>> 8);
2046 swap_long(uword64 data
)
2052 unsigned int tmphi
= WORD64HI(data
);
2053 unsigned int tmplo
= WORD64LO(data
);
2054 tmphi
= swap_word(tmphi
);
2055 tmplo
= swap_word(tmplo
);
2056 /* Now swap the HI and LO parts */
2057 return SET64LO(tmphi
) | SET64HI(tmplo
);
2060 /*---------------------------------------------------------------------------*/
2061 /*-- simulator engine -------------------------------------------------------*/
2062 /*---------------------------------------------------------------------------*/
2067 /* RESET: Fixed PC address: */
2068 PC
= (((uword64
)0xFFFFFFFF<<32) | 0xBFC00000);
2069 /* The reset vector address is in the unmapped, uncached memory space. */
2071 SR
&= ~(status_SR
| status_TS
| status_RP
);
2072 SR
|= (status_ERL
| status_BEV
);
2073 /* VR4300 starts in Big-Endian mode */
2074 CONFIG
&= ~(config_EP_mask
<< config_EP_shift
);
2075 CONFIG
|= ((config_EP_D
<< config_EP_shift
) | config_BE
);
2076 /* TODO: The VR4300 CONFIG register is not modelled fully at the moment */
2078 #if defined(HASFPU) && (GPRLEN == (64))
2079 /* Cheat and allow access to the complete register set immediately: */
2080 SR
|= status_FR
; /* 64bit registers */
2081 #endif /* HASFPU and 64bit FP registers */
2083 /* Ensure that any instructions with pending register updates are
2087 for (loop
= 0; (loop
< PSLOTS
); loop
++)
2088 pending_slot_reg
[loop
] = (LAST_EMBED_REGNUM
+ 1);
2089 pending_in
= pending_out
= pending_total
= 0;
2093 /* Initialise the FPU registers to the unknown state */
2096 for (rn
= 0; (rn
< 32); rn
++)
2097 fpr_state
[rn
] = fmt_uninterpreted
;
2101 /* In reality this check should be performed at various points
2102 within the simulation, since it is possible to change the
2103 endianness of user programs. However, we perform the check here
2104 to ensure that the start-of-day values agree: */
2105 state
|= (BigEndianCPU
? simBE
: 0);
2106 if ((target_byte_order
== 1234) != !(state
& simBE
)) {
2107 fprintf(stderr
,"ColdReset: GDB (%s) and simulator (%s) do not agree on target endianness\n",
2108 target_byte_order
== 1234 ? "little" : "big",
2109 state
& simBE
? "big" : "little");
2113 if (!(state
& simHOSTBE
) == !(state
& simBE
)) {
2114 host_read_word
= xfer_direct_word
;
2115 host_read_long
= xfer_direct_long
;
2116 host_swap_word
= swap_direct_word
;
2117 host_swap_long
= swap_direct_long
;
2118 } else if (state
& simHOSTBE
) {
2119 host_read_word
= xfer_little_word
;
2120 host_read_long
= xfer_little_long
;
2121 host_swap_word
= swap_word
;
2122 host_swap_long
= swap_long
;
2123 } else { /* HOST little-endian */
2124 host_read_word
= xfer_big_word
;
2125 host_read_long
= xfer_big_long
;
2126 host_swap_word
= swap_word
;
2127 host_swap_long
= swap_long
;
2133 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2134 /* Translate a virtual address to a physical address and cache
2135 coherence algorithm describing the mechanism used to resolve the
2136 memory reference. Given the virtual address vAddr, and whether the
2137 reference is to Instructions ot Data (IorD), find the corresponding
2138 physical address (pAddr) and the cache coherence algorithm (CCA)
2139 used to resolve the reference. If the virtual address is in one of
2140 the unmapped address spaces the physical address and the CCA are
2141 determined directly by the virtual address. If the virtual address
2142 is in one of the mapped address spaces then the TLB is used to
2143 determine the physical address and access type; if the required
2144 translation is not present in the TLB or the desired access is not
2145 permitted the function fails and an exception is taken.
2147 NOTE: This function is extended to return an exception state. This,
2148 along with the exception generation is used to notify whether a
2149 valid address translation occured */
2152 AddressTranslation(vAddr
,IorD
,LorS
,pAddr
,CCA
,host
,raw
)
2161 int res
= -1; /* TRUE : Assume good return */
2164 callback
->printf_filtered(callback
,"AddressTranslation(0x%08X%08X,%s,%s,...);\n",WORD64HI(vAddr
),WORD64LO(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(LorS
? "iSTORE" : "isLOAD"));
2167 /* Check that the address is valid for this memory model */
2169 /* For a simple (flat) memory model, we simply pass virtual
2170 addressess through (mostly) unchanged. */
2171 vAddr
&= 0xFFFFFFFF;
2173 /* Treat the kernel memory spaces identically for the moment: */
2174 if ((membank_base
== K1BASE
) && (vAddr
>= K0BASE
) && (vAddr
< (K0BASE
+ K0SIZE
)))
2175 vAddr
+= (K1BASE
- K0BASE
);
2177 /* Also assume that the K1BASE memory wraps. This is required to
2178 allow the PMON run-time __sizemem() routine to function (without
2179 having to provide exception simulation). NOTE: A kludge to work
2180 around the fact that the monitor memory is currently held in the
2182 if (((vAddr
< monitor_base
) || (vAddr
>= (monitor_base
+ monitor_size
))) && (vAddr
>= K1BASE
&& vAddr
< (K1BASE
+ K1SIZE
)))
2183 vAddr
= (K1BASE
| (vAddr
& (membank_size
- 1)));
2185 *pAddr
= vAddr
; /* default for isTARGET */
2186 *CCA
= Uncached
; /* not used for isHOST */
2188 /* NOTE: This is a duplicate of the code that appears in the
2189 LoadMemory and StoreMemory functions. They should be merged into
2190 a single function (that can be in-lined if required). */
2191 if ((vAddr
>= membank_base
) && (vAddr
< (membank_base
+ membank_size
))) {
2193 *pAddr
= (int)&membank
[((unsigned int)(vAddr
- membank_base
) & (membank_size
- 1))];
2194 } else if ((vAddr
>= monitor_base
) && (vAddr
< (monitor_base
+ monitor_size
))) {
2196 *pAddr
= (int)&monitor
[((unsigned int)(vAddr
- monitor_base
) & (monitor_size
- 1))];
2198 #if 1 /* def DEBUG */
2199 sim_warning("Failed: AddressTranslation(0x%08X%08X,%s,%s,...) IPC = 0x%08X%08X",WORD64HI(vAddr
),WORD64LO(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(LorS
? "isSTORE" : "isLOAD"),WORD64HI(IPC
),WORD64LO(IPC
));
2201 res
= 0; /* AddressTranslation has failed */
2202 *pAddr
= (SIM_ADDR
)-1;
2203 if (!raw
) /* only generate exceptions on real memory transfers */
2204 SignalException((LorS
== isSTORE
) ? AddressStore
: AddressLoad
);
2206 sim_warning("AddressTranslation for %s %s from 0x%08X%08X failed",(IorD
? "data" : "instruction"),(LorS
? "store" : "load"),WORD64HI(vAddr
),WORD64LO(vAddr
));
2212 /* Description from page A-23 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2213 /* Prefetch data from memory. Prefetch is an advisory instruction for
2214 which an implementation specific action is taken. The action taken
2215 may increase performance, but must not change the meaning of the
2216 program, or alter architecturally-visible state. */
2218 Prefetch(CCA
,pAddr
,vAddr
,DATA
,hint
)
2226 callback
->printf_filtered(callback
,"Prefetch(%d,0x%08X%08X,0x%08X%08X,%d,%d);\n",CCA
,WORD64HI(pAddr
),WORD64LO(pAddr
),WORD64HI(vAddr
),WORD64LO(vAddr
),DATA
,hint
);
2229 /* For our simple memory model we do nothing */
2233 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2234 /* Load a value from memory. Use the cache and main memory as
2235 specified in the Cache Coherence Algorithm (CCA) and the sort of
2236 access (IorD) to find the contents of AccessLength memory bytes
2237 starting at physical location pAddr. The data is returned in the
2238 fixed width naturally-aligned memory element (MemElem). The
2239 low-order two (or three) bits of the address and the AccessLength
2240 indicate which of the bytes within MemElem needs to be given to the
2241 processor. If the memory access type of the reference is uncached
2242 then only the referenced bytes are read from memory and valid
2243 within the memory element. If the access type is cached, and the
2244 data is not present in cache, an implementation specific size and
2245 alignment block of memory is read and loaded into the cache to
2246 satisfy a load reference. At a minimum, the block is the entire
2249 LoadMemory(CCA
,AccessLength
,pAddr
,vAddr
,IorD
,raw
)
2260 if (membank
== NULL
)
2261 callback
->printf_filtered(callback
,"DBG: LoadMemory(%d,%d,0x%08X%08X,0x%08X%08X,%s,%s)\n",CCA
,AccessLength
,WORD64HI(pAddr
),WORD64LO(pAddr
),WORD64HI(vAddr
),WORD64LO(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(raw
? "isRAW" : "isREAL"));
2264 #if defined(WARN_MEM)
2265 if (CCA
!= uncached
)
2266 sim_warning("LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA
);
2268 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
) {
2269 /* In reality this should be a Bus Error */
2270 sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%08X%08X\n",AccessLength
,(LOADDRMASK
+ 1)<<2,WORD64HI(pAddr
),WORD64LO(pAddr
));
2272 #endif /* WARN_MEM */
2274 /* Decide which physical memory locations are being dealt with. At
2275 this point we should be able to split the pAddr bits into the
2276 relevant address map being simulated. If the "raw" variable is
2277 set, the memory read being performed should *NOT* update any I/O
2278 state or affect the CPU state. This also includes avoiding
2279 affecting statistics gathering. */
2281 /* If instruction fetch then we need to check that the two lo-order
2282 bits are zero, otherwise raise a InstructionFetch exception: */
2283 if ((IorD
== isINSTRUCTION
) && ((pAddr
& 0x3) != 0))
2284 SignalException(InstructionFetch
);
2287 unsigned char *mem
= NULL
;
2291 dotrace(tracefh
,((IorD
== isDATA
) ? 0 : 2),(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"load%s",((IorD
== isDATA
) ? "" : " instruction"));
2294 /* NOTE: Quicker methods of decoding the address space can be used
2295 when a real memory map is being simulated (i.e. using hi-order
2296 address bits to select device). */
2297 if ((pAddr
>= membank_base
) && (pAddr
< (membank_base
+ membank_size
))) {
2298 index
= ((unsigned int)(pAddr
- membank_base
) & (membank_size
- 1));
2300 } else if ((pAddr
>= monitor_base
) && (pAddr
< (monitor_base
+ monitor_size
))) {
2301 index
= ((unsigned int)(pAddr
- monitor_base
) & (monitor_size
- 1));
2305 sim_error("Simulator memory not found for physical address 0x%08X%08X\n",WORD64HI(pAddr
),WORD64LO(pAddr
));
2307 /* If we obtained the endianness of the host, and it is the same
2308 as the target memory system we can optimise the memory
2309 accesses. However, without that information we must perform
2310 slow transfer, and hope that the compiler optimisation will
2311 merge successive loads. */
2312 value
= 0; /* no data loaded yet */
2314 /* In reality we should always be loading a doubleword value (or
2315 word value in 32bit memory worlds). The external code then
2316 extracts the required bytes. However, to keep performance
2317 high we only load the required bytes into the relevant
2320 switch (AccessLength
) { /* big-endian memory */
2321 case AccessLength_DOUBLEWORD
:
2322 value
|= ((uword64
)mem
[index
++] << 56);
2323 case AccessLength_SEPTIBYTE
:
2324 value
|= ((uword64
)mem
[index
++] << 48);
2325 case AccessLength_SEXTIBYTE
:
2326 value
|= ((uword64
)mem
[index
++] << 40);
2327 case AccessLength_QUINTIBYTE
:
2328 value
|= ((uword64
)mem
[index
++] << 32);
2329 case AccessLength_WORD
:
2330 value
|= ((unsigned int)mem
[index
++] << 24);
2331 case AccessLength_TRIPLEBYTE
:
2332 value
|= ((unsigned int)mem
[index
++] << 16);
2333 case AccessLength_HALFWORD
:
2334 value
|= ((unsigned int)mem
[index
++] << 8);
2335 case AccessLength_BYTE
:
2336 value
|= mem
[index
];
2340 index
+= (AccessLength
+ 1);
2341 switch (AccessLength
) { /* little-endian memory */
2342 case AccessLength_DOUBLEWORD
:
2343 value
|= ((uword64
)mem
[--index
] << 56);
2344 case AccessLength_SEPTIBYTE
:
2345 value
|= ((uword64
)mem
[--index
] << 48);
2346 case AccessLength_SEXTIBYTE
:
2347 value
|= ((uword64
)mem
[--index
] << 40);
2348 case AccessLength_QUINTIBYTE
:
2349 value
|= ((uword64
)mem
[--index
] << 32);
2350 case AccessLength_WORD
:
2351 value
|= ((uword64
)mem
[--index
] << 24);
2352 case AccessLength_TRIPLEBYTE
:
2353 value
|= ((uword64
)mem
[--index
] << 16);
2354 case AccessLength_HALFWORD
:
2355 value
|= ((uword64
)mem
[--index
] << 8);
2356 case AccessLength_BYTE
:
2357 value
|= ((uword64
)mem
[--index
] << 0);
2363 printf("DBG: LoadMemory() : (offset %d) : value = 0x%08X%08X\n",(int)(pAddr
& LOADDRMASK
),WORD64HI(value
),WORD64LO(value
));
2366 /* TODO: We could try and avoid the shifts when dealing with raw
2367 memory accesses. This would mean updating the LoadMemory and
2368 StoreMemory routines to avoid shifting the data before
2369 returning or using it. */
2370 if (!raw
) { /* do nothing for raw accessess */
2372 value
<<= (((7 - (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
2373 else /* little-endian only needs to be shifted up to the correct byte offset */
2374 value
<<= ((pAddr
& LOADDRMASK
) * 8);
2378 printf("DBG: LoadMemory() : shifted value = 0x%08X%08X\n",WORD64HI(value
),WORD64LO(value
));
2386 /* Description from page A-23 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2387 /* Store a value to memory. The specified data is stored into the
2388 physical location pAddr using the memory hierarchy (data caches and
2389 main memory) as specified by the Cache Coherence Algorithm
2390 (CCA). The MemElem contains the data for an aligned, fixed-width
2391 memory element (word for 32-bit processors, doubleword for 64-bit
2392 processors), though only the bytes that will actually be stored to
2393 memory need to be valid. The low-order two (or three) bits of pAddr
2394 and the AccessLength field indicates which of the bytes within the
2395 MemElem data should actually be stored; only these bytes in memory
2398 StoreMemory(CCA
,AccessLength
,MemElem
,pAddr
,vAddr
,raw
)
2407 callback
->printf_filtered(callback
,"DBG: StoreMemory(%d,%d,0x%08X%08X,0x%08X%08X,0x%08X%08X,%s)\n",CCA
,AccessLength
,WORD64HI(MemElem
),WORD64LO(MemElem
),WORD64HI(pAddr
),WORD64LO(pAddr
),WORD64HI(vAddr
),WORD64LO(vAddr
),(raw
? "isRAW" : "isREAL"));
2410 #if defined(WARN_MEM)
2411 if (CCA
!= uncached
)
2412 sim_warning("StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA
);
2414 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
2415 sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%08X%08X\n",AccessLength
,(LOADDRMASK
+ 1)<<2,WORD64HI(pAddr
),WORD64LO(pAddr
));
2416 #endif /* WARN_MEM */
2420 dotrace(tracefh
,1,(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"store");
2423 /* See the comments in the LoadMemory routine about optimising
2424 memory accesses. Also if we wanted to make the simulator smaller,
2425 we could merge a lot of this code with the LoadMemory
2426 routine. However, this would slow the simulator down with
2427 run-time conditionals. */
2430 unsigned char *mem
= NULL
;
2432 if ((pAddr
>= membank_base
) && (pAddr
< (membank_base
+ membank_size
))) {
2433 index
= ((unsigned int)(pAddr
- membank_base
) & (membank_size
- 1));
2435 } else if ((pAddr
>= monitor_base
) && (pAddr
< (monitor_base
+ monitor_size
))) {
2436 index
= ((unsigned int)(pAddr
- monitor_base
) & (monitor_size
- 1));
2441 sim_error("Simulator memory not found for physical address 0x%08X%08X\n",WORD64HI(pAddr
),WORD64LO(pAddr
));
2446 printf("DBG: StoreMemory: offset = %d MemElem = 0x%08X%08X\n",(unsigned int)(pAddr
& LOADDRMASK
),WORD64HI(MemElem
),WORD64LO(MemElem
));
2451 shift
= ((7 - AccessLength
) * 8);
2452 else /* real memory access */
2453 shift
= ((pAddr
& LOADDRMASK
) * 8);
2456 /* no need to shift raw little-endian data */
2458 MemElem
>>= ((pAddr
& LOADDRMASK
) * 8);
2462 printf("DBG: StoreMemory: shift = %d MemElem = 0x%08X%08X\n",shift
,WORD64HI(MemElem
),WORD64LO(MemElem
));
2466 switch (AccessLength
) { /* big-endian memory */
2467 case AccessLength_DOUBLEWORD
:
2468 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2470 case AccessLength_SEPTIBYTE
:
2471 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2473 case AccessLength_SEXTIBYTE
:
2474 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2476 case AccessLength_QUINTIBYTE
:
2477 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2479 case AccessLength_WORD
:
2480 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2482 case AccessLength_TRIPLEBYTE
:
2483 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2485 case AccessLength_HALFWORD
:
2486 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2488 case AccessLength_BYTE
:
2489 mem
[index
++] = (unsigned char)(MemElem
>> 56);
2493 index
+= (AccessLength
+ 1);
2494 switch (AccessLength
) { /* little-endian memory */
2495 case AccessLength_DOUBLEWORD
:
2496 mem
[--index
] = (unsigned char)(MemElem
>> 56);
2497 case AccessLength_SEPTIBYTE
:
2498 mem
[--index
] = (unsigned char)(MemElem
>> 48);
2499 case AccessLength_SEXTIBYTE
:
2500 mem
[--index
] = (unsigned char)(MemElem
>> 40);
2501 case AccessLength_QUINTIBYTE
:
2502 mem
[--index
] = (unsigned char)(MemElem
>> 32);
2503 case AccessLength_WORD
:
2504 mem
[--index
] = (unsigned char)(MemElem
>> 24);
2505 case AccessLength_TRIPLEBYTE
:
2506 mem
[--index
] = (unsigned char)(MemElem
>> 16);
2507 case AccessLength_HALFWORD
:
2508 mem
[--index
] = (unsigned char)(MemElem
>> 8);
2509 case AccessLength_BYTE
:
2510 mem
[--index
] = (unsigned char)(MemElem
>> 0);
2520 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2521 /* Order loads and stores to synchronise shared memory. Perform the
2522 action necessary to make the effects of groups of synchronizable
2523 loads and stores indicated by stype occur in the same order for all
2526 SyncOperation(stype
)
2530 callback
->printf_filtered(callback
,"SyncOperation(%d) : TODO\n",stype
);
2535 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2536 /* Signal an exception condition. This will result in an exception
2537 that aborts the instruction. The instruction operation pseudocode
2538 will never see a return from this function call. */
2541 SignalException (int exception
,...)
2543 SignalException(exception
)
2547 /* Ensure that any active atomic read/modify/write operation will fail: */
2550 switch (exception
) {
2551 /* TODO: For testing purposes I have been ignoring TRAPs. In
2552 reality we should either simulate them, or allow the user to
2553 ignore them at run-time. */
2555 sim_warning("Ignoring instruction TRAP (PC 0x%08X%08X)",WORD64HI(IPC
),WORD64LO(IPC
));
2558 case ReservedInstruction
:
2561 unsigned int instruction
;
2562 va_start(ap
,exception
);
2563 instruction
= va_arg(ap
,unsigned int);
2565 /* Provide simple monitor support using ReservedInstruction
2566 exceptions. The following code simulates the fixed vector
2567 entry points into the IDT monitor by causing a simulator
2568 trap, performing the monitor operation, and returning to
2569 the address held in the $ra register (standard PCS return
2570 address). This means we only need to pre-load the vector
2571 space with suitable instruction values. For systems were
2572 actual trap instructions are used, we would not need to
2573 perform this magic. */
2574 if ((instruction
& ~RSVD_INSTRUCTION_AMASK
) == RSVD_INSTRUCTION
) {
2575 sim_monitor(instruction
& RSVD_INSTRUCTION_AMASK
);
2576 PC
= RA
; /* simulate the return from the vector entry */
2577 /* NOTE: This assumes that a branch-and-link style
2578 instruction was used to enter the vector (which is the
2579 case with the current IDT monitor). */
2580 break; /* out of the switch statement */
2581 } /* else fall through to normal exception processing */
2582 sim_warning("ReservedInstruction 0x%08X at IPC = 0x%08X%08X",instruction
,WORD64HI(IPC
),WORD64LO(IPC
));
2587 if (exception
!= BreakPoint
)
2588 callback
->printf_filtered(callback
,"DBG: SignalException(%d) IPC = 0x%08X%08X\n",exception
,WORD64HI(IPC
),WORD64LO(IPC
));
2590 /* Store exception code into current exception id variable (used
2593 /* TODO: If not simulating exceptions then stop the simulator
2594 execution. At the moment we always stop the simulation. */
2595 state
|= (simSTOP
| simEXCEPTION
);
2597 /* Keep a copy of the current A0 in-case this is the program exit
2599 if (exception
== BreakPoint
) {
2601 unsigned int instruction
;
2602 va_start(ap
,exception
);
2603 instruction
= va_arg(ap
,unsigned int);
2605 /* Check for our special terminating BREAK: */
2606 if ((instruction
& 0x03FFFFC0) == 0x03ff0000) {
2607 rcexit
= (unsigned int)(A0
& 0xFFFFFFFF);
2608 state
&= ~simEXCEPTION
;
2613 /* Store exception code into current exception id variable (used
2615 CAUSE
= (exception
<< 2);
2616 if (state
& simDELAYSLOT
) {
2618 EPC
= (IPC
- 4); /* reference the branch instruction */
2621 /* The following is so that the simulator will continue from the
2622 exception address on breakpoint operations. */
2626 case SimulatorFault
:
2630 va_start(ap
,exception
);
2631 msg
= va_arg(ap
,char *);
2632 fprintf(stderr
,"FATAL: Simulator error \"%s\"\n",msg
);
2641 #if defined(WARN_RESULT)
2642 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2643 /* This function indicates that the result of the operation is
2644 undefined. However, this should not affect the instruction
2645 stream. All that is meant to happen is that the destination
2646 register is set to an undefined result. To keep the simulator
2647 simple, we just don't bother updating the destination register, so
2648 the overall result will be undefined. If desired we can stop the
2649 simulator by raising a pseudo-exception. */
2653 sim_warning("UndefinedResult: IPC = 0x%08X%08X",WORD64HI(IPC
),WORD64LO(IPC
));
2654 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2659 #endif /* WARN_RESULT */
2662 CacheOp(op
,pAddr
,vAddr
,instruction
)
2666 unsigned int instruction
;
2668 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2669 static int icache_warning
= 1;
2670 static int dcache_warning
= 1;
2672 static int icache_warning
= 0;
2673 static int dcache_warning
= 0;
2676 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2677 enable bit in the Status Register is clear - a coprocessor
2678 unusable exception is taken. */
2680 callback
->printf_filtered(callback
,"TODO: Cache availability checking (PC = 0x%08X%08X)\n",WORD64HI(IPC
),WORD64LO(IPC
));
2684 case 0: /* instruction cache */
2686 case 0: /* Index Invalidate */
2687 case 1: /* Index Load Tag */
2688 case 2: /* Index Store Tag */
2689 case 4: /* Hit Invalidate */
2691 case 6: /* Hit Writeback */
2692 if (!icache_warning
)
2694 sim_warning("Instruction CACHE operation %d to be coded",(op
>> 2));
2700 SignalException(ReservedInstruction
,instruction
);
2705 case 1: /* data cache */
2707 case 0: /* Index Writeback Invalidate */
2708 case 1: /* Index Load Tag */
2709 case 2: /* Index Store Tag */
2710 case 3: /* Create Dirty */
2711 case 4: /* Hit Invalidate */
2712 case 5: /* Hit Writeback Invalidate */
2713 case 6: /* Hit Writeback */
2714 if (!dcache_warning
)
2716 sim_warning("Data CACHE operation %d to be coded",(op
>> 2));
2722 SignalException(ReservedInstruction
,instruction
);
2727 default: /* unrecognised cache ID */
2728 SignalException(ReservedInstruction
,instruction
);
2735 /*-- FPU support routines ---------------------------------------------------*/
2737 #if defined(HASFPU) /* Only needed when building FPU aware simulators */
2740 #define SizeFGR() (GPRLEN)
2742 /* They depend on the CPU being simulated */
2743 #define SizeFGR() ((PROCESSOR_64BIT && ((SR & status_FR) == 1)) ? 64 : 32)
2746 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2747 formats conform to ANSI/IEEE Std 754-1985. */
2748 /* SINGLE precision floating:
2749 * seeeeeeeefffffffffffffffffffffff
2751 * e = 8bits = exponent
2752 * f = 23bits = fraction
2754 /* SINGLE precision fixed:
2755 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2757 * i = 31bits = integer
2759 /* DOUBLE precision floating:
2760 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2762 * e = 11bits = exponent
2763 * f = 52bits = fraction
2765 /* DOUBLE precision fixed:
2766 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2768 * i = 63bits = integer
2771 /* Extract sign-bit: */
2772 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2773 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2774 /* Extract biased exponent: */
2775 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2776 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2777 /* Extract unbiased Exponent: */
2778 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2779 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2780 /* Extract complete fraction field: */
2781 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2782 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2783 /* Extract numbered fraction bit: */
2784 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2785 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2787 /* Explicit QNaN values used when value required: */
2788 #define FPQNaN_SINGLE (0x7FBFFFFF)
2789 #define FPQNaN_WORD (0x7FFFFFFF)
2790 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2791 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2793 /* Explicit Infinity values used when required: */
2794 #define FPINF_SINGLE (0x7F800000)
2795 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2797 #if 1 /* def DEBUG */
2798 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2799 #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>"))))))
2810 /* Treat unused register values, as fixed-point 64bit values: */
2811 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2813 /* If request to read data as "uninterpreted", then use the current
2815 fmt
= fpr_state
[fpr
];
2820 /* For values not yet accessed, set to the desired format: */
2821 if (fpr_state
[fpr
] == fmt_uninterpreted
) {
2822 fpr_state
[fpr
] = fmt
;
2824 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2827 if (fmt
!= fpr_state
[fpr
]) {
2828 sim_warning("FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%08X%08X)",fpr
,DOFMT(fpr_state
[fpr
]),DOFMT(fmt
),WORD64HI(IPC
),WORD64LO(IPC
));
2829 fpr_state
[fpr
] = fmt_unknown
;
2832 if (fpr_state
[fpr
] == fmt_unknown
) {
2833 /* Set QNaN value: */
2836 value
= FPQNaN_SINGLE
;
2840 value
= FPQNaN_DOUBLE
;
2844 value
= FPQNaN_WORD
;
2848 value
= FPQNaN_LONG
;
2855 } else if (SizeFGR() == 64) {
2859 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2862 case fmt_uninterpreted
:
2872 } else if ((fpr
& 1) == 0) { /* even registers only */
2876 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2879 case fmt_uninterpreted
:
2882 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2892 SignalException(SimulatorFault
,"Unrecognised FP format in ValueFPR()");
2895 printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%08X%08X : PC = 0x%08X%08X : SizeFGR() = %d\n",fpr
,DOFMT(fmt
),WORD64HI(value
),WORD64LO(value
),WORD64HI(IPC
),WORD64LO(IPC
),SizeFGR());
2902 StoreFPR(fpr
,fmt
,value
)
2910 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%08X%08X : PC = 0x%08X%08X : SizeFGR() = %d\n",fpr
,DOFMT(fmt
),WORD64HI(value
),WORD64LO(value
),WORD64HI(IPC
),WORD64LO(IPC
),SizeFGR());
2913 if (SizeFGR() == 64) {
2917 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2918 fpr_state
[fpr
] = fmt
;
2921 case fmt_uninterpreted
:
2925 fpr_state
[fpr
] = fmt
;
2929 fpr_state
[fpr
] = fmt_unknown
;
2933 } else if ((fpr
& 1) == 0) { /* even register number only */
2937 FGR
[fpr
+1] = 0xDEADC0DE;
2938 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2939 fpr_state
[fpr
+ 1] = fmt
;
2940 fpr_state
[fpr
] = fmt
;
2943 case fmt_uninterpreted
:
2946 FGR
[fpr
+1] = (value
>> 32);
2947 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2948 fpr_state
[fpr
+ 1] = fmt
;
2949 fpr_state
[fpr
] = fmt
;
2953 fpr_state
[fpr
] = fmt_unknown
;
2958 #if defined(WARN_RESULT)
2961 #endif /* WARN_RESULT */
2964 SignalException(SimulatorFault
,"Unrecognised FP format in StoreFPR()");
2967 printf("DBG: StoreFPR: fpr[%d] = 0x%08X%08X (format %s)\n",fpr
,WORD64HI(FGR
[fpr
]),WORD64LO(FGR
[fpr
]),DOFMT(fmt
));
2980 /* Check if (((E - bias) == (E_max + 1)) && (fraction != 0)). We
2981 know that the exponent field is biased... we we cheat and avoid
2982 removing the bias value. */
2985 boolean
= ((FP_S_be(op
) == 0xFF) && (FP_S_f(op
) != 0));
2986 /* We could use "FP_S_fb(1,op)" to ascertain whether we are
2987 dealing with a SNaN or QNaN */
2990 boolean
= ((FP_D_be(op
) == 0x7FF) && (FP_D_f(op
) != 0));
2991 /* We could use "FP_S_fb(1,op)" to ascertain whether we are
2992 dealing with a SNaN or QNaN */
2995 boolean
= (op
== FPQNaN_WORD
);
2998 boolean
= (op
== FPQNaN_LONG
);
3003 printf("DBG: NaN: returning %d for 0x%08X%08X (format = %s)\n",boolean
,WORD64HI(op
),WORD64LO(op
),DOFMT(fmt
));
3017 printf("DBG: Infinity: format %s 0x%08X%08X (PC = 0x%08X%08X)\n",DOFMT(fmt
),WORD64HI(op
),WORD64LO(op
),WORD64HI(IPC
),WORD64LO(IPC
));
3020 /* Check if (((E - bias) == (E_max + 1)) && (fraction == 0)). We
3021 know that the exponent field is biased... we we cheat and avoid
3022 removing the bias value. */
3025 boolean
= ((FP_S_be(op
) == 0xFF) && (FP_S_f(op
) == 0));
3028 boolean
= ((FP_D_be(op
) == 0x7FF) && (FP_D_f(op
) == 0));
3031 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
3036 printf("DBG: Infinity: returning %d for 0x%08X%08X (format = %s)\n",boolean
,WORD64HI(op
),WORD64LO(op
),DOFMT(fmt
));
3050 /* Argument checking already performed by the FPCOMPARE code */
3053 printf("DBG: Less: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3056 /* The format type should already have been checked: */
3060 unsigned int wop1
= (unsigned int)op1
;
3061 unsigned int wop2
= (unsigned int)op2
;
3062 boolean
= (*(float *)&wop1
< *(float *)&wop2
);
3066 boolean
= (*(double *)&op1
< *(double *)&op2
);
3071 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
3085 /* Argument checking already performed by the FPCOMPARE code */
3088 printf("DBG: Equal: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3091 /* The format type should already have been checked: */
3094 boolean
= ((op1
& 0xFFFFFFFF) == (op2
& 0xFFFFFFFF));
3097 boolean
= (op1
== op2
);
3102 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
3109 AbsoluteValue(op
,fmt
)
3116 printf("DBG: AbsoluteValue: %s: op = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op
),WORD64LO(op
));
3119 /* The format type should already have been checked: */
3123 unsigned int wop
= (unsigned int)op
;
3124 float tmp
= ((float)fabs((double)*(float *)&wop
));
3125 result
= (uword64
)*(unsigned int *)&tmp
;
3130 double tmp
= (fabs(*(double *)&op
));
3131 result
= *(uword64
*)&tmp
;
3146 printf("DBG: Negate: %s: op = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op
),WORD64LO(op
));
3149 /* The format type should already have been checked: */
3153 unsigned int wop
= (unsigned int)op
;
3154 float tmp
= ((float)0.0 - *(float *)&wop
);
3155 result
= (uword64
)*(unsigned int *)&tmp
;
3160 double tmp
= ((double)0.0 - *(double *)&op
);
3161 result
= *(uword64
*)&tmp
;
3178 printf("DBG: Add: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3181 /* The registers must specify FPRs valid for operands of type
3182 "fmt". If they are not valid, the result is undefined. */
3184 /* The format type should already have been checked: */
3188 unsigned int wop1
= (unsigned int)op1
;
3189 unsigned int wop2
= (unsigned int)op2
;
3190 float tmp
= (*(float *)&wop1
+ *(float *)&wop2
);
3191 result
= (uword64
)*(unsigned int *)&tmp
;
3196 double tmp
= (*(double *)&op1
+ *(double *)&op2
);
3197 result
= *(uword64
*)&tmp
;
3203 printf("DBG: Add: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3218 printf("DBG: Sub: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3221 /* The registers must specify FPRs valid for operands of type
3222 "fmt". If they are not valid, the result is undefined. */
3224 /* The format type should already have been checked: */
3228 unsigned int wop1
= (unsigned int)op1
;
3229 unsigned int wop2
= (unsigned int)op2
;
3230 float tmp
= (*(float *)&wop1
- *(float *)&wop2
);
3231 result
= (uword64
)*(unsigned int *)&tmp
;
3236 double tmp
= (*(double *)&op1
- *(double *)&op2
);
3237 result
= *(uword64
*)&tmp
;
3243 printf("DBG: Sub: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3250 Multiply(op1
,op2
,fmt
)
3258 printf("DBG: Multiply: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3261 /* The registers must specify FPRs valid for operands of type
3262 "fmt". If they are not valid, the result is undefined. */
3264 /* The format type should already have been checked: */
3268 unsigned int wop1
= (unsigned int)op1
;
3269 unsigned int wop2
= (unsigned int)op2
;
3270 float tmp
= (*(float *)&wop1
* *(float *)&wop2
);
3271 result
= (uword64
)*(unsigned int *)&tmp
;
3276 double tmp
= (*(double *)&op1
* *(double *)&op2
);
3277 result
= *(uword64
*)&tmp
;
3283 printf("DBG: Multiply: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3298 printf("DBG: Divide: %s: op1 = 0x%08X%08X : op2 = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op1
),WORD64LO(op1
),WORD64HI(op2
),WORD64LO(op2
));
3301 /* The registers must specify FPRs valid for operands of type
3302 "fmt". If they are not valid, the result is undefined. */
3304 /* The format type should already have been checked: */
3308 unsigned int wop1
= (unsigned int)op1
;
3309 unsigned int wop2
= (unsigned int)op2
;
3310 float tmp
= (*(float *)&wop1
/ *(float *)&wop2
);
3311 result
= (uword64
)*(unsigned int *)&tmp
;
3316 double tmp
= (*(double *)&op1
/ *(double *)&op2
);
3317 result
= *(uword64
*)&tmp
;
3323 printf("DBG: Divide: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3337 printf("DBG: Recip: %s: op = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op
),WORD64LO(op
));
3340 /* The registers must specify FPRs valid for operands of type
3341 "fmt". If they are not valid, the result is undefined. */
3343 /* The format type should already have been checked: */
3347 unsigned int wop
= (unsigned int)op
;
3348 float tmp
= ((float)1.0 / *(float *)&wop
);
3349 result
= (uword64
)*(unsigned int *)&tmp
;
3354 double tmp
= ((double)1.0 / *(double *)&op
);
3355 result
= *(uword64
*)&tmp
;
3361 printf("DBG: Recip: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3375 printf("DBG: SquareRoot: %s: op = 0x%08X%08X\n",DOFMT(fmt
),WORD64HI(op
),WORD64LO(op
));
3378 /* The registers must specify FPRs valid for operands of type
3379 "fmt". If they are not valid, the result is undefined. */
3381 /* The format type should already have been checked: */
3385 unsigned int wop
= (unsigned int)op
;
3387 float tmp
= ((float)sqrt((double)*(float *)&wop
));
3388 result
= (uword64
)*(unsigned int *)&tmp
;
3390 /* TODO: Provide square-root */
3391 result
= (uword64
)0;
3398 double tmp
= (sqrt(*(double *)&op
));
3399 result
= *(uword64
*)&tmp
;
3401 /* TODO: Provide square-root */
3402 result
= (uword64
)0;
3409 printf("DBG: SquareRoot: returning 0x%08X%08X (format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(fmt
));
3416 Convert(rm
,op
,from
,to
)
3425 printf("DBG: Convert: mode %s : op 0x%08X%08X : from %s : to %s : (PC = 0x%08X%08X)\n",RMMODE(rm
),WORD64HI(op
),WORD64LO(op
),DOFMT(from
),DOFMT(to
),WORD64HI(IPC
),WORD64LO(IPC
));
3428 /* The value "op" is converted to the destination format, rounding
3429 using mode "rm". When the destination is a fixed-point format,
3430 then a source value of Infinity, NaN or one which would round to
3431 an integer outside the fixed point range then an IEEE Invalid
3432 Operation condition is raised. */
3439 tmp
= (float)(*(double *)&op
);
3443 tmp
= (float)((int)(op
& 0xFFFFFFFF));
3447 tmp
= (float)((word64
)op
);
3452 /* FIXME: This code is incorrect. The rounding mode does not
3453 round to integral values; it rounds to the nearest
3454 representable value in the format. */
3458 /* Round result to nearest representable value. When two
3459 representable values are equally near, round to the value
3460 that has a least significant bit of zero (i.e. is even). */
3462 tmp
= (float)anint((double)tmp
);
3464 /* TODO: Provide round-to-nearest */
3469 /* Round result to the value closest to, and not greater in
3470 magnitude than, the result. */
3472 tmp
= (float)aint((double)tmp
);
3474 /* TODO: Provide round-to-zero */
3479 /* Round result to the value closest to, and not less than,
3481 tmp
= (float)ceil((double)tmp
);
3485 /* Round result to the value closest to, and not greater than,
3487 tmp
= (float)floor((double)tmp
);
3492 result
= (uword64
)*(unsigned int *)&tmp
;
3504 unsigned int wop
= (unsigned int)op
;
3505 tmp
= (double)(*(float *)&wop
);
3510 xxx
= SIGNEXTEND((op
& 0xFFFFFFFF),32);
3515 tmp
= (double)((word64
)op
);
3520 /* FIXME: This code is incorrect. The rounding mode does not
3521 round to integral values; it rounds to the nearest
3522 representable value in the format. */
3527 tmp
= anint(*(double *)&tmp
);
3529 /* TODO: Provide round-to-nearest */
3535 tmp
= aint(*(double *)&tmp
);
3537 /* TODO: Provide round-to-zero */
3542 tmp
= ceil(*(double *)&tmp
);
3546 tmp
= floor(*(double *)&tmp
);
3551 result
= *(uword64
*)&tmp
;
3557 if (Infinity(op
,from
) || NaN(op
,from
) || (1 == 0/*TODO: check range */)) {
3558 printf("DBG: TODO: update FCSR\n");
3559 SignalException(FPE
);
3561 if (to
== fmt_word
) {
3566 unsigned int wop
= (unsigned int)op
;
3567 tmp
= (int)*((float *)&wop
);
3571 tmp
= (int)*((double *)&op
);
3573 printf("DBG: from double %.30f (0x%08X%08X) to word: 0x%08X\n",*((double *)&op
),WORD64HI(op
),WORD64LO(op
),tmp
);
3577 result
= (uword64
)tmp
;
3578 } else { /* fmt_long */
3583 unsigned int wop
= (unsigned int)op
;
3584 tmp
= (word64
)*((float *)&wop
);
3588 tmp
= (word64
)*((double *)&op
);
3591 result
= (uword64
)tmp
;
3598 printf("DBG: Convert: returning 0x%08X%08X (to format = %s)\n",WORD64HI(result
),WORD64LO(result
),DOFMT(to
));
3605 /*-- co-processor support routines ------------------------------------------*/
3608 CoProcPresent(coproc_number
)
3609 unsigned int coproc_number
;
3611 /* Return TRUE if simulator provides a model for the given co-processor number */
3616 COP_LW(coproc_num
,coproc_reg
,memword
)
3617 int coproc_num
, coproc_reg
;
3618 unsigned int memword
;
3620 switch (coproc_num
) {
3624 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%08X%08X\n",memword
,WORD64HI(memword
),WORD64LO(memword
));
3626 StoreFPR(coproc_reg
,fmt_uninterpreted
,(uword64
)memword
);
3631 #if 0 /* this should be controlled by a configuration option */
3632 callback
->printf_filtered(callback
,"COP_LW(%d,%d,0x%08X) at IPC = 0x%08X%08X : TODO (architecture specific)\n",coproc_num
,coproc_reg
,memword
,WORD64HI(IPC
),WORD64LO(IPC
));
3641 COP_LD(coproc_num
,coproc_reg
,memword
)
3642 int coproc_num
, coproc_reg
;
3645 switch (coproc_num
) {
3648 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3653 #if 0 /* this message should be controlled by a configuration option */
3654 callback
->printf_filtered(callback
,"COP_LD(%d,%d,0x%08X%08X) at IPC = 0x%08X%08X : TODO (architecture specific)\n",coproc_num
,coproc_reg
,WORD64HI(memword
),WORD64LO(memword
),WORD64HI(IPC
),WORD64LO(IPC
));
3663 COP_SW(coproc_num
,coproc_reg
)
3664 int coproc_num
, coproc_reg
;
3666 unsigned int value
= 0;
3667 switch (coproc_num
) {
3671 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3674 value
= (unsigned int)ValueFPR(coproc_reg
,fpr_state
[coproc_reg
]);
3677 printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(fpr_state
[coproc_reg
]));
3679 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_single
);
3686 #if 0 /* should be controlled by configuration option */
3687 callback
->printf_filtered(callback
,"COP_SW(%d,%d) at IPC = 0x%08X%08X : TODO (architecture specific)\n",coproc_num
,coproc_reg
,WORD64HI(IPC
),WORD64LO(IPC
));
3696 COP_SD(coproc_num
,coproc_reg
)
3697 int coproc_num
, coproc_reg
;
3700 switch (coproc_num
) {
3704 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3707 value
= ValueFPR(coproc_reg
,fpr_state
[coproc_reg
]);
3710 printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(fpr_state
[coproc_reg
]));
3712 value
= ValueFPR(coproc_reg
,fmt_double
);
3719 #if 0 /* should be controlled by configuration option */
3720 callback
->printf_filtered(callback
,"COP_SD(%d,%d) at IPC = 0x%08X%08X : TODO (architecture specific)\n",coproc_num
,coproc_reg
,WORD64HI(IPC
),WORD64LO(IPC
));
3729 decode_coproc(instruction
)
3730 unsigned int instruction
;
3732 int coprocnum
= ((instruction
>> 26) & 3);
3734 switch (coprocnum
) {
3735 case 0: /* standard CPU control and cache registers */
3738 Standard CP0 registers
3739 0 = Index R4000 VR4100 VR4300
3740 1 = Random R4000 VR4100 VR4300
3741 2 = EntryLo0 R4000 VR4100 VR4300
3742 3 = EntryLo1 R4000 VR4100 VR4300
3743 4 = Context R4000 VR4100 VR4300
3744 5 = PageMask R4000 VR4100 VR4300
3745 6 = Wired R4000 VR4100 VR4300
3746 8 = BadVAddr R4000 VR4100 VR4300
3747 9 = Count R4000 VR4100 VR4300
3748 10 = EntryHi R4000 VR4100 VR4300
3749 11 = Compare R4000 VR4100 VR4300
3750 12 = SR R4000 VR4100 VR4300
3751 13 = Cause R4000 VR4100 VR4300
3752 14 = EPC R4000 VR4100 VR4300
3753 15 = PRId R4000 VR4100 VR4300
3754 16 = Config R4000 VR4100 VR4300
3755 17 = LLAddr R4000 VR4100 VR4300
3756 18 = WatchLo R4000 VR4100 VR4300
3757 19 = WatchHi R4000 VR4100 VR4300
3758 20 = XContext R4000 VR4100 VR4300
3759 26 = PErr or ECC R4000 VR4100 VR4300
3760 27 = CacheErr R4000 VR4100
3761 28 = TagLo R4000 VR4100 VR4300
3762 29 = TagHi R4000 VR4100 VR4300
3763 30 = ErrorEPC R4000 VR4100 VR4300
3765 int code
= ((instruction
>> 21) & 0x1F);
3766 /* R4000 Users Manual (second edition) lists the following CP0
3768 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3769 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3770 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3771 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3772 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3773 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3774 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3775 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3776 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3777 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3779 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0)) {
3780 int rt
= ((instruction
>> 16) & 0x1F);
3781 int rd
= ((instruction
>> 11) & 0x1F);
3782 if (code
== 0x00) { /* MF : move from */
3783 #if 0 /* message should be controlled by configuration option */
3784 callback
->printf_filtered(callback
,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt
,rd
);
3786 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3787 } else { /* MT : move to */
3788 /* CPR[0,rd] = GPR[rt]; */
3789 #if 0 /* should be controlled by configuration option */
3790 callback
->printf_filtered(callback
,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt
,rd
);
3794 sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%08X%08X : No handler present",instruction
,WORD64HI(IPC
),WORD64LO(IPC
));
3795 /* TODO: When executing an ERET or RFE instruction we should
3796 clear LLBIT, to ensure that any out-standing atomic
3797 read/modify/write sequence fails. */
3801 case 2: /* undefined co-processor */
3802 sim_warning("COP2 instruction 0x%08X at IPC = 0x%08X%08X : No handler present",instruction
,WORD64HI(IPC
),WORD64LO(IPC
));
3805 case 1: /* should not occur (FPU co-processor) */
3806 case 3: /* should not occur (FPU co-processor) */
3807 SignalException(ReservedInstruction
,instruction
);
3814 /*-- instruction simulation -------------------------------------------------*/
3819 unsigned int pipeline_count
= 1;
3822 if (membank
== NULL
) {
3823 printf("DBG: simulate() entered with no memory\n");
3828 #if 0 /* Disabled to check that everything works OK */
3829 /* The VR4300 seems to sign-extend the PC on its first
3830 access. However, this may just be because it is currently
3831 configured in 32bit mode. However... */
3832 PC
= SIGNEXTEND(PC
,32);
3835 /* main controlling loop */
3837 /* Fetch the next instruction from the simulator memory: */
3838 uword64 vaddr
= (uword64
)PC
;
3841 unsigned int instruction
;
3842 int dsstate
= (state
& simDELAYSLOT
);
3846 printf("DBG: state = 0x%08X :",state
);
3847 if (state
& simSTOP
) printf(" simSTOP");
3848 if (state
& simSTEP
) printf(" simSTEP");
3849 if (state
& simHALTEX
) printf(" simHALTEX");
3850 if (state
& simHALTIN
) printf(" simHALTIN");
3851 if (state
& simBE
) printf(" simBE");
3857 callback
->printf_filtered(callback
,"DBG: DSPC = 0x%08X%08X\n",WORD64HI(DSPC
),WORD64LO(DSPC
));
3860 if (AddressTranslation(PC
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) { /* Copy the action of the LW instruction */
3861 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3862 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3865 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3866 value
= LoadMemory(cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3867 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3868 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3870 fprintf(stderr
,"Cannot translate address for PC = 0x%08X%08X failed\n",WORD64HI(PC
),WORD64LO(PC
));
3875 callback
->printf_filtered(callback
,"DBG: fetched 0x%08X from PC = 0x%08X%08X\n",instruction
,WORD64HI(PC
),WORD64LO(PC
));
3878 #if !defined(FASTSIM) || defined(PROFILE)
3879 instruction_fetches
++;
3880 /* Since we increment above, the value should only ever be zero if
3881 we have just overflowed: */
3882 if (instruction_fetches
== 0)
3883 instruction_fetch_overflow
++;
3884 #if defined(PROFILE)
3885 if ((state
& simPROFILE
) && ((instruction_fetches
% profile_frequency
) == 0) && profile_hist
) {
3886 unsigned n
= ((unsigned int)(PC
- profile_minpc
) >> (profile_shift
+ 2));
3887 if (n
< profile_nsamples
) {
3888 /* NOTE: The counts for the profiling bins are only 16bits wide */
3889 if (profile_hist
[n
] != USHRT_MAX
)
3890 (profile_hist
[n
])++;
3893 #endif /* PROFILE */
3894 #endif /* !FASTSIM && PROFILE */
3896 IPC
= PC
; /* copy PC for this instruction */
3897 /* This is required by exception processing, to ensure that we can
3898 cope with exceptions in the delay slots of branches that may
3899 already have changed the PC. */
3900 PC
+= 4; /* increment ready for the next fetch */
3901 /* NOTE: If we perform a delay slot change to the PC, this
3902 increment is not requuired. However, it would make the
3903 simulator more complicated to try and avoid this small hit. */
3905 /* Currently this code provides a simple model. For more
3906 complicated models we could perform exception status checks at
3907 this point, and set the simSTOP state as required. This could
3908 also include processing any hardware interrupts raised by any
3909 I/O model attached to the simulator context.
3911 Support for "asynchronous" I/O events within the simulated world
3912 could be providing by managing a counter, and calling a I/O
3913 specific handler when a particular threshold is reached. On most
3914 architectures a decrement and check for zero operation is
3915 usually quicker than an increment and compare. However, the
3916 process of managing a known value decrement to zero, is higher
3917 than the cost of using an explicit value UINT_MAX into the
3918 future. Which system is used will depend on how complicated the
3919 I/O model is, and how much it is likely to affect the simulator
3922 If events need to be scheduled further in the future than
3923 UINT_MAX event ticks, then the I/O model should just provide its
3924 own counter, triggered from the event system. */
3926 /* MIPS pipeline ticks. To allow for future support where the
3927 pipeline hit of individual instructions is known, this control
3928 loop manages a "pipeline_count" variable. It is initialised to
3929 1 (one), and will only be changed by the simulator engine when
3930 executing an instruction. If the engine does not have access to
3931 pipeline cycle count information then all instructions will be
3932 treated as using a single cycle. NOTE: A standard system is not
3933 provided by the default simulator because different MIPS
3934 architectures have different cycle counts for the same
3938 /* Set previous flag, depending on current: */
3939 if (state
& simPCOC0
)
3943 /* and update the current value: */
3950 /* NOTE: For multi-context simulation environments the "instruction"
3951 variable should be local to this routine. */
3953 /* Shorthand accesses for engine. Note: If we wanted to use global
3954 variables (and a single-threaded simulator engine), then we can
3955 create the actual variables with these names. */
3957 if (!(state
& simSKIPNEXT
)) {
3958 /* Include the simulator engine */
3960 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3961 #error "Mismatch between run-time simulator code and simulation engine"
3964 #if defined(WARN_LOHI)
3965 /* Decrement the HI/LO validity ticks */
3970 #endif /* WARN_LOHI */
3972 #if defined(WARN_ZERO)
3973 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3974 should check for it being changed. It is better doing it here,
3975 than within the simulator, since it will help keep the simulator
3978 sim_warning("The ZERO register has been updated with 0x%08X%08X (PC = 0x%08X%08X) (reset back to zero)",WORD64HI(ZERO
),WORD64LO(ZERO
),WORD64HI(IPC
),WORD64LO(IPC
));
3979 ZERO
= 0; /* reset back to zero before next instruction */
3981 #endif /* WARN_ZERO */
3982 } else /* simSKIPNEXT check */
3983 state
&= ~simSKIPNEXT
;
3985 /* If the delay slot was active before the instruction is
3986 executed, then update the PC to its new value: */
3989 printf("DBG: dsstate set before instruction execution - updating PC to 0x%08X%08X\n",WORD64HI(DSPC
),WORD64LO(DSPC
));
3992 state
&= ~simDELAYSLOT
;
3995 if (MIPSISA
< 4) { /* The following is only required on pre MIPS IV processors: */
3996 /* Deal with pending register updates: */
3998 printf("DBG: EMPTY BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in
,pending_out
,pending_total
);
4000 if (pending_out
!= pending_in
) {
4002 int index
= pending_out
;
4003 int total
= pending_total
;
4004 if (pending_total
== 0) {
4005 fprintf(stderr
,"FATAL: Mis-match on pending update pointers\n");
4008 for (loop
= 0; (loop
< total
); loop
++) {
4010 printf("DBG: BEFORE index = %d, loop = %d\n",index
,loop
);
4012 if (pending_slot_reg
[index
] != (LAST_EMBED_REGNUM
+ 1)) {
4014 printf("pending_slot_count[%d] = %d\n",index
,pending_slot_count
[index
]);
4016 if (--(pending_slot_count
[index
]) == 0) {
4018 printf("pending_slot_reg[%d] = %d\n",index
,pending_slot_reg
[index
]);
4019 printf("pending_slot_value[%d] = 0x%08X%08X\n",index
,WORD64HI(pending_slot_value
[index
]),WORD64LO(pending_slot_value
[index
]));
4021 if (pending_slot_reg
[index
] == COCIDX
) {
4022 SETFCC(0,((FCR31
& (1 << 23)) ? 1 : 0));
4024 registers
[pending_slot_reg
[index
]] = pending_slot_value
[index
];
4026 /* The only time we have PENDING updates to FPU
4027 registers, is when performing binary transfers. This
4028 means we should update the register type field. */
4029 if ((pending_slot_reg
[index
] >= FGRIDX
) && (pending_slot_reg
[index
] < (FGRIDX
+ 32)))
4030 fpr_state
[pending_slot_reg
[index
]] = fmt_uninterpreted
;
4034 printf("registers[%d] = 0x%08X%08X\n",pending_slot_reg
[index
],WORD64HI(registers
[pending_slot_reg
[index
]]),WORD64LO(registers
[pending_slot_reg
[index
]]));
4036 pending_slot_reg
[index
] = (LAST_EMBED_REGNUM
+ 1);
4038 if (pending_out
== PSLOTS
)
4044 printf("DBG: AFTER index = %d, loop = %d\n",index
,loop
);
4047 if (index
== PSLOTS
)
4052 printf("DBG: EMPTY AFTER pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in
,pending_out
,pending_total
);
4056 #if !defined(FASTSIM)
4057 pipeline_ticks
+= pipeline_count
;
4058 #endif /* FASTSIM */
4060 if (state
& simSTEP
)
4062 } while (!(state
& simSTOP
));
4065 if (membank
== NULL
) {
4066 printf("DBG: simulate() LEAVING with no memory\n");
4074 /*---------------------------------------------------------------------------*/
4075 /*> EOF interp.c <*/