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