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