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