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