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