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