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