* sim/mips/interp.c: Correct some HASFPU problems.
[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 'x', "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 #if defined(HASFPU)
890 else if ((rn >= FGRIDX) && (rn < (FGRIDX + 32)))
891 register_widths[rn] = GPRLEN;
892 #endif
893 else if ((rn >= 33) && (rn <= 37))
894 register_widths[rn] = GPRLEN;
895 else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89)))
896 register_widths[rn] = 32;
897 else
898 register_widths[rn] = 0;
899 }
900 }
901
902
903 if (logfile != NULL) {
904 if (strcmp(logfile,"-") == 0)
905 logfh = stdout;
906 else {
907 logfh = fopen(logfile,"wb+");
908 if (logfh == NULL) {
909 callback->printf_filtered(callback,"Failed to create file \"%s\", writing log information to stderr.\n",tracefile);
910 logfh = stderr;
911 }
912 }
913 }
914
915 /* FIXME: In the future both of these malloc's can be replaced by
916 calls to sim-core. */
917
918 /* If the host has "mmap" available we could use it to provide a
919 very large virtual address space for the simulator, since memory
920 would only be allocated within the "mmap" space as it is
921 accessed. This can also be linked to the architecture specific
922 support, required to simulate the MMU. */
923 sim_size(STATE_MEM_SIZE (sd));
924 /* NOTE: The above will also have enabled any profiling state! */
925
926 /* Create the monitor address space as well */
927 monitor = (unsigned char *)calloc(1,monitor_size);
928 if (!monitor)
929 fprintf(stderr,"Not enough VM for monitor simulation (%d bytes)\n",
930 monitor_size);
931
932 #if defined(TRACE)
933 if (state & simTRACE)
934 open_trace();
935 #endif /* TRACE */
936
937 /* Write the monitor trap address handlers into the monitor (eeprom)
938 address space. This can only be done once the target endianness
939 has been determined. */
940 {
941 unsigned loop;
942 /* Entry into the IDT monitor is via fixed address vectors, and
943 not using machine instructions. To avoid clashing with use of
944 the MIPS TRAP system, we place our own (simulator specific)
945 "undefined" instructions into the relevant vector slots. */
946 for (loop = 0; (loop < monitor_size); loop += 4) {
947 uword64 vaddr = (monitor_base + loop);
948 uword64 paddr;
949 int cca;
950 if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
951 StoreMemory(cca, AccessLength_WORD,
952 (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)),
953 0, paddr, vaddr, isRAW);
954 }
955 /* The PMON monitor uses the same address space, but rather than
956 branching into it the address of a routine is loaded. We can
957 cheat for the moment, and direct the PMON routine to IDT style
958 instructions within the monitor space. This relies on the IDT
959 monitor not using the locations from 0xBFC00500 onwards as its
960 entry points.*/
961 for (loop = 0; (loop < 24); loop++)
962 {
963 uword64 vaddr = (monitor_base + 0x500 + (loop * 4));
964 uword64 paddr;
965 int cca;
966 unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
967 switch (loop)
968 {
969 case 0: /* read */
970 value = 7;
971 break;
972
973 case 1: /* write */
974 value = 8;
975 break;
976
977 case 2: /* open */
978 value = 6;
979 break;
980
981 case 3: /* close */
982 value = 10;
983 break;
984
985 case 5: /* printf */
986 value = ((0x500 - 16) / 8); /* not an IDT reason code */
987 break;
988
989 case 8: /* cliexit */
990 value = 17;
991 break;
992
993 case 11: /* flush_cache */
994 value = 28;
995 break;
996 }
997 /* FIXME - should monitor_base be SIM_ADDR?? */
998 value = ((unsigned int)monitor_base + (value * 8));
999 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
1000 StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1001 else
1002 sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
1003
1004 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
1005 vaddr -= 0x300;
1006 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
1007 StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1008 else
1009 sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
1010 }
1011 }
1012
1013 return sd;
1014 }
1015
1016 #if defined(TRACE)
1017 static void
1018 open_trace()
1019 {
1020 tracefh = fopen(tracefile,"wb+");
1021 if (tracefh == NULL)
1022 {
1023 sim_warning("Failed to create file \"%s\", writing trace information to stderr.",tracefile);
1024 tracefh = stderr;
1025 }
1026 }
1027 #endif /* TRACE */
1028
1029 /* For the profile writing, we write the data in the host
1030 endianness. This unfortunately means we are assuming that the
1031 profile file we create is processed on the same host executing the
1032 simulator. The gmon.out file format should either have an explicit
1033 endianness, or a method of encoding the endianness in the file
1034 header. */
1035 static int
1036 writeout32(fh,val)
1037 FILE *fh;
1038 unsigned int val;
1039 {
1040 char buff[4];
1041 int res = 1;
1042
1043 if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
1044 buff[3] = ((val >> 0) & 0xFF);
1045 buff[2] = ((val >> 8) & 0xFF);
1046 buff[1] = ((val >> 16) & 0xFF);
1047 buff[0] = ((val >> 24) & 0xFF);
1048 } else {
1049 buff[0] = ((val >> 0) & 0xFF);
1050 buff[1] = ((val >> 8) & 0xFF);
1051 buff[2] = ((val >> 16) & 0xFF);
1052 buff[3] = ((val >> 24) & 0xFF);
1053 }
1054 if (fwrite(buff,4,1,fh) != 1) {
1055 sim_warning("Failed to write 4bytes to the profile file");
1056 res = 0;
1057 }
1058 return(res);
1059 }
1060
1061 static int
1062 writeout16(fh,val)
1063 FILE *fh;
1064 unsigned short val;
1065 {
1066 char buff[2];
1067 int res = 1;
1068 if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
1069 buff[1] = ((val >> 0) & 0xFF);
1070 buff[0] = ((val >> 8) & 0xFF);
1071 } else {
1072 buff[0] = ((val >> 0) & 0xFF);
1073 buff[1] = ((val >> 8) & 0xFF);
1074 }
1075 if (fwrite(buff,2,1,fh) != 1) {
1076 sim_warning("Failed to write 2bytes to the profile file");
1077 res = 0;
1078 }
1079 return(res);
1080 }
1081
1082 void
1083 sim_close (sd, quitting)
1084 SIM_DESC sd;
1085 int quitting;
1086 {
1087 #ifdef DEBUG
1088 printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
1089 #endif
1090
1091 /* "quitting" is non-zero if we cannot hang on errors */
1092
1093 /* Ensure that any resources allocated through the callback
1094 mechanism are released: */
1095 callback->shutdown(callback);
1096
1097 #if defined(PROFILE)
1098 if ((state & simPROFILE) && (profile_hist != NULL)) {
1099 FILE *pf = fopen("gmon.out","wb");
1100 unsigned loop;
1101
1102 if (pf == NULL)
1103 sim_warning("Failed to open \"gmon.out\" profile file");
1104 else {
1105 int ok;
1106 #ifdef DEBUG
1107 printf("DBG: minpc = 0x%s\n",pr_addr(profile_minpc));
1108 printf("DBG: maxpc = 0x%s\n",pr_addr(profile_maxpc));
1109 #endif /* DEBUG */
1110 ok = writeout32(pf,(unsigned int)profile_minpc);
1111 if (ok)
1112 ok = writeout32(pf,(unsigned int)profile_maxpc);
1113 if (ok)
1114 ok = writeout32(pf,(profile_nsamples * 2) + 12); /* size of sample buffer (+ header) */
1115 #ifdef DEBUG
1116 printf("DBG: nsamples = %d (size = 0x%08X)\n",profile_nsamples,((profile_nsamples * 2) + 12));
1117 #endif /* DEBUG */
1118 for (loop = 0; (ok && (loop < profile_nsamples)); loop++) {
1119 ok = writeout16(pf,profile_hist[loop]);
1120 if (!ok)
1121 break;
1122 }
1123
1124 fclose(pf);
1125 }
1126
1127 free(profile_hist);
1128 profile_hist = NULL;
1129 state &= ~simPROFILE;
1130 }
1131 #endif /* PROFILE */
1132
1133 #if defined(TRACE)
1134 if (tracefh != NULL && tracefh != stderr)
1135 fclose(tracefh);
1136 tracefh = NULL;
1137 state &= ~simTRACE;
1138 #endif /* TRACE */
1139
1140 if (logfh != NULL && logfh != stdout && logfh != stderr)
1141 fclose(logfh);
1142 logfh = NULL;
1143
1144 if (STATE_MEMORY (sd) != NULL)
1145 free(STATE_MEMORY (sd)); /* cfree not available on all hosts */
1146 STATE_MEMORY (sd) = NULL;
1147
1148 return;
1149 }
1150
1151
1152 int
1153 sim_write (sd,addr,buffer,size)
1154 SIM_DESC sd;
1155 SIM_ADDR addr;
1156 unsigned char *buffer;
1157 int size;
1158 {
1159 int index = size;
1160 uword64 vaddr = (uword64)addr;
1161
1162 /* Return the number of bytes written, or zero if error. */
1163 #ifdef DEBUG
1164 callback->printf_filtered(callback,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
1165 #endif
1166
1167 /* We provide raw read and write routines, since we do not want to
1168 count the GDB memory accesses in our statistics gathering. */
1169
1170 /* There is a lot of code duplication in the individual blocks
1171 below, but the variables are declared locally to a block to give
1172 the optimiser the best chance of improving the code. We have to
1173 perform slow byte reads from the host memory, to ensure that we
1174 get the data into the correct endianness for the (simulated)
1175 target memory world. */
1176
1177 /* Mask count to get odd byte, odd halfword, and odd word out of the
1178 way. We can then perform doubleword transfers to and from the
1179 simulator memory for optimum performance. */
1180 if (index && (index & 1)) {
1181 uword64 paddr;
1182 int cca;
1183 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1184 uword64 value = ((uword64)(*buffer++));
1185 StoreMemory(cca,AccessLength_BYTE,value,0,paddr,vaddr,isRAW);
1186 }
1187 vaddr++;
1188 index &= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
1189 }
1190 if (index && (index & 2)) {
1191 uword64 paddr;
1192 int cca;
1193 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1194 uword64 value;
1195 /* We need to perform the following magic to ensure that that
1196 bytes are written into same byte positions in the target memory
1197 world, regardless of the endianness of the host. */
1198 if (BigEndianMem) {
1199 value = ((uword64)(*buffer++) << 8);
1200 value |= ((uword64)(*buffer++) << 0);
1201 } else {
1202 value = ((uword64)(*buffer++) << 0);
1203 value |= ((uword64)(*buffer++) << 8);
1204 }
1205 StoreMemory(cca,AccessLength_HALFWORD,value,0,paddr,vaddr,isRAW);
1206 }
1207 vaddr += 2;
1208 index &= ~2;
1209 }
1210 if (index && (index & 4)) {
1211 uword64 paddr;
1212 int cca;
1213 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1214 uword64 value;
1215 if (BigEndianMem) {
1216 value = ((uword64)(*buffer++) << 24);
1217 value |= ((uword64)(*buffer++) << 16);
1218 value |= ((uword64)(*buffer++) << 8);
1219 value |= ((uword64)(*buffer++) << 0);
1220 } else {
1221 value = ((uword64)(*buffer++) << 0);
1222 value |= ((uword64)(*buffer++) << 8);
1223 value |= ((uword64)(*buffer++) << 16);
1224 value |= ((uword64)(*buffer++) << 24);
1225 }
1226 StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
1227 }
1228 vaddr += 4;
1229 index &= ~4;
1230 }
1231 for (;index; index -= 8) {
1232 uword64 paddr;
1233 int cca;
1234 if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
1235 uword64 value;
1236 if (BigEndianMem) {
1237 value = ((uword64)(*buffer++) << 56);
1238 value |= ((uword64)(*buffer++) << 48);
1239 value |= ((uword64)(*buffer++) << 40);
1240 value |= ((uword64)(*buffer++) << 32);
1241 value |= ((uword64)(*buffer++) << 24);
1242 value |= ((uword64)(*buffer++) << 16);
1243 value |= ((uword64)(*buffer++) << 8);
1244 value |= ((uword64)(*buffer++) << 0);
1245 } else {
1246 value = ((uword64)(*buffer++) << 0);
1247 value |= ((uword64)(*buffer++) << 8);
1248 value |= ((uword64)(*buffer++) << 16);
1249 value |= ((uword64)(*buffer++) << 24);
1250 value |= ((uword64)(*buffer++) << 32);
1251 value |= ((uword64)(*buffer++) << 40);
1252 value |= ((uword64)(*buffer++) << 48);
1253 value |= ((uword64)(*buffer++) << 56);
1254 }
1255 StoreMemory(cca,AccessLength_DOUBLEWORD,value,0,paddr,vaddr,isRAW);
1256 }
1257 vaddr += 8;
1258 }
1259
1260 return(size);
1261 }
1262
1263 int
1264 sim_read (sd,addr,buffer,size)
1265 SIM_DESC sd;
1266 SIM_ADDR addr;
1267 unsigned char *buffer;
1268 int size;
1269 {
1270 int index;
1271
1272 /* Return the number of bytes read, or zero if error. */
1273 #ifdef DEBUG
1274 callback->printf_filtered(callback,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
1275 #endif /* DEBUG */
1276
1277 /* TODO: Perform same optimisation as the sim_write() code
1278 above. NOTE: This will require a bit more work since we will need
1279 to ensure that the source physical address is doubleword aligned
1280 before, and then deal with trailing bytes. */
1281 for (index = 0; (index < size); index++) {
1282 uword64 vaddr,paddr,value;
1283 int cca;
1284 vaddr = (uword64)addr + index;
1285 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&cca,isTARGET,isRAW)) {
1286 LoadMemory(&value,NULL,cca,AccessLength_BYTE,paddr,vaddr,isDATA,isRAW);
1287 buffer[index] = (unsigned char)(value&0xFF);
1288 } else
1289 break;
1290 }
1291
1292 return(index);
1293 }
1294
1295 void
1296 sim_store_register (sd,rn,memory)
1297 SIM_DESC sd;
1298 int rn;
1299 unsigned char *memory;
1300 {
1301 /* NOTE: gdb (the client) stores registers in target byte order
1302 while the simulator uses host byte order */
1303 #ifdef DEBUG
1304 callback->printf_filtered(callback,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
1305 #endif /* DEBUG */
1306
1307 /* Unfortunately this suffers from the same problem as the register
1308 numbering one. We need to know what the width of each logical
1309 register number is for the architecture being simulated. */
1310
1311 if (register_widths[rn] == 0)
1312 sim_warning("Invalid register width for %d (register store ignored)",rn);
1313 else
1314 {
1315 if (register_widths[rn] == 32)
1316 registers[rn] = T2H_4 (*(unsigned int*)memory);
1317 else
1318 registers[rn] = T2H_8 (*(uword64*)memory);
1319 }
1320
1321 return;
1322 }
1323
1324 void
1325 sim_fetch_register (sd,rn,memory)
1326 SIM_DESC sd;
1327 int rn;
1328 unsigned char *memory;
1329 {
1330 /* NOTE: gdb (the client) stores registers in target byte order
1331 while the simulator uses host byte order */
1332 #ifdef DEBUG
1333 callback->printf_filtered(callback,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
1334 #endif /* DEBUG */
1335
1336 if (register_widths[rn] == 0)
1337 sim_warning("Invalid register width for %d (register fetch ignored)",rn);
1338 else
1339 {
1340 if (register_widths[rn] == 32)
1341 *((unsigned int *)memory) = H2T_4 ((unsigned int)(registers[rn] & 0xFFFFFFFF));
1342 else /* 64bit register */
1343 *((uword64 *)memory) = H2T_8 (registers[rn]);
1344 }
1345
1346 return;
1347 }
1348
1349
1350 void
1351 sim_info (sd,verbose)
1352 SIM_DESC sd;
1353 int verbose;
1354 {
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 defined(HASFPU)
2021 if (aregs == 5)
2022 {
2023 FGR[0] = WORD64LO (GPR[4]);
2024 fpr_state[0] = fmt_uninterpreted;
2025 }
2026 else if (aregs == 6)
2027 {
2028 FGR[0] = WORD64LO (GPR[5]);
2029 FGR[1] = WORD64LO (GPR[4]);
2030 fpr_state[0] = fmt_uninterpreted;
2031 fpr_state[1] = fmt_uninterpreted;
2032 }
2033 #endif /* defined(HASFPU) */
2034
2035 PC = RA;
2036 }
2037 }
2038
2039 void
2040 sim_warning(char *fmt,...)
2041 {
2042 char buf[256];
2043 va_list ap;
2044
2045 va_start (ap,fmt);
2046 vsprintf (buf, fmt, ap);
2047 va_end (ap);
2048
2049 if (logfh != NULL) {
2050 fprintf(logfh,"SIM Warning: %s\n", buf);
2051 } else {
2052 callback->printf_filtered(callback,"SIM Warning: %s\n", buf);
2053 }
2054 /* This used to call SignalException with a SimulatorFault, but that causes
2055 the simulator to exit, and that is inappropriate for a warning. */
2056 return;
2057 }
2058
2059 void
2060 sim_error(char *fmt,...)
2061 {
2062 char buf[256];
2063 va_list ap;
2064
2065 va_start (ap,fmt);
2066 vsprintf (buf, fmt, ap);
2067 va_end (ap);
2068
2069 callback->printf_filtered(callback,"SIM Error: %s", buf);
2070 SignalException (SimulatorFault, buf);
2071 return;
2072 }
2073
2074 static unsigned int
2075 power2(value)
2076 unsigned int value;
2077 {
2078 int loop,tmp;
2079
2080 /* Round *UP* to the nearest power-of-2 if not already one */
2081 if (value != (value & ~(value - 1))) {
2082 for (tmp = value, loop = 0; (tmp != 0); loop++)
2083 tmp >>= 1;
2084 value = (1 << loop);
2085 }
2086
2087 return(value);
2088 }
2089
2090 static long
2091 getnum(value)
2092 char *value;
2093 {
2094 long num;
2095 char *end;
2096
2097 num = strtol(value,&end,10);
2098 if (end == value)
2099 callback->printf_filtered(callback,"Warning: Invalid number \"%s\" ignored, using zero\n",value);
2100 else {
2101 if (*end && ((tolower(*end) == 'k') || (tolower(*end) == 'm'))) {
2102 if (tolower(*end) == 'k')
2103 num *= (1 << 10);
2104 else
2105 num *= (1 << 20);
2106 end++;
2107 }
2108 if (*end)
2109 callback->printf_filtered(callback,"Warning: Spurious characters \"%s\" at end of number ignored\n",end);
2110 }
2111
2112 return(num);
2113 }
2114
2115 /*-- trace support ----------------------------------------------------------*/
2116
2117 /* The TRACE support is provided (if required) in the memory accessing
2118 routines. Since we are also providing the architecture specific
2119 features, the architecture simulation code can also deal with
2120 notifying the TRACE world of cache flushes, etc. Similarly we do
2121 not need to provide profiling support in the simulator engine,
2122 since we can sample in the instruction fetch control loop. By
2123 defining the TRACE manifest, we add tracing as a run-time
2124 option. */
2125
2126 #if defined(TRACE)
2127 /* Tracing by default produces "din" format (as required by
2128 dineroIII). Each line of such a trace file *MUST* have a din label
2129 and address field. The rest of the line is ignored, so comments can
2130 be included if desired. The first field is the label which must be
2131 one of the following values:
2132
2133 0 read data
2134 1 write data
2135 2 instruction fetch
2136 3 escape record (treated as unknown access type)
2137 4 escape record (causes cache flush)
2138
2139 The address field is a 32bit (lower-case) hexadecimal address
2140 value. The address should *NOT* be preceded by "0x".
2141
2142 The size of the memory transfer is not important when dealing with
2143 cache lines (as long as no more than a cache line can be
2144 transferred in a single operation :-), however more information
2145 could be given following the dineroIII requirement to allow more
2146 complete memory and cache simulators to provide better
2147 results. i.e. the University of Pisa has a cache simulator that can
2148 also take bus size and speed as (variable) inputs to calculate
2149 complete system performance (a much more useful ability when trying
2150 to construct an end product, rather than a processor). They
2151 currently have an ARM version of their tool called ChARM. */
2152
2153
2154 static
2155 void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
2156 {
2157 if (state & simTRACE) {
2158 va_list ap;
2159 fprintf(tracefh,"%d %s ; width %d ; ",
2160 type,
2161 pr_addr(address),
2162 width);
2163 va_start(ap,comment);
2164 vfprintf(tracefh,comment,ap);
2165 va_end(ap);
2166 fprintf(tracefh,"\n");
2167 }
2168 /* NOTE: Since the "din" format will only accept 32bit addresses, and
2169 we may be generating 64bit ones, we should put the hi-32bits of the
2170 address into the comment field. */
2171
2172 /* TODO: Provide a buffer for the trace lines. We can then avoid
2173 performing writes until the buffer is filled, or the file is
2174 being closed. */
2175
2176 /* NOTE: We could consider adding a comment field to the "din" file
2177 produced using type 3 markers (unknown access). This would then
2178 allow information about the program that the "din" is for, and
2179 the MIPs world that was being simulated, to be placed into the
2180 trace file. */
2181
2182 return;
2183 }
2184 #endif /* TRACE */
2185
2186 /*---------------------------------------------------------------------------*/
2187 /*-- simulator engine -------------------------------------------------------*/
2188 /*---------------------------------------------------------------------------*/
2189
2190 static void
2191 ColdReset()
2192 {
2193 /* RESET: Fixed PC address: */
2194 PC = (((uword64)0xFFFFFFFF<<32) | 0xBFC00000);
2195 /* The reset vector address is in the unmapped, uncached memory space. */
2196
2197 SR &= ~(status_SR | status_TS | status_RP);
2198 SR |= (status_ERL | status_BEV);
2199
2200 #if defined(HASFPU) && (GPRLEN == (64))
2201 /* Cheat and allow access to the complete register set immediately: */
2202 SR |= status_FR; /* 64bit registers */
2203 #endif /* HASFPU and 64bit FP registers */
2204
2205 /* Ensure that any instructions with pending register updates are
2206 cleared: */
2207 {
2208 int loop;
2209 for (loop = 0; (loop < PSLOTS); loop++)
2210 pending_slot_reg[loop] = (LAST_EMBED_REGNUM + 1);
2211 pending_in = pending_out = pending_total = 0;
2212 }
2213
2214 #if defined(HASFPU)
2215 /* Initialise the FPU registers to the unknown state */
2216 {
2217 int rn;
2218 for (rn = 0; (rn < 32); rn++)
2219 fpr_state[rn] = fmt_uninterpreted;
2220 }
2221 #endif /* HASFPU */
2222
2223 return;
2224 }
2225
2226 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2227 /* Translate a virtual address to a physical address and cache
2228 coherence algorithm describing the mechanism used to resolve the
2229 memory reference. Given the virtual address vAddr, and whether the
2230 reference is to Instructions ot Data (IorD), find the corresponding
2231 physical address (pAddr) and the cache coherence algorithm (CCA)
2232 used to resolve the reference. If the virtual address is in one of
2233 the unmapped address spaces the physical address and the CCA are
2234 determined directly by the virtual address. If the virtual address
2235 is in one of the mapped address spaces then the TLB is used to
2236 determine the physical address and access type; if the required
2237 translation is not present in the TLB or the desired access is not
2238 permitted the function fails and an exception is taken.
2239
2240 NOTE: This function is extended to return an exception state. This,
2241 along with the exception generation is used to notify whether a
2242 valid address translation occured */
2243
2244 static int
2245 AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw)
2246 uword64 vAddr;
2247 int IorD;
2248 int LorS;
2249 uword64 *pAddr;
2250 int *CCA;
2251 int host;
2252 int raw;
2253 {
2254 SIM_DESC sd = &simulator;
2255 int res = -1; /* TRUE : Assume good return */
2256
2257 #ifdef DEBUG
2258 callback->printf_filtered(callback,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
2259 #endif
2260
2261 /* Check that the address is valid for this memory model */
2262
2263 /* For a simple (flat) memory model, we simply pass virtual
2264 addressess through (mostly) unchanged. */
2265 vAddr &= 0xFFFFFFFF;
2266
2267 /* Treat the kernel memory spaces identically for the moment: */
2268 if ((STATE_MEM_BASE (sd) == K1BASE) && (vAddr >= K0BASE) && (vAddr < (K0BASE + K0SIZE)))
2269 vAddr += (K1BASE - K0BASE);
2270
2271 /* Also assume that the K1BASE memory wraps. This is required to
2272 allow the PMON run-time __sizemem() routine to function (without
2273 having to provide exception simulation). NOTE: A kludge to work
2274 around the fact that the monitor memory is currently held in the
2275 K1BASE space. */
2276 if (((vAddr < monitor_base) || (vAddr >= (monitor_base + monitor_size))) && (vAddr >= K1BASE && vAddr < (K1BASE + K1SIZE)))
2277 vAddr = (K1BASE | (vAddr & (STATE_MEM_SIZE (sd) - 1)));
2278
2279 *pAddr = vAddr; /* default for isTARGET */
2280 *CCA = Uncached; /* not used for isHOST */
2281
2282 /* NOTE: This is a duplicate of the code that appears in the
2283 LoadMemory and StoreMemory functions. They should be merged into
2284 a single function (that can be in-lined if required). */
2285 if ((vAddr >= STATE_MEM_BASE (sd)) && (vAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2286 if (host)
2287 *pAddr = (int)&STATE_MEMORY (sd)[((unsigned int)(vAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1))];
2288 } else if ((vAddr >= monitor_base) && (vAddr < (monitor_base + monitor_size))) {
2289 if (host)
2290 *pAddr = (int)&monitor[((unsigned int)(vAddr - monitor_base) & (monitor_size - 1))];
2291 } else {
2292 #ifdef DEBUG
2293 sim_warning("Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC));
2294 #endif /* DEBUG */
2295 res = 0; /* AddressTranslation has failed */
2296 *pAddr = (SIM_ADDR)-1;
2297 if (!raw) /* only generate exceptions on real memory transfers */
2298 SignalException((LorS == isSTORE) ? AddressStore : AddressLoad);
2299 #ifdef DEBUG
2300 else
2301 /* This is a normal occurance during gdb operation, for instance trying
2302 to print parameters at function start before they have been setup,
2303 and hence we should not print a warning except when debugging the
2304 simulator. */
2305 sim_warning("AddressTranslation for %s %s from 0x%s failed",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
2306 #endif
2307 }
2308
2309 return(res);
2310 }
2311
2312 /* Description from page A-23 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2313 /* Prefetch data from memory. Prefetch is an advisory instruction for
2314 which an implementation specific action is taken. The action taken
2315 may increase performance, but must not change the meaning of the
2316 program, or alter architecturally-visible state. */
2317
2318 static void UNUSED
2319 Prefetch(CCA,pAddr,vAddr,DATA,hint)
2320 int CCA;
2321 uword64 pAddr;
2322 uword64 vAddr;
2323 int DATA;
2324 int hint;
2325 {
2326 #ifdef DEBUG
2327 callback->printf_filtered(callback,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
2328 #endif /* DEBUG */
2329
2330 /* For our simple memory model we do nothing */
2331 return;
2332 }
2333
2334 /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2335 /* Load a value from memory. Use the cache and main memory as
2336 specified in the Cache Coherence Algorithm (CCA) and the sort of
2337 access (IorD) to find the contents of AccessLength memory bytes
2338 starting at physical location pAddr. The data is returned in the
2339 fixed width naturally-aligned memory element (MemElem). The
2340 low-order two (or three) bits of the address and the AccessLength
2341 indicate which of the bytes within MemElem needs to be given to the
2342 processor. If the memory access type of the reference is uncached
2343 then only the referenced bytes are read from memory and valid
2344 within the memory element. If the access type is cached, and the
2345 data is not present in cache, an implementation specific size and
2346 alignment block of memory is read and loaded into the cache to
2347 satisfy a load reference. At a minimum, the block is the entire
2348 memory element. */
2349 static void
2350 LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
2351 uword64* memvalp;
2352 uword64* memval1p;
2353 int CCA;
2354 int AccessLength;
2355 uword64 pAddr;
2356 uword64 vAddr;
2357 int IorD;
2358 int raw;
2359 {
2360 SIM_DESC sd = &simulator;
2361 uword64 value = 0;
2362 uword64 value1 = 0;
2363
2364 #ifdef DEBUG
2365 if (STATE_MEMORY (sd) == NULL)
2366 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"));
2367 #endif /* DEBUG */
2368
2369 #if defined(WARN_MEM)
2370 if (CCA != uncached)
2371 sim_warning("LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
2372
2373 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) {
2374 /* In reality this should be a Bus Error */
2375 sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
2376 }
2377 #endif /* WARN_MEM */
2378
2379 /* Decide which physical memory locations are being dealt with. At
2380 this point we should be able to split the pAddr bits into the
2381 relevant address map being simulated. If the "raw" variable is
2382 set, the memory read being performed should *NOT* update any I/O
2383 state or affect the CPU state. This also includes avoiding
2384 affecting statistics gathering. */
2385
2386 /* If instruction fetch then we need to check that the two lo-order
2387 bits are zero, otherwise raise a InstructionFetch exception: */
2388 if ((IorD == isINSTRUCTION)
2389 && ((pAddr & 0x3) != 0)
2390 && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
2391 SignalException(InstructionFetch);
2392 else {
2393 unsigned int index = 0;
2394 unsigned char *mem = NULL;
2395
2396 #if defined(TRACE)
2397 if (!raw)
2398 dotrace(tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
2399 #endif /* TRACE */
2400
2401 /* NOTE: Quicker methods of decoding the address space can be used
2402 when a real memory map is being simulated (i.e. using hi-order
2403 address bits to select device). */
2404 if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2405 index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1));
2406 mem = STATE_MEMORY (sd);
2407 } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) {
2408 index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1));
2409 mem = monitor;
2410 }
2411 if (mem == NULL)
2412 sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
2413 else {
2414 /* If we obtained the endianness of the host, and it is the same
2415 as the target memory system we can optimise the memory
2416 accesses. However, without that information we must perform
2417 slow transfer, and hope that the compiler optimisation will
2418 merge successive loads. */
2419
2420 /* In reality we should always be loading a doubleword value (or
2421 word value in 32bit memory worlds). The external code then
2422 extracts the required bytes. However, to keep performance
2423 high we only load the required bytes into the relevant
2424 slots. */
2425 if (BigEndianMem)
2426 switch (AccessLength) { /* big-endian memory */
2427 case AccessLength_QUADWORD :
2428 value1 |= ((uword64)mem[index++] << 56);
2429 case 14: /* AccessLength is one less than datalen */
2430 value1 |= ((uword64)mem[index++] << 48);
2431 case 13:
2432 value1 |= ((uword64)mem[index++] << 40);
2433 case 12:
2434 value1 |= ((uword64)mem[index++] << 32);
2435 case 11:
2436 value1 |= ((unsigned int)mem[index++] << 24);
2437 case 10:
2438 value1 |= ((unsigned int)mem[index++] << 16);
2439 case 9:
2440 value1 |= ((unsigned int)mem[index++] << 8);
2441 case 8:
2442 value1 |= mem[index];
2443
2444 case AccessLength_DOUBLEWORD :
2445 value |= ((uword64)mem[index++] << 56);
2446 case AccessLength_SEPTIBYTE :
2447 value |= ((uword64)mem[index++] << 48);
2448 case AccessLength_SEXTIBYTE :
2449 value |= ((uword64)mem[index++] << 40);
2450 case AccessLength_QUINTIBYTE :
2451 value |= ((uword64)mem[index++] << 32);
2452 case AccessLength_WORD :
2453 value |= ((unsigned int)mem[index++] << 24);
2454 case AccessLength_TRIPLEBYTE :
2455 value |= ((unsigned int)mem[index++] << 16);
2456 case AccessLength_HALFWORD :
2457 value |= ((unsigned int)mem[index++] << 8);
2458 case AccessLength_BYTE :
2459 value |= mem[index];
2460 break;
2461 }
2462 else {
2463 index += (AccessLength + 1);
2464 switch (AccessLength) { /* little-endian memory */
2465 case AccessLength_QUADWORD :
2466 value1 |= ((uword64)mem[--index] << 56);
2467 case 14: /* AccessLength is one less than datalen */
2468 value1 |= ((uword64)mem[--index] << 48);
2469 case 13:
2470 value1 |= ((uword64)mem[--index] << 40);
2471 case 12:
2472 value1 |= ((uword64)mem[--index] << 32);
2473 case 11:
2474 value1 |= ((uword64)mem[--index] << 24);
2475 case 10:
2476 value1 |= ((uword64)mem[--index] << 16);
2477 case 9:
2478 value1 |= ((uword64)mem[--index] << 8);
2479 case 8:
2480 value1 |= ((uword64)mem[--index] << 0);
2481
2482 case AccessLength_DOUBLEWORD :
2483 value |= ((uword64)mem[--index] << 56);
2484 case AccessLength_SEPTIBYTE :
2485 value |= ((uword64)mem[--index] << 48);
2486 case AccessLength_SEXTIBYTE :
2487 value |= ((uword64)mem[--index] << 40);
2488 case AccessLength_QUINTIBYTE :
2489 value |= ((uword64)mem[--index] << 32);
2490 case AccessLength_WORD :
2491 value |= ((uword64)mem[--index] << 24);
2492 case AccessLength_TRIPLEBYTE :
2493 value |= ((uword64)mem[--index] << 16);
2494 case AccessLength_HALFWORD :
2495 value |= ((uword64)mem[--index] << 8);
2496 case AccessLength_BYTE :
2497 value |= ((uword64)mem[--index] << 0);
2498 break;
2499 }
2500 }
2501
2502 #ifdef DEBUG
2503 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
2504 (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
2505 #endif /* DEBUG */
2506
2507 /* TODO: We could try and avoid the shifts when dealing with raw
2508 memory accesses. This would mean updating the LoadMemory and
2509 StoreMemory routines to avoid shifting the data before
2510 returning or using it. */
2511 if (AccessLength <= AccessLength_DOUBLEWORD) {
2512 if (!raw) { /* do nothing for raw accessess */
2513 if (BigEndianMem)
2514 value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
2515 else /* little-endian only needs to be shifted up to the correct byte offset */
2516 value <<= ((pAddr & LOADDRMASK) * 8);
2517 }
2518 }
2519
2520 #ifdef DEBUG
2521 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
2522 pr_uword64(value1),pr_uword64(value));
2523 #endif /* DEBUG */
2524 }
2525 }
2526
2527 *memvalp = value;
2528 if (memval1p) *memval1p = value1;
2529 }
2530
2531
2532 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
2533 (revision 3.1) */
2534 /* Store a value to memory. The specified data is stored into the
2535 physical location pAddr using the memory hierarchy (data caches and
2536 main memory) as specified by the Cache Coherence Algorithm
2537 (CCA). The MemElem contains the data for an aligned, fixed-width
2538 memory element (word for 32-bit processors, doubleword for 64-bit
2539 processors), though only the bytes that will actually be stored to
2540 memory need to be valid. The low-order two (or three) bits of pAddr
2541 and the AccessLength field indicates which of the bytes within the
2542 MemElem data should actually be stored; only these bytes in memory
2543 will be changed. */
2544
2545 static void
2546 StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
2547 int CCA;
2548 int AccessLength;
2549 uword64 MemElem;
2550 uword64 MemElem1; /* High order 64 bits */
2551 uword64 pAddr;
2552 uword64 vAddr;
2553 int raw;
2554 {
2555 SIM_DESC sd = &simulator;
2556 #ifdef DEBUG
2557 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"));
2558 #endif /* DEBUG */
2559
2560 #if defined(WARN_MEM)
2561 if (CCA != uncached)
2562 sim_warning("StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
2563
2564 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
2565 sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
2566 #endif /* WARN_MEM */
2567
2568 #if defined(TRACE)
2569 if (!raw)
2570 dotrace(tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
2571 #endif /* TRACE */
2572
2573 /* See the comments in the LoadMemory routine about optimising
2574 memory accesses. Also if we wanted to make the simulator smaller,
2575 we could merge a lot of this code with the LoadMemory
2576 routine. However, this would slow the simulator down with
2577 run-time conditionals. */
2578 {
2579 unsigned int index = 0;
2580 unsigned char *mem = NULL;
2581
2582 if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
2583 index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1));
2584 mem = STATE_MEMORY (sd);
2585 } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) {
2586 index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1));
2587 mem = monitor;
2588 }
2589
2590 if (mem == NULL)
2591 sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
2592 else {
2593 int shift = 0;
2594
2595 #ifdef DEBUG
2596 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
2597 #endif /* DEBUG */
2598
2599 if (AccessLength <= AccessLength_DOUBLEWORD) {
2600 if (BigEndianMem) {
2601 if (raw)
2602 shift = ((7 - AccessLength) * 8);
2603 else /* real memory access */
2604 shift = ((pAddr & LOADDRMASK) * 8);
2605 MemElem <<= shift;
2606 } else {
2607 /* no need to shift raw little-endian data */
2608 if (!raw)
2609 MemElem >>= ((pAddr & LOADDRMASK) * 8);
2610 }
2611 }
2612
2613 #ifdef DEBUG
2614 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
2615 #endif /* DEBUG */
2616
2617 if (BigEndianMem) {
2618 switch (AccessLength) { /* big-endian memory */
2619 case AccessLength_QUADWORD :
2620 mem[index++] = (unsigned char)(MemElem1 >> 56);
2621 MemElem1 <<= 8;
2622 case 14 :
2623 mem[index++] = (unsigned char)(MemElem1 >> 56);
2624 MemElem1 <<= 8;
2625 case 13 :
2626 mem[index++] = (unsigned char)(MemElem1 >> 56);
2627 MemElem1 <<= 8;
2628 case 12 :
2629 mem[index++] = (unsigned char)(MemElem1 >> 56);
2630 MemElem1 <<= 8;
2631 case 11 :
2632 mem[index++] = (unsigned char)(MemElem1 >> 56);
2633 MemElem1 <<= 8;
2634 case 10 :
2635 mem[index++] = (unsigned char)(MemElem1 >> 56);
2636 MemElem1 <<= 8;
2637 case 9 :
2638 mem[index++] = (unsigned char)(MemElem1 >> 56);
2639 MemElem1 <<= 8;
2640 case 8 :
2641 mem[index++] = (unsigned char)(MemElem1 >> 56);
2642
2643 case AccessLength_DOUBLEWORD :
2644 mem[index++] = (unsigned char)(MemElem >> 56);
2645 MemElem <<= 8;
2646 case AccessLength_SEPTIBYTE :
2647 mem[index++] = (unsigned char)(MemElem >> 56);
2648 MemElem <<= 8;
2649 case AccessLength_SEXTIBYTE :
2650 mem[index++] = (unsigned char)(MemElem >> 56);
2651 MemElem <<= 8;
2652 case AccessLength_QUINTIBYTE :
2653 mem[index++] = (unsigned char)(MemElem >> 56);
2654 MemElem <<= 8;
2655 case AccessLength_WORD :
2656 mem[index++] = (unsigned char)(MemElem >> 56);
2657 MemElem <<= 8;
2658 case AccessLength_TRIPLEBYTE :
2659 mem[index++] = (unsigned char)(MemElem >> 56);
2660 MemElem <<= 8;
2661 case AccessLength_HALFWORD :
2662 mem[index++] = (unsigned char)(MemElem >> 56);
2663 MemElem <<= 8;
2664 case AccessLength_BYTE :
2665 mem[index++] = (unsigned char)(MemElem >> 56);
2666 break;
2667 }
2668 } else {
2669 index += (AccessLength + 1);
2670 switch (AccessLength) { /* little-endian memory */
2671 case AccessLength_QUADWORD :
2672 mem[--index] = (unsigned char)(MemElem1 >> 56);
2673 case 14 :
2674 mem[--index] = (unsigned char)(MemElem1 >> 48);
2675 case 13 :
2676 mem[--index] = (unsigned char)(MemElem1 >> 40);
2677 case 12 :
2678 mem[--index] = (unsigned char)(MemElem1 >> 32);
2679 case 11 :
2680 mem[--index] = (unsigned char)(MemElem1 >> 24);
2681 case 10 :
2682 mem[--index] = (unsigned char)(MemElem1 >> 16);
2683 case 9 :
2684 mem[--index] = (unsigned char)(MemElem1 >> 8);
2685 case 8 :
2686 mem[--index] = (unsigned char)(MemElem1 >> 0);
2687
2688 case AccessLength_DOUBLEWORD :
2689 mem[--index] = (unsigned char)(MemElem >> 56);
2690 case AccessLength_SEPTIBYTE :
2691 mem[--index] = (unsigned char)(MemElem >> 48);
2692 case AccessLength_SEXTIBYTE :
2693 mem[--index] = (unsigned char)(MemElem >> 40);
2694 case AccessLength_QUINTIBYTE :
2695 mem[--index] = (unsigned char)(MemElem >> 32);
2696 case AccessLength_WORD :
2697 mem[--index] = (unsigned char)(MemElem >> 24);
2698 case AccessLength_TRIPLEBYTE :
2699 mem[--index] = (unsigned char)(MemElem >> 16);
2700 case AccessLength_HALFWORD :
2701 mem[--index] = (unsigned char)(MemElem >> 8);
2702 case AccessLength_BYTE :
2703 mem[--index] = (unsigned char)(MemElem >> 0);
2704 break;
2705 }
2706 }
2707 }
2708 }
2709
2710 return;
2711 }
2712
2713
2714 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2715 /* Order loads and stores to synchronise shared memory. Perform the
2716 action necessary to make the effects of groups of synchronizable
2717 loads and stores indicated by stype occur in the same order for all
2718 processors. */
2719 static void
2720 SyncOperation(stype)
2721 int stype;
2722 {
2723 #ifdef DEBUG
2724 callback->printf_filtered(callback,"SyncOperation(%d) : TODO\n",stype);
2725 #endif /* DEBUG */
2726 return;
2727 }
2728
2729 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2730 /* Signal an exception condition. This will result in an exception
2731 that aborts the instruction. The instruction operation pseudocode
2732 will never see a return from this function call. */
2733
2734 static void
2735 SignalException (int exception,...)
2736 {
2737 int vector;
2738 SIM_DESC sd = &simulator;
2739 /* Ensure that any active atomic read/modify/write operation will fail: */
2740 LLBIT = 0;
2741
2742 switch (exception) {
2743 /* TODO: For testing purposes I have been ignoring TRAPs. In
2744 reality we should either simulate them, or allow the user to
2745 ignore them at run-time. */
2746 case Trap :
2747 sim_warning("Ignoring instruction TRAP (PC 0x%s)",pr_addr(IPC));
2748 break;
2749
2750 case ReservedInstruction :
2751 {
2752 va_list ap;
2753 unsigned int instruction;
2754 va_start(ap,exception);
2755 instruction = va_arg(ap,unsigned int);
2756 va_end(ap);
2757 /* Provide simple monitor support using ReservedInstruction
2758 exceptions. The following code simulates the fixed vector
2759 entry points into the IDT monitor by causing a simulator
2760 trap, performing the monitor operation, and returning to
2761 the address held in the $ra register (standard PCS return
2762 address). This means we only need to pre-load the vector
2763 space with suitable instruction values. For systems were
2764 actual trap instructions are used, we would not need to
2765 perform this magic. */
2766 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) {
2767 sim_monitor( ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
2768 PC = RA; /* simulate the return from the vector entry */
2769 /* NOTE: This assumes that a branch-and-link style
2770 instruction was used to enter the vector (which is the
2771 case with the current IDT monitor). */
2772 sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
2773 }
2774 /* Look for the mips16 entry and exit instructions, and
2775 simulate a handler for them. */
2776 else if ((IPC & 1) != 0
2777 && (instruction & 0xf81f) == 0xe809
2778 && (instruction & 0x0c0) != 0x0c0) {
2779 mips16_entry (instruction);
2780 sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
2781 } /* else fall through to normal exception processing */
2782 sim_warning("ReservedInstruction 0x%08X at IPC = 0x%s",instruction,pr_addr(IPC));
2783 }
2784
2785 case BreakPoint:
2786 #ifdef DEBUG
2787 callback->printf_filtered(callback,"DBG: SignalException(%d) IPC = 0x%s\n",exception,pr_addr(IPC));
2788 #endif /* DEBUG */
2789 /* Keep a copy of the current A0 in-case this is the program exit
2790 breakpoint: */
2791 {
2792 va_list ap;
2793 unsigned int instruction;
2794 va_start(ap,exception);
2795 instruction = va_arg(ap,unsigned int);
2796 va_end(ap);
2797 /* Check for our special terminating BREAK: */
2798 if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
2799 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2800 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
2801 }
2802 }
2803 if (state & simDELAYSLOT)
2804 PC = IPC - 4; /* reference the branch instruction */
2805 else
2806 PC = IPC;
2807 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2808 sim_stopped, SIGTRAP);
2809
2810 default:
2811 /* Store exception code into current exception id variable (used
2812 by exit code): */
2813
2814 /* TODO: If not simulating exceptions then stop the simulator
2815 execution. At the moment we always stop the simulation. */
2816
2817 /* See figure 5-17 for an outline of the code below */
2818 if (! (SR & status_EXL))
2819 {
2820 CAUSE = (exception << 2);
2821 if (state & simDELAYSLOT)
2822 {
2823 state &= ~simDELAYSLOT;
2824 CAUSE |= cause_BD;
2825 EPC = (IPC - 4); /* reference the branch instruction */
2826 }
2827 else
2828 EPC = IPC;
2829 /* FIXME: TLB et.al. */
2830 vector = 0x180;
2831 }
2832 else
2833 {
2834 CAUSE = (exception << 2);
2835 vector = 0x180;
2836 }
2837 SR |= status_EXL;
2838 /* Store exception code into current exception id variable (used
2839 by exit code): */
2840 if (SR & status_BEV)
2841 PC = (signed)0xBFC00200 + 0x180;
2842 else
2843 PC = (signed)0x80000000 + 0x180;
2844
2845 switch ((CAUSE >> 2) & 0x1F)
2846 {
2847 case Interrupt:
2848 /* Interrupts arrive during event processing, no need to
2849 restart */
2850 return;
2851
2852 case TLBModification:
2853 case TLBLoad:
2854 case TLBStore:
2855 case AddressLoad:
2856 case AddressStore:
2857 case InstructionFetch:
2858 case DataReference:
2859 /* The following is so that the simulator will continue from the
2860 exception address on breakpoint operations. */
2861 PC = EPC;
2862 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2863 sim_stopped, SIGBUS);
2864
2865 case ReservedInstruction:
2866 case CoProcessorUnusable:
2867 PC = EPC;
2868 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2869 sim_stopped, SIGILL);
2870
2871 case IntegerOverflow:
2872 case FPE:
2873 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2874 sim_stopped, SIGFPE);
2875
2876 case Trap:
2877 case Watch:
2878 case SystemCall:
2879 PC = EPC;
2880 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2881 sim_stopped, SIGTRAP);
2882
2883 case BreakPoint:
2884 PC = EPC;
2885 sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
2886 "FATAL: Should not encounter a breakpoint\n");
2887
2888 default : /* Unknown internal exception */
2889 PC = EPC;
2890 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
2891 sim_stopped, SIGQUIT);
2892
2893 }
2894
2895 case SimulatorFault:
2896 {
2897 va_list ap;
2898 char *msg;
2899 va_start(ap,exception);
2900 msg = va_arg(ap,char *);
2901 va_end(ap);
2902 sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
2903 "FATAL: Simulator error \"%s\"\n",msg);
2904 }
2905 }
2906
2907 return;
2908 }
2909
2910 #if defined(WARN_RESULT)
2911 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2912 /* This function indicates that the result of the operation is
2913 undefined. However, this should not affect the instruction
2914 stream. All that is meant to happen is that the destination
2915 register is set to an undefined result. To keep the simulator
2916 simple, we just don't bother updating the destination register, so
2917 the overall result will be undefined. If desired we can stop the
2918 simulator by raising a pseudo-exception. */
2919 static void
2920 UndefinedResult()
2921 {
2922 sim_warning("UndefinedResult: IPC = 0x%s",pr_addr(IPC));
2923 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2924 state |= simSTOP;
2925 #endif
2926 return;
2927 }
2928 #endif /* WARN_RESULT */
2929
2930 static void UNUSED
2931 CacheOp(op,pAddr,vAddr,instruction)
2932 int op;
2933 uword64 pAddr;
2934 uword64 vAddr;
2935 unsigned int instruction;
2936 {
2937 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2938 static int icache_warning = 1;
2939 static int dcache_warning = 1;
2940 #else
2941 static int icache_warning = 0;
2942 static int dcache_warning = 0;
2943 #endif
2944
2945 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2946 enable bit in the Status Register is clear - a coprocessor
2947 unusable exception is taken. */
2948 #if 0
2949 callback->printf_filtered(callback,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(IPC));
2950 #endif
2951
2952 switch (op & 0x3) {
2953 case 0: /* instruction cache */
2954 switch (op >> 2) {
2955 case 0: /* Index Invalidate */
2956 case 1: /* Index Load Tag */
2957 case 2: /* Index Store Tag */
2958 case 4: /* Hit Invalidate */
2959 case 5: /* Fill */
2960 case 6: /* Hit Writeback */
2961 if (!icache_warning)
2962 {
2963 sim_warning("Instruction CACHE operation %d to be coded",(op >> 2));
2964 icache_warning = 1;
2965 }
2966 break;
2967
2968 default:
2969 SignalException(ReservedInstruction,instruction);
2970 break;
2971 }
2972 break;
2973
2974 case 1: /* data cache */
2975 switch (op >> 2) {
2976 case 0: /* Index Writeback Invalidate */
2977 case 1: /* Index Load Tag */
2978 case 2: /* Index Store Tag */
2979 case 3: /* Create Dirty */
2980 case 4: /* Hit Invalidate */
2981 case 5: /* Hit Writeback Invalidate */
2982 case 6: /* Hit Writeback */
2983 if (!dcache_warning)
2984 {
2985 sim_warning("Data CACHE operation %d to be coded",(op >> 2));
2986 dcache_warning = 1;
2987 }
2988 break;
2989
2990 default:
2991 SignalException(ReservedInstruction,instruction);
2992 break;
2993 }
2994 break;
2995
2996 default: /* unrecognised cache ID */
2997 SignalException(ReservedInstruction,instruction);
2998 break;
2999 }
3000
3001 return;
3002 }
3003
3004 /*-- FPU support routines ---------------------------------------------------*/
3005
3006 #if defined(HASFPU) /* Only needed when building FPU aware simulators */
3007
3008 #if 1
3009 #define SizeFGR() (GPRLEN)
3010 #else
3011 /* They depend on the CPU being simulated */
3012 #define SizeFGR() ((PROCESSOR_64BIT && ((SR & status_FR) == 1)) ? 64 : 32)
3013 #endif
3014
3015 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
3016 formats conform to ANSI/IEEE Std 754-1985. */
3017 /* SINGLE precision floating:
3018 * seeeeeeeefffffffffffffffffffffff
3019 * s = 1bit = sign
3020 * e = 8bits = exponent
3021 * f = 23bits = fraction
3022 */
3023 /* SINGLE precision fixed:
3024 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
3025 * s = 1bit = sign
3026 * i = 31bits = integer
3027 */
3028 /* DOUBLE precision floating:
3029 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
3030 * s = 1bit = sign
3031 * e = 11bits = exponent
3032 * f = 52bits = fraction
3033 */
3034 /* DOUBLE precision fixed:
3035 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
3036 * s = 1bit = sign
3037 * i = 63bits = integer
3038 */
3039
3040 /* Extract sign-bit: */
3041 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
3042 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
3043 /* Extract biased exponent: */
3044 #define FP_S_be(v) (((v) >> 23) & 0xFF)
3045 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
3046 /* Extract unbiased Exponent: */
3047 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
3048 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
3049 /* Extract complete fraction field: */
3050 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
3051 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
3052 /* Extract numbered fraction bit: */
3053 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
3054 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
3055
3056 /* Explicit QNaN values used when value required: */
3057 #define FPQNaN_SINGLE (0x7FBFFFFF)
3058 #define FPQNaN_WORD (0x7FFFFFFF)
3059 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
3060 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
3061
3062 /* Explicit Infinity values used when required: */
3063 #define FPINF_SINGLE (0x7F800000)
3064 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
3065
3066 #if 1 /* def DEBUG */
3067 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
3068 #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>"))))))
3069 #endif /* DEBUG */
3070
3071 static uword64
3072 ValueFPR(fpr,fmt)
3073 int fpr;
3074 FP_formats fmt;
3075 {
3076 uword64 value = 0;
3077 int err = 0;
3078
3079 /* Treat unused register values, as fixed-point 64bit values: */
3080 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
3081 #if 1
3082 /* If request to read data as "uninterpreted", then use the current
3083 encoding: */
3084 fmt = fpr_state[fpr];
3085 #else
3086 fmt = fmt_long;
3087 #endif
3088
3089 /* For values not yet accessed, set to the desired format: */
3090 if (fpr_state[fpr] == fmt_uninterpreted) {
3091 fpr_state[fpr] = fmt;
3092 #ifdef DEBUG
3093 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
3094 #endif /* DEBUG */
3095 }
3096 if (fmt != fpr_state[fpr]) {
3097 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));
3098 fpr_state[fpr] = fmt_unknown;
3099 }
3100
3101 if (fpr_state[fpr] == fmt_unknown) {
3102 /* Set QNaN value: */
3103 switch (fmt) {
3104 case fmt_single:
3105 value = FPQNaN_SINGLE;
3106 break;
3107
3108 case fmt_double:
3109 value = FPQNaN_DOUBLE;
3110 break;
3111
3112 case fmt_word:
3113 value = FPQNaN_WORD;
3114 break;
3115
3116 case fmt_long:
3117 value = FPQNaN_LONG;
3118 break;
3119
3120 default:
3121 err = -1;
3122 break;
3123 }
3124 } else if (SizeFGR() == 64) {
3125 switch (fmt) {
3126 case fmt_single:
3127 case fmt_word:
3128 value = (FGR[fpr] & 0xFFFFFFFF);
3129 break;
3130
3131 case fmt_uninterpreted:
3132 case fmt_double:
3133 case fmt_long:
3134 value = FGR[fpr];
3135 break;
3136
3137 default :
3138 err = -1;
3139 break;
3140 }
3141 } else {
3142 switch (fmt) {
3143 case fmt_single:
3144 case fmt_word:
3145 value = (FGR[fpr] & 0xFFFFFFFF);
3146 break;
3147
3148 case fmt_uninterpreted:
3149 case fmt_double:
3150 case fmt_long:
3151 if ((fpr & 1) == 0) { /* even registers only */
3152 value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
3153 } else {
3154 SignalException (ReservedInstruction, 0);
3155 }
3156 break;
3157
3158 default :
3159 err = -1;
3160 break;
3161 }
3162 }
3163
3164 if (err)
3165 SignalException(SimulatorFault,"Unrecognised FP format in ValueFPR()");
3166
3167 #ifdef DEBUG
3168 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());
3169 #endif /* DEBUG */
3170
3171 return(value);
3172 }
3173
3174 static void
3175 StoreFPR(fpr,fmt,value)
3176 int fpr;
3177 FP_formats fmt;
3178 uword64 value;
3179 {
3180 int err = 0;
3181
3182 #ifdef DEBUG
3183 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());
3184 #endif /* DEBUG */
3185
3186 if (SizeFGR() == 64) {
3187 switch (fmt) {
3188 case fmt_single :
3189 case fmt_word :
3190 FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
3191 fpr_state[fpr] = fmt;
3192 break;
3193
3194 case fmt_uninterpreted:
3195 case fmt_double :
3196 case fmt_long :
3197 FGR[fpr] = value;
3198 fpr_state[fpr] = fmt;
3199 break;
3200
3201 default :
3202 fpr_state[fpr] = fmt_unknown;
3203 err = -1;
3204 break;
3205 }
3206 } else {
3207 switch (fmt) {
3208 case fmt_single :
3209 case fmt_word :
3210 FGR[fpr] = (value & 0xFFFFFFFF);
3211 fpr_state[fpr] = fmt;
3212 break;
3213
3214 case fmt_uninterpreted:
3215 case fmt_double :
3216 case fmt_long :
3217 if ((fpr & 1) == 0) { /* even register number only */
3218 FGR[fpr+1] = (value >> 32);
3219 FGR[fpr] = (value & 0xFFFFFFFF);
3220 fpr_state[fpr + 1] = fmt;
3221 fpr_state[fpr] = fmt;
3222 } else {
3223 fpr_state[fpr] = fmt_unknown;
3224 fpr_state[fpr + 1] = fmt_unknown;
3225 SignalException (ReservedInstruction, 0);
3226 }
3227 break;
3228
3229 default :
3230 fpr_state[fpr] = fmt_unknown;
3231 err = -1;
3232 break;
3233 }
3234 }
3235 #if defined(WARN_RESULT)
3236 else
3237 UndefinedResult();
3238 #endif /* WARN_RESULT */
3239
3240 if (err)
3241 SignalException(SimulatorFault,"Unrecognised FP format in StoreFPR()");
3242
3243 #ifdef DEBUG
3244 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
3245 #endif /* DEBUG */
3246
3247 return;
3248 }
3249
3250 static int
3251 NaN(op,fmt)
3252 uword64 op;
3253 FP_formats fmt;
3254 {
3255 int boolean = 0;
3256
3257 /* Check if (((E - bias) == (E_max + 1)) && (fraction != 0)). We
3258 know that the exponent field is biased... we we cheat and avoid
3259 removing the bias value. */
3260 switch (fmt) {
3261 case fmt_single:
3262 boolean = ((FP_S_be(op) == 0xFF) && (FP_S_f(op) != 0));
3263 /* We could use "FP_S_fb(1,op)" to ascertain whether we are
3264 dealing with a SNaN or QNaN */
3265 break;
3266 case fmt_double:
3267 boolean = ((FP_D_be(op) == 0x7FF) && (FP_D_f(op) != 0));
3268 /* We could use "FP_S_fb(1,op)" to ascertain whether we are
3269 dealing with a SNaN or QNaN */
3270 break;
3271 case fmt_word:
3272 boolean = (op == FPQNaN_WORD);
3273 break;
3274 case fmt_long:
3275 boolean = (op == FPQNaN_LONG);
3276 break;
3277 default:
3278 fprintf (stderr, "Bad switch\n");
3279 abort ();
3280 }
3281
3282 #ifdef DEBUG
3283 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
3284 #endif /* DEBUG */
3285
3286 return(boolean);
3287 }
3288
3289 static int
3290 Infinity(op,fmt)
3291 uword64 op;
3292 FP_formats fmt;
3293 {
3294 int boolean = 0;
3295
3296 #ifdef DEBUG
3297 printf("DBG: Infinity: format %s 0x%s (PC = 0x%s)\n",DOFMT(fmt),pr_addr(op),pr_addr(IPC));
3298 #endif /* DEBUG */
3299
3300 /* Check if (((E - bias) == (E_max + 1)) && (fraction == 0)). We
3301 know that the exponent field is biased... we we cheat and avoid
3302 removing the bias value. */
3303 switch (fmt) {
3304 case fmt_single:
3305 boolean = ((FP_S_be(op) == 0xFF) && (FP_S_f(op) == 0));
3306 break;
3307 case fmt_double:
3308 boolean = ((FP_D_be(op) == 0x7FF) && (FP_D_f(op) == 0));
3309 break;
3310 default:
3311 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
3312 break;
3313 }
3314
3315 #ifdef DEBUG
3316 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
3317 #endif /* DEBUG */
3318
3319 return(boolean);
3320 }
3321
3322 static int
3323 Less(op1,op2,fmt)
3324 uword64 op1;
3325 uword64 op2;
3326 FP_formats fmt;
3327 {
3328 int boolean = 0;
3329
3330 /* Argument checking already performed by the FPCOMPARE code */
3331
3332 #ifdef DEBUG
3333 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3334 #endif /* DEBUG */
3335
3336 /* The format type should already have been checked: */
3337 switch (fmt) {
3338 case fmt_single:
3339 {
3340 unsigned int wop1 = (unsigned int)op1;
3341 unsigned int wop2 = (unsigned int)op2;
3342 boolean = (*(float *)&wop1 < *(float *)&wop2);
3343 }
3344 break;
3345 case fmt_double:
3346 boolean = (*(double *)&op1 < *(double *)&op2);
3347 break;
3348 default:
3349 fprintf (stderr, "Bad switch\n");
3350 abort ();
3351 }
3352
3353 #ifdef DEBUG
3354 printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
3355 #endif /* DEBUG */
3356
3357 return(boolean);
3358 }
3359
3360 static int
3361 Equal(op1,op2,fmt)
3362 uword64 op1;
3363 uword64 op2;
3364 FP_formats fmt;
3365 {
3366 int boolean = 0;
3367
3368 /* Argument checking already performed by the FPCOMPARE code */
3369
3370 #ifdef DEBUG
3371 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3372 #endif /* DEBUG */
3373
3374 /* The format type should already have been checked: */
3375 switch (fmt) {
3376 case fmt_single:
3377 boolean = ((op1 & 0xFFFFFFFF) == (op2 & 0xFFFFFFFF));
3378 break;
3379 case fmt_double:
3380 boolean = (op1 == op2);
3381 break;
3382 default:
3383 fprintf (stderr, "Bad switch\n");
3384 abort ();
3385 }
3386
3387 #ifdef DEBUG
3388 printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
3389 #endif /* DEBUG */
3390
3391 return(boolean);
3392 }
3393
3394 static uword64
3395 AbsoluteValue(op,fmt)
3396 uword64 op;
3397 FP_formats fmt;
3398 {
3399 uword64 result = 0;
3400
3401 #ifdef DEBUG
3402 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3403 #endif /* DEBUG */
3404
3405 /* The format type should already have been checked: */
3406 switch (fmt) {
3407 case fmt_single:
3408 {
3409 unsigned int wop = (unsigned int)op;
3410 float tmp = ((float)fabs((double)*(float *)&wop));
3411 result = (uword64)*(unsigned int *)&tmp;
3412 }
3413 break;
3414 case fmt_double:
3415 {
3416 double tmp = (fabs(*(double *)&op));
3417 result = *(uword64 *)&tmp;
3418 }
3419 default:
3420 fprintf (stderr, "Bad switch\n");
3421 abort ();
3422 }
3423
3424 return(result);
3425 }
3426
3427 static uword64
3428 Negate(op,fmt)
3429 uword64 op;
3430 FP_formats fmt;
3431 {
3432 uword64 result = 0;
3433
3434 #ifdef DEBUG
3435 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3436 #endif /* DEBUG */
3437
3438 /* The format type should already have been checked: */
3439 switch (fmt) {
3440 case fmt_single:
3441 {
3442 unsigned int wop = (unsigned int)op;
3443 float tmp = ((float)0.0 - *(float *)&wop);
3444 result = (uword64)*(unsigned int *)&tmp;
3445 }
3446 break;
3447 case fmt_double:
3448 {
3449 double tmp = ((double)0.0 - *(double *)&op);
3450 result = *(uword64 *)&tmp;
3451 }
3452 break;
3453 default:
3454 fprintf (stderr, "Bad switch\n");
3455 abort ();
3456 }
3457
3458 return(result);
3459 }
3460
3461 static uword64
3462 Add(op1,op2,fmt)
3463 uword64 op1;
3464 uword64 op2;
3465 FP_formats fmt;
3466 {
3467 uword64 result = 0;
3468
3469 #ifdef DEBUG
3470 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3471 #endif /* DEBUG */
3472
3473 /* The registers must specify FPRs valid for operands of type
3474 "fmt". If they are not valid, the result is undefined. */
3475
3476 /* The format type should already have been checked: */
3477 switch (fmt) {
3478 case fmt_single:
3479 {
3480 unsigned int wop1 = (unsigned int)op1;
3481 unsigned int wop2 = (unsigned int)op2;
3482 float tmp = (*(float *)&wop1 + *(float *)&wop2);
3483 result = (uword64)*(unsigned int *)&tmp;
3484 }
3485 break;
3486 case fmt_double:
3487 {
3488 double tmp = (*(double *)&op1 + *(double *)&op2);
3489 result = *(uword64 *)&tmp;
3490 }
3491 break;
3492 default:
3493 fprintf (stderr, "Bad switch\n");
3494 abort ();
3495 }
3496
3497 #ifdef DEBUG
3498 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3499 #endif /* DEBUG */
3500
3501 return(result);
3502 }
3503
3504 static uword64
3505 Sub(op1,op2,fmt)
3506 uword64 op1;
3507 uword64 op2;
3508 FP_formats fmt;
3509 {
3510 uword64 result = 0;
3511
3512 #ifdef DEBUG
3513 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3514 #endif /* DEBUG */
3515
3516 /* The registers must specify FPRs valid for operands of type
3517 "fmt". If they are not valid, the result is undefined. */
3518
3519 /* The format type should already have been checked: */
3520 switch (fmt) {
3521 case fmt_single:
3522 {
3523 unsigned int wop1 = (unsigned int)op1;
3524 unsigned int wop2 = (unsigned int)op2;
3525 float tmp = (*(float *)&wop1 - *(float *)&wop2);
3526 result = (uword64)*(unsigned int *)&tmp;
3527 }
3528 break;
3529 case fmt_double:
3530 {
3531 double tmp = (*(double *)&op1 - *(double *)&op2);
3532 result = *(uword64 *)&tmp;
3533 }
3534 break;
3535 default:
3536 fprintf (stderr, "Bad switch\n");
3537 abort ();
3538 }
3539
3540 #ifdef DEBUG
3541 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3542 #endif /* DEBUG */
3543
3544 return(result);
3545 }
3546
3547 static uword64
3548 Multiply(op1,op2,fmt)
3549 uword64 op1;
3550 uword64 op2;
3551 FP_formats fmt;
3552 {
3553 uword64 result = 0;
3554
3555 #ifdef DEBUG
3556 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3557 #endif /* DEBUG */
3558
3559 /* The registers must specify FPRs valid for operands of type
3560 "fmt". If they are not valid, the result is undefined. */
3561
3562 /* The format type should already have been checked: */
3563 switch (fmt) {
3564 case fmt_single:
3565 {
3566 unsigned int wop1 = (unsigned int)op1;
3567 unsigned int wop2 = (unsigned int)op2;
3568 float tmp = (*(float *)&wop1 * *(float *)&wop2);
3569 result = (uword64)*(unsigned int *)&tmp;
3570 }
3571 break;
3572 case fmt_double:
3573 {
3574 double tmp = (*(double *)&op1 * *(double *)&op2);
3575 result = *(uword64 *)&tmp;
3576 }
3577 break;
3578 default:
3579 fprintf (stderr, "Bad switch\n");
3580 abort ();
3581 }
3582
3583 #ifdef DEBUG
3584 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3585 #endif /* DEBUG */
3586
3587 return(result);
3588 }
3589
3590 static uword64
3591 Divide(op1,op2,fmt)
3592 uword64 op1;
3593 uword64 op2;
3594 FP_formats fmt;
3595 {
3596 uword64 result = 0;
3597
3598 #ifdef DEBUG
3599 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3600 #endif /* DEBUG */
3601
3602 /* The registers must specify FPRs valid for operands of type
3603 "fmt". If they are not valid, the result is undefined. */
3604
3605 /* The format type should already have been checked: */
3606 switch (fmt) {
3607 case fmt_single:
3608 {
3609 unsigned int wop1 = (unsigned int)op1;
3610 unsigned int wop2 = (unsigned int)op2;
3611 float tmp = (*(float *)&wop1 / *(float *)&wop2);
3612 result = (uword64)*(unsigned int *)&tmp;
3613 }
3614 break;
3615 case fmt_double:
3616 {
3617 double tmp = (*(double *)&op1 / *(double *)&op2);
3618 result = *(uword64 *)&tmp;
3619 }
3620 break;
3621 default:
3622 fprintf (stderr, "Bad switch\n");
3623 abort ();
3624 }
3625
3626 #ifdef DEBUG
3627 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3628 #endif /* DEBUG */
3629
3630 return(result);
3631 }
3632
3633 static uword64 UNUSED
3634 Recip(op,fmt)
3635 uword64 op;
3636 FP_formats fmt;
3637 {
3638 uword64 result = 0;
3639
3640 #ifdef DEBUG
3641 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3642 #endif /* DEBUG */
3643
3644 /* The registers must specify FPRs valid for operands of type
3645 "fmt". If they are not valid, the result is undefined. */
3646
3647 /* The format type should already have been checked: */
3648 switch (fmt) {
3649 case fmt_single:
3650 {
3651 unsigned int wop = (unsigned int)op;
3652 float tmp = ((float)1.0 / *(float *)&wop);
3653 result = (uword64)*(unsigned int *)&tmp;
3654 }
3655 break;
3656 case fmt_double:
3657 {
3658 double tmp = ((double)1.0 / *(double *)&op);
3659 result = *(uword64 *)&tmp;
3660 }
3661 break;
3662 default:
3663 fprintf (stderr, "Bad switch\n");
3664 abort ();
3665 }
3666
3667 #ifdef DEBUG
3668 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3669 #endif /* DEBUG */
3670
3671 return(result);
3672 }
3673
3674 static uword64
3675 SquareRoot(op,fmt)
3676 uword64 op;
3677 FP_formats fmt;
3678 {
3679 uword64 result = 0;
3680
3681 #ifdef DEBUG
3682 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3683 #endif /* DEBUG */
3684
3685 /* The registers must specify FPRs valid for operands of type
3686 "fmt". If they are not valid, the result is undefined. */
3687
3688 /* The format type should already have been checked: */
3689 switch (fmt) {
3690 case fmt_single:
3691 {
3692 unsigned int wop = (unsigned int)op;
3693 #ifdef HAVE_SQRT
3694 float tmp = ((float)sqrt((double)*(float *)&wop));
3695 result = (uword64)*(unsigned int *)&tmp;
3696 #else
3697 /* TODO: Provide square-root */
3698 result = (uword64)0;
3699 #endif
3700 }
3701 break;
3702 case fmt_double:
3703 {
3704 #ifdef HAVE_SQRT
3705 double tmp = (sqrt(*(double *)&op));
3706 result = *(uword64 *)&tmp;
3707 #else
3708 /* TODO: Provide square-root */
3709 result = (uword64)0;
3710 #endif
3711 }
3712 break;
3713 default:
3714 fprintf (stderr, "Bad switch\n");
3715 abort ();
3716 }
3717
3718 #ifdef DEBUG
3719 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3720 #endif /* DEBUG */
3721
3722 return(result);
3723 }
3724
3725 static uword64
3726 Convert(rm,op,from,to)
3727 int rm;
3728 uword64 op;
3729 FP_formats from;
3730 FP_formats to;
3731 {
3732 uword64 result = 0;
3733
3734 #ifdef DEBUG
3735 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));
3736 #endif /* DEBUG */
3737
3738 /* The value "op" is converted to the destination format, rounding
3739 using mode "rm". When the destination is a fixed-point format,
3740 then a source value of Infinity, NaN or one which would round to
3741 an integer outside the fixed point range then an IEEE Invalid
3742 Operation condition is raised. */
3743 switch (to) {
3744 case fmt_single:
3745 {
3746 float tmp;
3747 switch (from) {
3748 case fmt_double:
3749 tmp = (float)(*(double *)&op);
3750 break;
3751
3752 case fmt_word:
3753 tmp = (float)((int)(op & 0xFFFFFFFF));
3754 break;
3755
3756 case fmt_long:
3757 tmp = (float)((word64)op);
3758 break;
3759 default:
3760 fprintf (stderr, "Bad switch\n");
3761 abort ();
3762 }
3763
3764 #if 0
3765 /* FIXME: This code is incorrect. The rounding mode does not
3766 round to integral values; it rounds to the nearest
3767 representable value in the format. */
3768
3769 switch (rm) {
3770 case FP_RM_NEAREST:
3771 /* Round result to nearest representable value. When two
3772 representable values are equally near, round to the value
3773 that has a least significant bit of zero (i.e. is even). */
3774 #ifdef HAVE_ANINT
3775 tmp = (float)anint((double)tmp);
3776 #else
3777 /* TODO: Provide round-to-nearest */
3778 #endif
3779 break;
3780
3781 case FP_RM_TOZERO:
3782 /* Round result to the value closest to, and not greater in
3783 magnitude than, the result. */
3784 #ifdef HAVE_AINT
3785 tmp = (float)aint((double)tmp);
3786 #else
3787 /* TODO: Provide round-to-zero */
3788 #endif
3789 break;
3790
3791 case FP_RM_TOPINF:
3792 /* Round result to the value closest to, and not less than,
3793 the result. */
3794 tmp = (float)ceil((double)tmp);
3795 break;
3796
3797 case FP_RM_TOMINF:
3798 /* Round result to the value closest to, and not greater than,
3799 the result. */
3800 tmp = (float)floor((double)tmp);
3801 break;
3802 }
3803 #endif /* 0 */
3804
3805 result = (uword64)*(unsigned int *)&tmp;
3806 }
3807 break;
3808
3809 case fmt_double:
3810 {
3811 double tmp;
3812 word64 xxx;
3813
3814 switch (from) {
3815 case fmt_single:
3816 {
3817 unsigned int wop = (unsigned int)op;
3818 tmp = (double)(*(float *)&wop);
3819 }
3820 break;
3821
3822 case fmt_word:
3823 xxx = SIGNEXTEND((op & 0xFFFFFFFF),32);
3824 tmp = (double)xxx;
3825 break;
3826
3827 case fmt_long:
3828 tmp = (double)((word64)op);
3829 break;
3830
3831 default:
3832 fprintf (stderr, "Bad switch\n");
3833 abort ();
3834 }
3835
3836 #if 0
3837 /* FIXME: This code is incorrect. The rounding mode does not
3838 round to integral values; it rounds to the nearest
3839 representable value in the format. */
3840
3841 switch (rm) {
3842 case FP_RM_NEAREST:
3843 #ifdef HAVE_ANINT
3844 tmp = anint(*(double *)&tmp);
3845 #else
3846 /* TODO: Provide round-to-nearest */
3847 #endif
3848 break;
3849
3850 case FP_RM_TOZERO:
3851 #ifdef HAVE_AINT
3852 tmp = aint(*(double *)&tmp);
3853 #else
3854 /* TODO: Provide round-to-zero */
3855 #endif
3856 break;
3857
3858 case FP_RM_TOPINF:
3859 tmp = ceil(*(double *)&tmp);
3860 break;
3861
3862 case FP_RM_TOMINF:
3863 tmp = floor(*(double *)&tmp);
3864 break;
3865 }
3866 #endif /* 0 */
3867
3868 result = *(uword64 *)&tmp;
3869 }
3870 break;
3871
3872 case fmt_word:
3873 case fmt_long:
3874 if (Infinity(op,from) || NaN(op,from) || (1 == 0/*TODO: check range */)) {
3875 printf("DBG: TODO: update FCSR\n");
3876 SignalException(FPE);
3877 } else {
3878 if (to == fmt_word) {
3879 int tmp = 0;
3880 switch (from) {
3881 case fmt_single:
3882 {
3883 unsigned int wop = (unsigned int)op;
3884 tmp = (int)*((float *)&wop);
3885 }
3886 break;
3887 case fmt_double:
3888 tmp = (int)*((double *)&op);
3889 #ifdef DEBUG
3890 printf("DBG: from double %.30f (0x%s) to word: 0x%08X\n",*((double *)&op),pr_addr(op),tmp);
3891 #endif /* DEBUG */
3892 break;
3893 default:
3894 fprintf (stderr, "Bad switch\n");
3895 abort ();
3896 }
3897 result = (uword64)tmp;
3898 } else { /* fmt_long */
3899 word64 tmp = 0;
3900 switch (from) {
3901 case fmt_single:
3902 {
3903 unsigned int wop = (unsigned int)op;
3904 tmp = (word64)*((float *)&wop);
3905 }
3906 break;
3907 case fmt_double:
3908 tmp = (word64)*((double *)&op);
3909 break;
3910 default:
3911 fprintf (stderr, "Bad switch\n");
3912 abort ();
3913 }
3914 result = (uword64)tmp;
3915 }
3916 }
3917 break;
3918 default:
3919 fprintf (stderr, "Bad switch\n");
3920 abort ();
3921 }
3922
3923 #ifdef DEBUG
3924 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result),DOFMT(to));
3925 #endif /* DEBUG */
3926
3927 return(result);
3928 }
3929 #endif /* HASFPU */
3930
3931 /*-- co-processor support routines ------------------------------------------*/
3932
3933 static int UNUSED
3934 CoProcPresent(coproc_number)
3935 unsigned int coproc_number;
3936 {
3937 /* Return TRUE if simulator provides a model for the given co-processor number */
3938 return(0);
3939 }
3940
3941 static void
3942 COP_LW(coproc_num,coproc_reg,memword)
3943 int coproc_num, coproc_reg;
3944 unsigned int memword;
3945 {
3946 switch (coproc_num) {
3947 #if defined(HASFPU)
3948 case 1:
3949 #ifdef DEBUG
3950 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
3951 #endif
3952 StoreFPR(coproc_reg,fmt_word,(uword64)memword);
3953 fpr_state[coproc_reg] = fmt_uninterpreted;
3954 break;
3955 #endif /* HASFPU */
3956
3957 default:
3958 #if 0 /* this should be controlled by a configuration option */
3959 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));
3960 #endif
3961 break;
3962 }
3963
3964 return;
3965 }
3966
3967 static void
3968 COP_LD(coproc_num,coproc_reg,memword)
3969 int coproc_num, coproc_reg;
3970 uword64 memword;
3971 {
3972 switch (coproc_num) {
3973 #if defined(HASFPU)
3974 case 1:
3975 StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3976 break;
3977 #endif /* HASFPU */
3978
3979 default:
3980 #if 0 /* this message should be controlled by a configuration option */
3981 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));
3982 #endif
3983 break;
3984 }
3985
3986 return;
3987 }
3988
3989 static unsigned int
3990 COP_SW(coproc_num,coproc_reg)
3991 int coproc_num, coproc_reg;
3992 {
3993 unsigned int value = 0;
3994
3995 switch (coproc_num) {
3996 #if defined(HASFPU)
3997 case 1:
3998 #if 1
3999 {
4000 FP_formats hold;
4001 hold = fpr_state[coproc_reg];
4002 fpr_state[coproc_reg] = fmt_word;
4003 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
4004 fpr_state[coproc_reg] = hold;
4005 }
4006 #else
4007 #if 1
4008 value = (unsigned int)ValueFPR(coproc_reg,fpr_state[coproc_reg]);
4009 #else
4010 #ifdef DEBUG
4011 printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(fpr_state[coproc_reg]));
4012 #endif /* DEBUG */
4013 value = (unsigned int)ValueFPR(coproc_reg,fmt_single);
4014 #endif
4015 #endif
4016 break;
4017 #endif /* HASFPU */
4018
4019 default:
4020 #if 0 /* should be controlled by configuration option */
4021 callback->printf_filtered(callback,"COP_SW(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
4022 #endif
4023 break;
4024 }
4025
4026 return(value);
4027 }
4028
4029 static uword64
4030 COP_SD(coproc_num,coproc_reg)
4031 int coproc_num, coproc_reg;
4032 {
4033 uword64 value = 0;
4034 switch (coproc_num) {
4035 #if defined(HASFPU)
4036 case 1:
4037 #if 1
4038 value = ValueFPR(coproc_reg,fmt_uninterpreted);
4039 #else
4040 #if 1
4041 value = ValueFPR(coproc_reg,fpr_state[coproc_reg]);
4042 #else
4043 #ifdef DEBUG
4044 printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(fpr_state[coproc_reg]));
4045 #endif /* DEBUG */
4046 value = ValueFPR(coproc_reg,fmt_double);
4047 #endif
4048 #endif
4049 break;
4050 #endif /* HASFPU */
4051
4052 default:
4053 #if 0 /* should be controlled by configuration option */
4054 callback->printf_filtered(callback,"COP_SD(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
4055 #endif
4056 break;
4057 }
4058
4059 return(value);
4060 }
4061
4062 static void
4063 decode_coproc(instruction)
4064 unsigned int instruction;
4065 {
4066 int coprocnum = ((instruction >> 26) & 3);
4067
4068 switch (coprocnum)
4069 {
4070 case 0: /* standard CPU control and cache registers */
4071 {
4072 int code = ((instruction >> 21) & 0x1F);
4073 /* R4000 Users Manual (second edition) lists the following CP0
4074 instructions:
4075 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
4076 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
4077 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
4078 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
4079 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
4080 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
4081 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
4082 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
4083 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
4084 ERET Exception return (VR4100 = 01000010000000000000000000011000)
4085 */
4086 if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
4087 {
4088 int rt = ((instruction >> 16) & 0x1F);
4089 int rd = ((instruction >> 11) & 0x1F);
4090
4091 switch (rd) /* NOTEs: Standard CP0 registers */
4092 {
4093 /* 0 = Index R4000 VR4100 VR4300 */
4094 /* 1 = Random R4000 VR4100 VR4300 */
4095 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
4096 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
4097 /* 4 = Context R4000 VR4100 VR4300 */
4098 /* 5 = PageMask R4000 VR4100 VR4300 */
4099 /* 6 = Wired R4000 VR4100 VR4300 */
4100 /* 8 = BadVAddr R4000 VR4100 VR4300 */
4101 /* 9 = Count R4000 VR4100 VR4300 */
4102 /* 10 = EntryHi R4000 VR4100 VR4300 */
4103 /* 11 = Compare R4000 VR4100 VR4300 */
4104 /* 12 = SR R4000 VR4100 VR4300 */
4105 case 12:
4106 if (code == 0x00)
4107 GPR[rt] = SR;
4108 else
4109 SR = GPR[rt];
4110 break;
4111 /* 13 = Cause R4000 VR4100 VR4300 */
4112 case 13:
4113 if (code == 0x00)
4114 GPR[rt] = CAUSE;
4115 else
4116 CAUSE = GPR[rt];
4117 break;
4118 /* 14 = EPC R4000 VR4100 VR4300 */
4119 /* 15 = PRId R4000 VR4100 VR4300 */
4120 /* 16 = Config R4000 VR4100 VR4300 */
4121 /* 17 = LLAddr R4000 VR4100 VR4300 */
4122 /* 18 = WatchLo R4000 VR4100 VR4300 */
4123 /* 19 = WatchHi R4000 VR4100 VR4300 */
4124 /* 20 = XContext R4000 VR4100 VR4300 */
4125 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
4126 /* 27 = CacheErr R4000 VR4100 */
4127 /* 28 = TagLo R4000 VR4100 VR4300 */
4128 /* 29 = TagHi R4000 VR4100 VR4300 */
4129 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
4130 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
4131 /* CPR[0,rd] = GPR[rt]; */
4132 default:
4133 if (code == 0x00)
4134 callback->printf_filtered(callback,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd);
4135 else
4136 callback->printf_filtered(callback,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd);
4137 }
4138 }
4139 else if (code == 0x10 && (instruction & 0x3f) == 0x18)
4140 {
4141 /* ERET */
4142 if (SR & status_ERL)
4143 {
4144 /* Oops, not yet available */
4145 callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
4146 PC = EPC;
4147 SR &= ~status_ERL;
4148 }
4149 else
4150 {
4151 PC = EPC;
4152 SR &= ~status_EXL;
4153 }
4154 }
4155 else
4156 sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
4157 /* TODO: When executing an ERET or RFE instruction we should
4158 clear LLBIT, to ensure that any out-standing atomic
4159 read/modify/write sequence fails. */
4160 }
4161 break;
4162
4163 case 2: /* undefined co-processor */
4164 sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
4165 break;
4166
4167 case 1: /* should not occur (FPU co-processor) */
4168 case 3: /* should not occur (FPU co-processor) */
4169 SignalException(ReservedInstruction,instruction);
4170 break;
4171 }
4172
4173 return;
4174 }
4175
4176 /*-- instruction simulation -------------------------------------------------*/
4177
4178 void
4179 sim_engine_run (sd, next_cpu_nr, siggnal)
4180 SIM_DESC sd;
4181 int next_cpu_nr; /* ignore */
4182 int siggnal; /* ignore */
4183 {
4184 #if !defined(FASTSIM)
4185 unsigned int pipeline_count = 1;
4186 #endif
4187
4188 #ifdef DEBUG
4189 if (STATE_MEMORY (sd) == NULL) {
4190 printf("DBG: simulate() entered with no memory\n");
4191 exit(1);
4192 }
4193 #endif /* DEBUG */
4194
4195 #if 0 /* Disabled to check that everything works OK */
4196 /* The VR4300 seems to sign-extend the PC on its first
4197 access. However, this may just be because it is currently
4198 configured in 32bit mode. However... */
4199 PC = SIGNEXTEND(PC,32);
4200 #endif
4201
4202 /* main controlling loop */
4203 while (1) {
4204 /* Fetch the next instruction from the simulator memory: */
4205 uword64 vaddr = (uword64)PC;
4206 uword64 paddr;
4207 int cca;
4208 unsigned int instruction; /* uword64? what's this used for? FIXME! */
4209 int dsstate = (state & simDELAYSLOT);
4210
4211 #ifdef DEBUG
4212 {
4213 printf("DBG: state = 0x%08X :",state);
4214 #if 0
4215 if (state & simSTOP) printf(" simSTOP");
4216 if (state & simSTEP) printf(" simSTEP");
4217 #endif
4218 if (state & simHALTEX) printf(" simHALTEX");
4219 if (state & simHALTIN) printf(" simHALTIN");
4220 #if 0
4221 if (state & simBE) printf(" simBE");
4222 #endif
4223 printf("\n");
4224 }
4225 #endif /* DEBUG */
4226
4227 #ifdef DEBUG
4228 if (dsstate)
4229 callback->printf_filtered(callback,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
4230 #endif /* DEBUG */
4231
4232 if (AddressTranslation(PC,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
4233 if ((vaddr & 1) == 0) {
4234 /* Copy the action of the LW instruction */
4235 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
4236 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
4237 uword64 value;
4238 unsigned int byte;
4239 paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
4240 LoadMemory(&value,NULL,cca,AccessLength_WORD,paddr,vaddr,isINSTRUCTION,isREAL);
4241 byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
4242 instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
4243 } else {
4244 /* Copy the action of the LH instruction */
4245 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 1) : 0);
4246 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 1) : 0);
4247 uword64 value;
4248 unsigned int byte;
4249 paddr = (((paddr & ~ (uword64) 1) & ~LOADDRMASK)
4250 | (((paddr & ~ (uword64) 1) & LOADDRMASK) ^ (reverse << 1)));
4251 LoadMemory(&value,NULL,cca, AccessLength_HALFWORD,
4252 paddr & ~ (uword64) 1,
4253 vaddr, isINSTRUCTION, isREAL);
4254 byte = (((vaddr &~ (uword64) 1) & LOADDRMASK) ^ (bigend << 1));
4255 instruction = ((value >> (8 * byte)) & 0xFFFF);
4256 }
4257 } else {
4258 fprintf(stderr,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC));
4259 exit(1);
4260 }
4261
4262 #ifdef DEBUG
4263 callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
4264 #endif /* DEBUG */
4265
4266 #if !defined(FASTSIM) || defined(PROFILE)
4267 instruction_fetches++;
4268 /* Since we increment above, the value should only ever be zero if
4269 we have just overflowed: */
4270 if (instruction_fetches == 0)
4271 instruction_fetch_overflow++;
4272 #if defined(PROFILE)
4273 if ((state & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
4274 unsigned n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
4275 if (n < profile_nsamples) {
4276 /* NOTE: The counts for the profiling bins are only 16bits wide */
4277 if (profile_hist[n] != USHRT_MAX)
4278 (profile_hist[n])++;
4279 }
4280 }
4281 #endif /* PROFILE */
4282 #endif /* !FASTSIM && PROFILE */
4283
4284 IPC = PC; /* copy PC for this instruction */
4285 /* This is required by exception processing, to ensure that we can
4286 cope with exceptions in the delay slots of branches that may
4287 already have changed the PC. */
4288 if ((vaddr & 1) == 0)
4289 PC += 4; /* increment ready for the next fetch */
4290 else
4291 PC += 2;
4292 /* NOTE: If we perform a delay slot change to the PC, this
4293 increment is not requuired. However, it would make the
4294 simulator more complicated to try and avoid this small hit. */
4295
4296 /* Currently this code provides a simple model. For more
4297 complicated models we could perform exception status checks at
4298 this point, and set the simSTOP state as required. This could
4299 also include processing any hardware interrupts raised by any
4300 I/O model attached to the simulator context.
4301
4302 Support for "asynchronous" I/O events within the simulated world
4303 could be providing by managing a counter, and calling a I/O
4304 specific handler when a particular threshold is reached. On most
4305 architectures a decrement and check for zero operation is
4306 usually quicker than an increment and compare. However, the
4307 process of managing a known value decrement to zero, is higher
4308 than the cost of using an explicit value UINT_MAX into the
4309 future. Which system is used will depend on how complicated the
4310 I/O model is, and how much it is likely to affect the simulator
4311 bandwidth.
4312
4313 If events need to be scheduled further in the future than
4314 UINT_MAX event ticks, then the I/O model should just provide its
4315 own counter, triggered from the event system. */
4316
4317 /* MIPS pipeline ticks. To allow for future support where the
4318 pipeline hit of individual instructions is known, this control
4319 loop manages a "pipeline_count" variable. It is initialised to
4320 1 (one), and will only be changed by the simulator engine when
4321 executing an instruction. If the engine does not have access to
4322 pipeline cycle count information then all instructions will be
4323 treated as using a single cycle. NOTE: A standard system is not
4324 provided by the default simulator because different MIPS
4325 architectures have different cycle counts for the same
4326 instructions.
4327
4328 [NOTE: pipeline_count has been replaced the event queue] */
4329
4330 #if defined(HASFPU)
4331 /* Set previous flag, depending on current: */
4332 if (state & simPCOC0)
4333 state |= simPCOC1;
4334 else
4335 state &= ~simPCOC1;
4336 /* and update the current value: */
4337 if (GETFCC(0))
4338 state |= simPCOC0;
4339 else
4340 state &= ~simPCOC0;
4341 #endif /* HASFPU */
4342
4343 /* NOTE: For multi-context simulation environments the "instruction"
4344 variable should be local to this routine. */
4345
4346 /* Shorthand accesses for engine. Note: If we wanted to use global
4347 variables (and a single-threaded simulator engine), then we can
4348 create the actual variables with these names. */
4349
4350 if (!(state & simSKIPNEXT)) {
4351 /* Include the simulator engine */
4352 #include "engine.c"
4353 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
4354 #error "Mismatch between run-time simulator code and simulation engine"
4355 #endif
4356
4357 #if defined(WARN_LOHI)
4358 /* Decrement the HI/LO validity ticks */
4359 if (HIACCESS > 0)
4360 HIACCESS--;
4361 if (LOACCESS > 0)
4362 LOACCESS--;
4363 if (HI1ACCESS > 0)
4364 HI1ACCESS--;
4365 if (LO1ACCESS > 0)
4366 LO1ACCESS--;
4367 #endif /* WARN_LOHI */
4368
4369 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
4370 should check for it being changed. It is better doing it here,
4371 than within the simulator, since it will help keep the simulator
4372 small. */
4373 if (ZERO != 0) {
4374 #if defined(WARN_ZERO)
4375 sim_warning("The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)",pr_addr(ZERO),pr_addr(IPC));
4376 #endif /* WARN_ZERO */
4377 ZERO = 0; /* reset back to zero before next instruction */
4378 }
4379 } else /* simSKIPNEXT check */
4380 state &= ~simSKIPNEXT;
4381
4382 /* If the delay slot was active before the instruction is
4383 executed, then update the PC to its new value: */
4384 if (dsstate) {
4385 #ifdef DEBUG
4386 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
4387 #endif /* DEBUG */
4388 PC = DSPC;
4389 state &= ~(simDELAYSLOT | simJALDELAYSLOT);
4390 }
4391
4392 if (MIPSISA < 4) { /* The following is only required on pre MIPS IV processors: */
4393 /* Deal with pending register updates: */
4394 #ifdef DEBUG
4395 printf("DBG: EMPTY BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
4396 #endif /* DEBUG */
4397 if (pending_out != pending_in) {
4398 int loop;
4399 int index = pending_out;
4400 int total = pending_total;
4401 if (pending_total == 0) {
4402 fprintf(stderr,"FATAL: Mis-match on pending update pointers\n");
4403 exit(1);
4404 }
4405 for (loop = 0; (loop < total); loop++) {
4406 #ifdef DEBUG
4407 printf("DBG: BEFORE index = %d, loop = %d\n",index,loop);
4408 #endif /* DEBUG */
4409 if (pending_slot_reg[index] != (LAST_EMBED_REGNUM + 1)) {
4410 #ifdef DEBUG
4411 printf("pending_slot_count[%d] = %d\n",index,pending_slot_count[index]);
4412 #endif /* DEBUG */
4413 if (--(pending_slot_count[index]) == 0) {
4414 #ifdef DEBUG
4415 printf("pending_slot_reg[%d] = %d\n",index,pending_slot_reg[index]);
4416 printf("pending_slot_value[%d] = 0x%s\n",index,pr_addr(pending_slot_value[index]));
4417 #endif /* DEBUG */
4418 if (pending_slot_reg[index] == COCIDX) {
4419 #if defined(HASFPU)
4420 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
4421 #else
4422 ;
4423 #endif
4424 } else {
4425 registers[pending_slot_reg[index]] = pending_slot_value[index];
4426 #if defined(HASFPU)
4427 /* The only time we have PENDING updates to FPU
4428 registers, is when performing binary transfers. This
4429 means we should update the register type field. */
4430 if ((pending_slot_reg[index] >= FGRIDX) && (pending_slot_reg[index] < (FGRIDX + 32)))
4431 fpr_state[pending_slot_reg[index] - FGRIDX] = fmt_uninterpreted;
4432 #endif /* HASFPU */
4433 }
4434 #ifdef DEBUG
4435 printf("registers[%d] = 0x%s\n",pending_slot_reg[index],pr_addr(registers[pending_slot_reg[index]]));
4436 #endif /* DEBUG */
4437 pending_slot_reg[index] = (LAST_EMBED_REGNUM + 1);
4438 pending_out++;
4439 if (pending_out == PSLOTS)
4440 pending_out = 0;
4441 pending_total--;
4442 }
4443 }
4444 #ifdef DEBUG
4445 printf("DBG: AFTER index = %d, loop = %d\n",index,loop);
4446 #endif /* DEBUG */
4447 index++;
4448 if (index == PSLOTS)
4449 index = 0;
4450 }
4451 }
4452 #ifdef DEBUG
4453 printf("DBG: EMPTY AFTER pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
4454 #endif /* DEBUG */
4455 }
4456
4457 #if !defined(FASTSIM)
4458 if (sim_events_tickn (sd, pipeline_count))
4459 {
4460 /* cpu->cia = cia; */
4461 sim_events_process (sd);
4462 }
4463 #else
4464 if (sim_events_tick (sd))
4465 {
4466 /* cpu->cia = cia; */
4467 sim_events_process (sd);
4468 }
4469 #endif /* FASTSIM */
4470 }
4471 }
4472
4473 /* This code copied from gdb's utils.c. Would like to share this code,
4474 but don't know of a common place where both could get to it. */
4475
4476 /* Temporary storage using circular buffer */
4477 #define NUMCELLS 16
4478 #define CELLSIZE 32
4479 static char*
4480 get_cell()
4481 {
4482 static char buf[NUMCELLS][CELLSIZE];
4483 static int cell=0;
4484 if (++cell>=NUMCELLS) cell=0;
4485 return buf[cell];
4486 }
4487
4488 /* Print routines to handle variable size regs, etc */
4489
4490 /* Eliminate warning from compiler on 32-bit systems */
4491 static int thirty_two = 32;
4492
4493 char*
4494 pr_addr(addr)
4495 SIM_ADDR addr;
4496 {
4497 char *paddr_str=get_cell();
4498 switch (sizeof(addr))
4499 {
4500 case 8:
4501 sprintf(paddr_str,"%08lx%08lx",
4502 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4503 break;
4504 case 4:
4505 sprintf(paddr_str,"%08lx",(unsigned long)addr);
4506 break;
4507 case 2:
4508 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
4509 break;
4510 default:
4511 sprintf(paddr_str,"%x",addr);
4512 }
4513 return paddr_str;
4514 }
4515
4516 char*
4517 pr_uword64(addr)
4518 uword64 addr;
4519 {
4520 char *paddr_str=get_cell();
4521 sprintf(paddr_str,"%08lx%08lx",
4522 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4523 return paddr_str;
4524 }
4525
4526
4527 /*---------------------------------------------------------------------------*/
4528 /*> EOF interp.c <*/
This page took 0.126507 seconds and 5 git commands to generate.