Commit | Line | Data |
---|---|---|
18c64df6 AC |
1 | /* MIPS Simulator definition. |
2 | Copyright (C) 1997 Free Software Foundation, Inc. | |
3 | Contributed by Cygnus Support. | |
4 | ||
5 | This file is part of GDB, the GNU debugger. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License along | |
18 | with this program; if not, write to the Free Software Foundation, Inc., | |
19 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
20 | ||
21 | #ifndef SIM_MAIN_H | |
22 | #define SIM_MAIN_H | |
23 | ||
24 | /* This simulator doesn't cache the Current Instruction Address */ | |
25 | #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) | |
26 | #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) | |
27 | ||
28 | #define SIM_HAVE_BIENDIAN | |
29 | #define SIM_HAVE_FLATMEM | |
30 | ||
31 | ||
32 | /* hobble some common features for moment */ | |
33 | #define WITH_PROFILE 0 | |
34 | #define WITH_TRACE 0 | |
35 | #define WITH_WATCHPOINTS 1 | |
36 | ||
37 | #include "sim-basics.h" | |
38 | ||
39 | /* dummy - not used */ | |
40 | typedef int sim_cia; | |
41 | #define NULL_CIA 0 | |
42 | ||
43 | #include "sim-base.h" | |
44 | ||
45 | ||
46 | /* Depreciated macros and types for manipulating 64bit values. Use | |
47 | ../common/sim-bits.h and ../common/sim-endian.h macros instead. */ | |
48 | ||
49 | typedef signed64 word64; | |
50 | typedef unsigned64 uword64; | |
51 | ||
52 | #define WORD64LO(t) (unsigned int)((t)&0xFFFFFFFF) | |
53 | #define WORD64HI(t) (unsigned int)(((uword64)(t))>>32) | |
54 | #define SET64LO(t) (((uword64)(t))&0xFFFFFFFF) | |
55 | #define SET64HI(t) (((uword64)(t))<<32) | |
56 | #define WORD64(h,l) ((word64)((SET64HI(h)|SET64LO(l)))) | |
57 | #define UWORD64(h,l) (SET64HI(h)|SET64LO(l)) | |
58 | ||
59 | /* Sign-extend the given value (e) as a value (b) bits long. We cannot | |
60 | assume the HI32bits of the operand are zero, so we must perform a | |
61 | mask to ensure we can use the simple subtraction to sign-extend. */ | |
62 | #define SIGNEXTEND(e,b) \ | |
63 | (((e) & ((uword64) 1 << ((b) - 1))) \ | |
64 | ? (((e) & (((uword64) 1 << (b)) - 1)) - ((uword64)1 << (b))) \ | |
65 | : ((e) & (((((uword64) 1 << ((b) - 1)) - 1) << 1) | 1))) | |
66 | ||
67 | /* Check if a value will fit within a halfword: */ | |
68 | #define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1)) | |
69 | ||
70 | /* windows always looses */ | |
71 | #include <signal.h> | |
72 | #ifndef SIGBUS | |
73 | #define SIGBUS SIGSEGV | |
74 | #endif | |
75 | #ifdef _WIN32 | |
76 | #define SIGTRAP 5 | |
77 | #define SIGQUIT 3 | |
78 | #endif | |
79 | ||
80 | ||
0c2c5f61 AC |
81 | /* Floating-point operations: */ |
82 | ||
83 | /* FPU registers must be one of the following types. All other values | |
84 | are reserved (and undefined). */ | |
85 | typedef enum { | |
86 | fmt_single = 0, | |
87 | fmt_double = 1, | |
88 | fmt_word = 4, | |
89 | fmt_long = 5, | |
90 | /* The following are well outside the normal acceptable format | |
91 | range, and are used in the register status vector. */ | |
92 | fmt_unknown = 0x10000000, | |
93 | fmt_uninterpreted = 0x20000000, | |
94 | } FP_formats; | |
95 | ||
96 | unsigned64 value_fpr PARAMS ((SIM_DESC sd, int fpr, FP_formats)); | |
97 | #define ValueFPR(FPR,FMT) value_fpr (sd, (FPR), (FMT)) | |
98 | ||
99 | void store_fpr PARAMS ((SIM_DESC sd, int fpr, FP_formats fmt, unsigned64 value)); | |
100 | #define StoreFPR(FPR,FMT,VALUE) store_fpr (sd, (FPR), (FMT), (VALUE)) | |
101 | ||
102 | int NaN PARAMS ((unsigned64 op, FP_formats fmt)); | |
103 | int Infinity PARAMS ((unsigned64 op, FP_formats fmt)); | |
104 | int Less PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
105 | int Equal PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
106 | unsigned64 AbsoluteValue PARAMS ((unsigned64 op, FP_formats fmt)); | |
107 | unsigned64 Negate PARAMS ((unsigned64 op, FP_formats fmt)); | |
108 | unsigned64 Add PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
109 | unsigned64 Sub PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
110 | unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
111 | unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); | |
112 | unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt)); | |
113 | unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt)); | |
114 | unsigned64 convert PARAMS ((SIM_DESC sd, int rm, unsigned64 op, FP_formats from, FP_formats to)); | |
115 | #define Convert(rm,op,from,to) convert(sd,rm,op,from,to) | |
116 | ||
117 | ||
118 | ||
119 | ||
18c64df6 | 120 | struct _sim_cpu { |
0c2c5f61 AC |
121 | |
122 | ||
123 | /* The following are internal simulator state variables: */ | |
124 | address_word ipc; /* internal Instruction PC */ | |
125 | address_word dspc; /* delay-slot PC */ | |
126 | #define IPC ((STATE_CPU (sd,0))->ipc) | |
127 | #define DSPC ((STATE_CPU (sd,0))->dspc) | |
128 | ||
129 | ||
130 | /* State of the simulator */ | |
131 | unsigned int state; | |
132 | unsigned int dsstate; | |
133 | #define STATE ((STATE_CPU (sd,0))->state) | |
134 | #define DSSTATE ((STATE_CPU (sd,0))->dsstate) | |
135 | ||
136 | ||
137 | /* This is nasty, since we have to rely on matching the register | |
138 | numbers used by GDB. Unfortunately, depending on the MIPS target | |
139 | GDB uses different register numbers. We cannot just include the | |
140 | relevant "gdb/tm.h" link, since GDB may not be configured before | |
141 | the sim world, and also the GDB header file requires too much other | |
142 | state. */ | |
143 | ||
144 | #ifndef TM_MIPS_H | |
145 | #define LAST_EMBED_REGNUM (89) | |
146 | #define NUM_REGS (LAST_EMBED_REGNUM + 1) | |
147 | /* start-sanitize-r5900 */ | |
148 | #undef NUM_REGS | |
149 | #define NUM_REGS (128) | |
150 | /* end-sanitize-r5900 */ | |
151 | #endif | |
152 | ||
153 | /* To keep this default simulator simple, and fast, we use a direct | |
154 | vector of registers. The internal simulator engine then uses | |
155 | manifests to access the correct slot. */ | |
156 | ||
157 | signed_word registers[LAST_EMBED_REGNUM + 1]; | |
158 | int register_widths[NUM_REGS]; | |
159 | #define REGISTERS ((STATE_CPU (sd,0))->registers) | |
160 | ||
161 | #define GPR (®ISTERS[0]) | |
162 | #define FGRIDX (38) | |
163 | #define FGR (®ISTERS[FGRIDX]) | |
164 | #define LO (REGISTERS[33]) | |
165 | #define HI (REGISTERS[34]) | |
166 | #define PC (REGISTERS[37]) | |
167 | #define CAUSE (REGISTERS[36]) | |
168 | #define SRIDX (32) | |
169 | #define SR (REGISTERS[SRIDX]) /* CPU status register */ | |
170 | #define FCR0IDX (71) | |
171 | #define FCR0 (REGISTERS[FCR0IDX]) /* really a 32bit register */ | |
172 | #define FCR31IDX (70) | |
173 | #define FCR31 (REGISTERS[FCR31IDX]) /* really a 32bit register */ | |
174 | #define FCSR (FCR31) | |
175 | #define Debug (REGISTERS[86]) | |
176 | #define DEPC (REGISTERS[87]) | |
177 | #define EPC (REGISTERS[88]) | |
178 | #define COCIDX (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */ | |
179 | ||
180 | /* The following are pseudonyms for standard registers */ | |
181 | #define ZERO (REGISTERS[0]) | |
182 | #define V0 (REGISTERS[2]) | |
183 | #define A0 (REGISTERS[4]) | |
184 | #define A1 (REGISTERS[5]) | |
185 | #define A2 (REGISTERS[6]) | |
186 | #define A3 (REGISTERS[7]) | |
187 | #define SP (REGISTERS[29]) | |
188 | #define RA (REGISTERS[31]) | |
189 | ||
190 | /* Keep the current format state for each register: */ | |
191 | FP_formats fpr_state[32]; | |
192 | #define FPR_STATE ((STATE_CPU (sd, 0))->fpr_state) | |
193 | ||
194 | ||
195 | /* Slots for delayed register updates. For the moment we just have a | |
196 | fixed number of slots (rather than a more generic, dynamic | |
197 | system). This keeps the simulator fast. However, we only allow | |
198 | for the register update to be delayed for a single instruction | |
199 | cycle. */ | |
200 | #define PSLOTS (5) /* Maximum number of instruction cycles */ | |
201 | int pending_in; | |
202 | int pending_out; | |
203 | int pending_total; | |
204 | int pending_slot_count[PSLOTS]; | |
205 | int pending_slot_reg[PSLOTS]; | |
206 | unsigned_word pending_slot_value[PSLOTS]; | |
207 | #define PENDING_IN ((STATE_CPU (sd, 0))->pending_in) | |
208 | #define PENDING_OUT ((STATE_CPU (sd, 0))->pending_out) | |
209 | #define PENDING_TOTAL ((STATE_CPU (sd, 0))->pending_total) | |
210 | #define PENDING_SLOT_COUNT ((STATE_CPU (sd, 0))->pending_slot_count) | |
211 | #define PENDING_SLOT_REG ((STATE_CPU (sd, 0))->pending_slot_reg) | |
212 | #define PENDING_SLOT_VALUE ((STATE_CPU (sd, 0))->pending_slot_value) | |
213 | ||
214 | ||
215 | /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic | |
216 | read-write instructions. It is set when a linked load occurs. It | |
217 | is tested and cleared by the conditional store. It is cleared | |
218 | (during other CPU operations) when a store to the location would | |
219 | no longer be atomic. In particular, it is cleared by exception | |
220 | return instructions. */ | |
221 | int llbit; | |
222 | #define LLBIT ((STATE_CPU (sd, 0))->llbit) | |
223 | ||
224 | ||
225 | /* The HIACCESS and LOACCESS counts are used to ensure that | |
226 | corruptions caused by using the HI or LO register to close to a | |
227 | following operation are spotted. */ | |
228 | ||
229 | int hiaccess; | |
230 | int loaccess; | |
231 | #define HIACCESS ((STATE_CPU (sd, 0))->hiaccess) | |
232 | #define LOACCESS ((STATE_CPU (sd, 0))->loaccess) | |
233 | /* start-sanitize-r5900 */ | |
234 | int hi1access; | |
235 | int lo1access; | |
236 | #define HI1ACCESS ((STATE_CPU (sd, 0))->hi1access) | |
237 | #define LO1ACCESS ((STATE_CPU (sd, 0))->lo1access) | |
238 | /* end-sanitize-r5900 */ | |
239 | #if 1 | |
240 | /* The 4300 and a few other processors have interlocks on hi/lo | |
241 | register reads, and hence do not have this problem. To avoid | |
242 | spurious warnings, we just disable this always. */ | |
243 | #define CHECKHILO(s) | |
244 | #else | |
245 | unsigned_word HLPC; | |
246 | /* If either of the preceding two instructions have accessed the HI | |
247 | or LO registers, then the values they see should be | |
248 | undefined. However, to keep the simulator world simple, we just | |
249 | let them use the value read and raise a warning to notify the | |
250 | user: */ | |
251 | #define CHECKHILO(s) {\ | |
252 | if ((HIACCESS != 0) || (LOACCESS != 0)) \ | |
253 | sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\ | |
254 | } | |
255 | /* end-sanitize-r5900 */ | |
256 | #undef CHECKHILO | |
257 | #define CHECKHILO(s) {\ | |
258 | if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\ | |
259 | sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\ | |
260 | } | |
261 | /* end-sanitize-r5900 */ | |
262 | #endif | |
263 | ||
264 | ||
265 | /* start-sanitize-r5900 */ | |
266 | /* The R5900 has 128 bit registers, but the hi 64 bits are only | |
267 | touched by multimedia (MMI) instructions. The normal mips | |
268 | instructions just use the lower 64 bits. To avoid changing the | |
269 | older parts of the simulator to handle this weirdness, the high | |
270 | 64 bits of each register are kept in a separate array | |
271 | (registers1). The high 64 bits of any register are by convention | |
272 | refered by adding a '1' to the end of the normal register's name. | |
273 | So LO still refers to the low 64 bits of the LO register, LO1 | |
274 | refers to the high 64 bits of that same register. */ | |
275 | ||
276 | signed_word registers1[LAST_EMBED_REGNUM + 1]; | |
277 | #define REGISTERS1 ((STATE_CPU (sd, 0))->registers1) | |
278 | #define GPR1 (®ISTERS1[0]) | |
279 | #define LO1 (REGISTERS1[32]) | |
280 | #define HI1 (REGISTERS1[33]) | |
281 | #define REGISTER_SA (124) | |
282 | ||
283 | unsigned_word sa; /* the shift amount register */ | |
284 | #define SA ((STATE_CPU (sd, 0))->sa) | |
285 | ||
286 | /* end-sanitize-r5900 */ | |
287 | ||
288 | ||
289 | ||
18c64df6 AC |
290 | sim_cpu_base base; |
291 | }; | |
292 | ||
293 | ||
294 | /* MIPS specific simulator watch config */ | |
295 | ||
296 | void watch_options_install PARAMS ((SIM_DESC sd)); | |
297 | ||
298 | struct swatch { | |
299 | sim_event *pc; | |
300 | sim_event *clock; | |
301 | sim_event *cycles; | |
302 | }; | |
303 | ||
304 | ||
305 | /* FIXME: At present much of the simulator is still static */ | |
306 | struct sim_state { | |
307 | ||
308 | struct swatch watch; | |
309 | ||
310 | sim_cpu cpu[1]; | |
311 | #if (WITH_SMP) | |
312 | #define STATE_CPU(sd,n) (&(sd)->cpu[n]) | |
313 | #else | |
314 | #define STATE_CPU(sd,n) (&(sd)->cpu[0]) | |
315 | #endif | |
316 | ||
317 | sim_state_base base; | |
318 | }; | |
319 | ||
320 | ||
321 | /* Exceptions: */ | |
322 | ||
323 | /* NOTE: These numbers depend on the processor architecture being | |
324 | simulated: */ | |
325 | #define Interrupt (0) | |
326 | #define TLBModification (1) | |
327 | #define TLBLoad (2) | |
328 | #define TLBStore (3) | |
329 | #define AddressLoad (4) | |
330 | #define AddressStore (5) | |
331 | #define InstructionFetch (6) | |
332 | #define DataReference (7) | |
333 | #define SystemCall (8) | |
334 | #define BreakPoint (9) | |
335 | #define ReservedInstruction (10) | |
336 | #define CoProcessorUnusable (11) | |
337 | #define IntegerOverflow (12) /* Arithmetic overflow (IDT monitor raises SIGFPE) */ | |
338 | #define Trap (13) | |
339 | #define FPE (15) | |
340 | #define DebugBreakPoint (16) | |
341 | #define Watch (23) | |
342 | ||
343 | /* The following exception code is actually private to the simulator | |
344 | world. It is *NOT* a processor feature, and is used to signal | |
345 | run-time errors in the simulator. */ | |
346 | #define SimulatorFault (0xFFFFFFFF) | |
347 | ||
348 | void signal_exception (SIM_DESC sd, int exception, ...); | |
349 | #define SignalException(exc,instruction) signal_exception (sd, (exc), (instruction)) | |
350 | #define SignalExceptionInterrupt() signal_exception (sd, Interrupt) | |
351 | #define SignalExceptionInstructionFetch() signal_exception (sd, InstructionFetch) | |
352 | #define SignalExceptionAddressStore() signal_exception (sd, AddressStore) | |
353 | #define SignalExceptionAddressLoad() signal_exception (sd, AddressLoad) | |
354 | #define SignalExceptionSimulatorFault(buf) signal_exception (sd, SimulatorFault, buf) | |
355 | #define SignalExceptionFPE() signal_exception (sd, FPE) | |
356 | #define SignalExceptionIntegerOverflow() signal_exception (sd, IntegerOverflow) | |
357 | #define SignalExceptionCoProcessorUnusable() signal_exception (sd, CoProcessorUnusable) | |
358 | ||
359 | ||
18c64df6 AC |
360 | /* Co-processor accesses */ |
361 | ||
362 | void cop_lw PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg, unsigned int memword)); | |
363 | void cop_ld PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg, uword64 memword)); | |
364 | unsigned int cop_sw PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg)); | |
365 | uword64 cop_sd PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg)); | |
366 | ||
367 | #define COP_LW(coproc_num,coproc_reg,memword) cop_lw(sd,coproc_num,coproc_reg,memword) | |
368 | #define COP_LD(coproc_num,coproc_reg,memword) cop_ld(sd,coproc_num,coproc_reg,memword) | |
369 | #define COP_SW(coproc_num,coproc_reg) cop_sw(sd,coproc_num,coproc_reg) | |
370 | #define COP_SD(coproc_num,coproc_reg) cop_sd(sd,coproc_num,coproc_reg) | |
371 | ||
372 | ||
373 | ||
374 | /* Memory accesses */ | |
375 | ||
376 | int address_translation PARAMS ((SIM_DESC sd, uword64 vAddr, int IorD, int LorS, uword64 *pAddr, int *CCA, int host, int raw)); | |
377 | #define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \ | |
378 | address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,host,raw) | |
379 | ||
380 | void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, uword64 pAddr, uword64 vAddr, int IorD, int raw)); | |
381 | #define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \ | |
382 | load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) | |
383 | ||
384 | void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, uword64 pAddr, uword64 vAddr, int raw)); | |
385 | #define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \ | |
386 | store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) | |
387 | ||
388 | void cache_op PARAMS ((SIM_DESC sd, int op, uword64 pAddr, uword64 vAddr, unsigned int instruction)); | |
389 | #define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,op,pAddr,vAddr,instruction) | |
390 | ||
391 | #endif |