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