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