Commit | Line | Data |
---|---|---|
c906108c SS |
1 | #ifndef SIM_MAIN_H |
2 | #define SIM_MAIN_H | |
3 | ||
4 | /* General config options */ | |
5 | ||
6 | #define WITH_CORE | |
7 | #define WITH_MODULO_MEMORY 1 | |
8 | #define WITH_WATCHPOINTS 1 | |
9 | ||
10 | ||
11 | /* The v850 has 32bit words, numbered 31 (MSB) to 0 (LSB) */ | |
12 | ||
13 | #define WITH_TARGET_WORD_MSB 31 | |
14 | ||
15 | ||
16 | #include "sim-basics.h" | |
17 | #include "sim-signal.h" | |
18 | ||
19 | typedef address_word sim_cia; | |
20 | ||
21 | #include "sim-base.h" | |
22 | ||
23 | #include "simops.h" | |
24 | #include "bfd.h" | |
25 | ||
26 | ||
27 | typedef signed8 int8; | |
28 | typedef unsigned8 uint8; | |
29 | typedef signed16 int16; | |
30 | typedef unsigned16 uint16; | |
31 | typedef signed32 int32; | |
32 | typedef unsigned32 uint32; | |
33 | typedef unsigned32 reg_t; | |
34 | ||
35 | ||
36 | /* The current state of the processor; registers, memory, etc. */ | |
37 | ||
38 | typedef struct _v850_regs { | |
39 | reg_t regs[32]; /* general-purpose registers */ | |
40 | reg_t sregs[32]; /* system registers, including psw */ | |
41 | reg_t pc; | |
42 | int dummy_mem; /* where invalid accesses go */ | |
43 | } v850_regs; | |
44 | ||
45 | struct _sim_cpu | |
46 | { | |
47 | /* ... simulator specific members ... */ | |
48 | v850_regs reg; | |
49 | reg_t psw_mask; /* only allow non-reserved bits to be set */ | |
50 | sim_event *pending_nmi; | |
51 | /* ... base type ... */ | |
52 | sim_cpu_base base; | |
53 | }; | |
54 | ||
55 | #define CIA_GET(CPU) ((CPU)->reg.pc + 0) | |
56 | #define CIA_SET(CPU,VAL) ((CPU)->reg.pc = (VAL)) | |
57 | ||
58 | struct sim_state { | |
59 | sim_cpu cpu[MAX_NR_PROCESSORS]; | |
60 | #if (WITH_SMP) | |
61 | #define STATE_CPU(sd,n) (&(sd)->cpu[n]) | |
62 | #else | |
63 | #define STATE_CPU(sd,n) (&(sd)->cpu[0]) | |
64 | #endif | |
65 | #if 0 | |
66 | SIM_ADDR rom_size; | |
67 | SIM_ADDR low_end; | |
68 | SIM_ADDR high_start; | |
69 | SIM_ADDR high_base; | |
70 | void *mem; | |
71 | #endif | |
72 | sim_state_base base; | |
73 | }; | |
74 | ||
75 | /* For compatibility, until all functions converted to passing | |
76 | SIM_DESC as an argument */ | |
77 | extern SIM_DESC simulator; | |
78 | ||
79 | ||
80 | #define V850_ROM_SIZE 0x8000 | |
81 | #define V850_LOW_END 0x200000 | |
82 | #define V850_HIGH_START 0xffe000 | |
83 | ||
84 | ||
85 | /* Because we are still using the old semantic table, provide compat | |
86 | macro's that store the instruction where the old simops expects | |
87 | it. */ | |
88 | ||
89 | extern uint32 OP[4]; | |
90 | #if 0 | |
91 | OP[0] = inst & 0x1f; /* RRRRR -> reg1 */ | |
92 | OP[1] = (inst >> 11) & 0x1f; /* rrrrr -> reg2 */ | |
93 | OP[2] = (inst >> 16) & 0xffff; /* wwwww -> reg3 OR imm16 */ | |
94 | OP[3] = inst; | |
95 | #endif | |
96 | ||
97 | #define SAVE_1 \ | |
98 | PC = cia; \ | |
99 | OP[0] = instruction_0 & 0x1f; \ | |
100 | OP[1] = (instruction_0 >> 11) & 0x1f; \ | |
101 | OP[2] = 0; \ | |
102 | OP[3] = instruction_0 | |
103 | ||
104 | #define COMPAT_1(CALL) \ | |
105 | SAVE_1; \ | |
106 | PC += (CALL); \ | |
107 | nia = PC | |
108 | ||
109 | #define SAVE_2 \ | |
110 | PC = cia; \ | |
111 | OP[0] = instruction_0 & 0x1f; \ | |
112 | OP[1] = (instruction_0 >> 11) & 0x1f; \ | |
113 | OP[2] = instruction_1; \ | |
114 | OP[3] = (instruction_1 << 16) | instruction_0 | |
115 | ||
116 | #define COMPAT_2(CALL) \ | |
117 | SAVE_2; \ | |
118 | PC += (CALL); \ | |
119 | nia = PC | |
120 | ||
121 | ||
122 | /* new */ | |
123 | #define GR ((CPU)->reg.regs) | |
124 | #define SR ((CPU)->reg.sregs) | |
125 | ||
126 | /* old */ | |
127 | #define State (STATE_CPU (simulator, 0)->reg) | |
128 | #define PC (State.pc) | |
129 | #define SP (State.regs[3]) | |
130 | #define EP (State.regs[30]) | |
131 | ||
132 | #define EIPC (State.sregs[0]) | |
133 | #define EIPSW (State.sregs[1]) | |
134 | #define FEPC (State.sregs[2]) | |
135 | #define FEPSW (State.sregs[3]) | |
136 | #define ECR (State.sregs[4]) | |
137 | #define PSW (State.sregs[5]) | |
138 | #define CTPC (SR[16]) | |
139 | #define CTPSW (SR[17]) | |
140 | #define DBPC (State.sregs[18]) | |
141 | #define DBPSW (State.sregs[19]) | |
142 | #define CTBP (State.sregs[20]) | |
143 | ||
144 | #define PSW_US BIT32 (8) | |
145 | #define PSW_NP 0x80 | |
146 | #define PSW_EP 0x40 | |
147 | #define PSW_ID 0x20 | |
148 | #define PSW_SAT 0x10 | |
149 | #define PSW_CY 0x8 | |
150 | #define PSW_OV 0x4 | |
151 | #define PSW_S 0x2 | |
152 | #define PSW_Z 0x1 | |
153 | ||
154 | #define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4) | |
155 | ||
156 | /* sign-extend a 4-bit number */ | |
157 | #define SEXT4(x) ((((x)&0xf)^(~0x7))+0x8) | |
158 | ||
159 | /* sign-extend a 5-bit number */ | |
160 | #define SEXT5(x) ((((x)&0x1f)^(~0xf))+0x10) | |
161 | ||
162 | /* sign-extend a 9-bit number */ | |
163 | #define SEXT9(x) ((((x)&0x1ff)^(~0xff))+0x100) | |
164 | ||
165 | /* sign-extend a 22-bit number */ | |
166 | #define SEXT22(x) ((((x)&0x3fffff)^(~0x1fffff))+0x200000) | |
167 | ||
168 | /* sign extend a 40 bit number */ | |
169 | #define SEXT40(x) ((((x) & UNSIGNED64 (0xffffffffff)) \ | |
170 | ^ (~UNSIGNED64 (0x7fffffffff))) \ | |
171 | + UNSIGNED64 (0x8000000000)) | |
172 | ||
173 | /* sign extend a 44 bit number */ | |
174 | #define SEXT44(x) ((((x) & UNSIGNED64 (0xfffffffffff)) \ | |
175 | ^ (~ UNSIGNED64 (0x7ffffffffff))) \ | |
176 | + UNSIGNED64 (0x80000000000)) | |
177 | ||
178 | /* sign extend a 60 bit number */ | |
179 | #define SEXT60(x) ((((x) & UNSIGNED64 (0xfffffffffffffff)) \ | |
180 | ^ (~ UNSIGNED64 (0x7ffffffffffffff))) \ | |
181 | + UNSIGNED64 (0x800000000000000)) | |
182 | ||
183 | /* No sign extension */ | |
184 | #define NOP(x) (x) | |
185 | ||
186 | #define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i)) | |
187 | ||
188 | #define RLW(x) load_mem (x, 4) | |
189 | ||
190 | /* Function declarations. */ | |
191 | ||
192 | #define IMEM16(EA) \ | |
193 | sim_core_read_aligned_2 (CPU, PC, exec_map, (EA)) | |
194 | ||
195 | #define IMEM16_IMMED(EA,N) \ | |
196 | sim_core_read_aligned_2 (STATE_CPU (sd, 0), \ | |
197 | PC, exec_map, (EA) + (N) * 2) | |
198 | ||
199 | #define load_mem(ADDR,LEN) \ | |
200 | sim_core_read_unaligned_##LEN (STATE_CPU (simulator, 0), \ | |
201 | PC, read_map, (ADDR)) | |
202 | ||
203 | #define store_mem(ADDR,LEN,DATA) \ | |
204 | sim_core_write_unaligned_##LEN (STATE_CPU (simulator, 0), \ | |
205 | PC, write_map, (ADDR), (DATA)) | |
206 | ||
207 | ||
208 | /* compare cccc field against PSW */ | |
209 | int condition_met (unsigned code); | |
210 | ||
211 | ||
212 | /* Debug/tracing calls */ | |
213 | ||
214 | enum op_types | |
215 | { | |
216 | OP_UNKNOWN, | |
217 | OP_NONE, | |
218 | OP_TRAP, | |
219 | OP_REG, | |
220 | OP_REG_REG, | |
221 | OP_REG_REG_CMP, | |
222 | OP_REG_REG_MOVE, | |
223 | OP_IMM_REG, | |
224 | OP_IMM_REG_CMP, | |
225 | OP_IMM_REG_MOVE, | |
226 | OP_COND_BR, | |
227 | OP_LOAD16, | |
228 | OP_STORE16, | |
229 | OP_LOAD32, | |
230 | OP_STORE32, | |
231 | OP_JUMP, | |
232 | OP_IMM_REG_REG, | |
233 | OP_UIMM_REG_REG, | |
234 | OP_IMM16_REG_REG, | |
235 | OP_UIMM16_REG_REG, | |
236 | OP_BIT, | |
237 | OP_EX1, | |
238 | OP_EX2, | |
239 | OP_LDSR, | |
240 | OP_STSR, | |
241 | OP_BIT_CHANGE, | |
242 | OP_REG_REG_REG, | |
243 | OP_REG_REG3, | |
244 | OP_IMM_REG_REG_REG, | |
245 | OP_PUSHPOP1, | |
246 | OP_PUSHPOP2, | |
247 | OP_PUSHPOP3, | |
248 | }; | |
249 | ||
250 | #ifdef DEBUG | |
251 | void trace_input PARAMS ((char *name, enum op_types type, int size)); | |
252 | void trace_output PARAMS ((enum op_types result)); | |
253 | void trace_result PARAMS ((int has_result, unsigned32 result)); | |
254 | ||
255 | extern int trace_num_values; | |
256 | extern unsigned32 trace_values[]; | |
257 | extern unsigned32 trace_pc; | |
258 | extern const char *trace_name; | |
259 | extern int trace_module; | |
260 | ||
261 | #define TRACE_BRANCH0() \ | |
262 | do { \ | |
263 | if (TRACE_BRANCH_P (CPU)) { \ | |
264 | trace_module = TRACE_BRANCH_IDX; \ | |
265 | trace_pc = cia; \ | |
266 | trace_name = itable[MY_INDEX].name; \ | |
267 | trace_num_values = 0; \ | |
268 | trace_result (1, (nia)); \ | |
269 | } \ | |
270 | } while (0) | |
271 | ||
272 | #define TRACE_BRANCH1(IN1) \ | |
273 | do { \ | |
274 | if (TRACE_BRANCH_P (CPU)) { \ | |
275 | trace_module = TRACE_BRANCH_IDX; \ | |
276 | trace_pc = cia; \ | |
277 | trace_name = itable[MY_INDEX].name; \ | |
278 | trace_values[0] = (IN1); \ | |
279 | trace_num_values = 1; \ | |
280 | trace_result (1, (nia)); \ | |
281 | } \ | |
282 | } while (0) | |
283 | ||
284 | #define TRACE_BRANCH2(IN1, IN2) \ | |
285 | do { \ | |
286 | if (TRACE_BRANCH_P (CPU)) { \ | |
287 | trace_module = TRACE_BRANCH_IDX; \ | |
288 | trace_pc = cia; \ | |
289 | trace_name = itable[MY_INDEX].name; \ | |
290 | trace_values[0] = (IN1); \ | |
291 | trace_values[1] = (IN2); \ | |
292 | trace_num_values = 2; \ | |
293 | trace_result (1, (nia)); \ | |
294 | } \ | |
295 | } while (0) | |
296 | ||
297 | #define TRACE_BRANCH3(IN1, IN2, IN3) \ | |
298 | do { \ | |
299 | if (TRACE_BRANCH_P (CPU)) { \ | |
300 | trace_module = TRACE_BRANCH_IDX; \ | |
301 | trace_pc = cia; \ | |
302 | trace_name = itable[MY_INDEX].name; \ | |
303 | trace_values[0] = (IN1); \ | |
304 | trace_values[1] = (IN2); \ | |
305 | trace_values[2] = (IN3); \ | |
306 | trace_num_values = 3; \ | |
307 | trace_result (1, (nia)); \ | |
308 | } \ | |
309 | } while (0) | |
310 | ||
311 | #define TRACE_LD(ADDR,RESULT) \ | |
312 | do { \ | |
313 | if (TRACE_MEMORY_P (CPU)) { \ | |
314 | trace_module = TRACE_MEMORY_IDX; \ | |
315 | trace_pc = cia; \ | |
316 | trace_name = itable[MY_INDEX].name; \ | |
317 | trace_values[0] = (ADDR); \ | |
318 | trace_num_values = 1; \ | |
319 | trace_result (1, (RESULT)); \ | |
320 | } \ | |
321 | } while (0) | |
322 | ||
323 | #define TRACE_LD_NAME(NAME, ADDR,RESULT) \ | |
324 | do { \ | |
325 | if (TRACE_MEMORY_P (CPU)) { \ | |
326 | trace_module = TRACE_MEMORY_IDX; \ | |
327 | trace_pc = cia; \ | |
328 | trace_name = (NAME); \ | |
329 | trace_values[0] = (ADDR); \ | |
330 | trace_num_values = 1; \ | |
331 | trace_result (1, (RESULT)); \ | |
332 | } \ | |
333 | } while (0) | |
334 | ||
335 | #define TRACE_ST(ADDR,RESULT) \ | |
336 | do { \ | |
337 | if (TRACE_MEMORY_P (CPU)) { \ | |
338 | trace_module = TRACE_MEMORY_IDX; \ | |
339 | trace_pc = cia; \ | |
340 | trace_name = itable[MY_INDEX].name; \ | |
341 | trace_values[0] = (ADDR); \ | |
342 | trace_num_values = 1; \ | |
343 | trace_result (1, (RESULT)); \ | |
344 | } \ | |
345 | } while (0) | |
346 | ||
347 | #else | |
348 | #define trace_input(NAME, IN1, IN2) | |
349 | #define trace_output(RESULT) | |
350 | #define trace_result(HAS_RESULT, RESULT) | |
351 | ||
352 | #define TRACE_ALU_INPUT0() | |
353 | #define TRACE_ALU_INPUT1(IN0) | |
354 | #define TRACE_ALU_INPUT2(IN0, IN1) | |
355 | #define TRACE_ALU_INPUT2(IN0, IN1) | |
356 | #define TRACE_ALU_INPUT2(IN0, IN1 INS2) | |
357 | #define TRACE_ALU_RESULT(RESULT) | |
358 | ||
359 | #define TRACE_BRANCH0() | |
360 | #define TRACE_BRANCH1(IN1) | |
361 | #define TRACE_BRANCH2(IN1, IN2) | |
362 | #define TRACE_BRANCH2(IN1, IN2, IN3) | |
363 | ||
364 | #define TRACE_LD(ADDR,RESULT) | |
365 | #define TRACE_ST(ADDR,RESULT) | |
366 | ||
367 | #endif | |
368 | ||
369 | ||
370 | extern void divun ( unsigned int N, | |
371 | unsigned long int als, | |
372 | unsigned long int sfi, | |
373 | unsigned32 /*unsigned long int*/ * quotient_ptr, | |
374 | unsigned32 /*unsigned long int*/ * remainder_ptr, | |
375 | boolean * overflow_ptr | |
376 | ); | |
377 | extern void divn ( unsigned int N, | |
378 | unsigned long int als, | |
379 | unsigned long int sfi, | |
380 | signed32 /*signed long int*/ * quotient_ptr, | |
381 | signed32 /*signed long int*/ * remainder_ptr, | |
382 | boolean * overflow_ptr | |
383 | ); | |
384 | extern int type1_regs[]; | |
385 | extern int type2_regs[]; | |
386 | extern int type3_regs[]; | |
387 | ||
388 | #endif |