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