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