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