Commit | Line | Data |
---|---|---|
22c1c7dd JL |
1 | #include <signal.h> |
2 | #include "sysdep.h" | |
3 | #include "bfd.h" | |
4 | #include "remote-sim.h" | |
5 | #include "callback.h" | |
6 | ||
7 | #include "v850_sim.h" | |
8 | ||
28647e4c | 9 | #define MEM_SIZE 18 /* V850 memory size is 18 bits XXX */ |
22c1c7dd JL |
10 | |
11 | uint16 OP[4]; | |
12 | ||
13 | static struct hash_entry *lookup_hash PARAMS ((uint32 ins)); | |
14 | ||
15 | #define MAX_HASH 63 | |
16 | struct hash_entry | |
17 | { | |
18 | struct hash_entry *next; | |
19 | long opcode; | |
20 | long mask; | |
21 | struct simops *ops; | |
22 | }; | |
23 | ||
24 | struct hash_entry hash_table[MAX_HASH+1]; | |
25 | ||
26 | static long | |
27 | hash(insn) | |
28 | long insn; | |
29 | { | |
0ef0eba5 JL |
30 | if ((insn & 0x30) == 0 |
31 | || (insn & 0x38) == 0x10) | |
32 | return (insn & 0x07e0) >> 5; | |
33 | if ((insn & 0x3c) == 0x18 | |
34 | || (insn & 0x3c) == 0x1c | |
35 | || (insn & 0x3c) == 0x20 | |
36 | || (insn & 0x3c) == 0x24 | |
37 | || (insn & 0x3c) == 0x28 | |
38 | || (insn & 0x3c) == 0x23) | |
39 | return (insn & 0x07c0) >> 6; | |
40 | if ((insn & 0x38) == 0x30) | |
41 | return (insn & 0x07e0) >> 5; | |
42 | /* What about sub-op field? XXX */ | |
43 | if ((insn & 0x38) == 0x38) | |
44 | return (insn & 0x07e0) >> 5; | |
45 | if ((insn & 0x3e) == 0x3c) | |
46 | return (insn & 0x07c0) >> 6; | |
47 | if ((insn & 0x3f) == 0x3e) | |
48 | return (insn & 0xc7e0) >> 5; | |
49 | /* Not really correct. XXX */ | |
50 | return insn & 0xffffffff; | |
51 | ||
22c1c7dd JL |
52 | } |
53 | ||
54 | static struct hash_entry * | |
55 | lookup_hash (ins) | |
56 | uint32 ins; | |
57 | { | |
58 | struct hash_entry *h; | |
59 | ||
0ef0eba5 | 60 | h = &hash_table[hash(ins)]; |
22c1c7dd JL |
61 | |
62 | while ( (ins & h->mask) != h->opcode) | |
63 | { | |
64 | if (h->next == NULL) | |
65 | { | |
66 | printf ("ERROR looking up hash for %x\n",ins); | |
67 | exit(1); | |
68 | } | |
69 | h = h->next; | |
70 | } | |
71 | return (h); | |
72 | } | |
73 | ||
28647e4c JL |
74 | uint8 |
75 | get_byte (x) | |
76 | uint8 *x; | |
22c1c7dd | 77 | { |
28647e4c | 78 | return *x; |
0ef0eba5 JL |
79 | } |
80 | ||
28647e4c JL |
81 | uint16 |
82 | get_half (x) | |
83 | uint8 *x; | |
0ef0eba5 JL |
84 | { |
85 | uint8 *a = x; | |
28647e4c | 86 | return (a[1] << 8) + (a[0]); |
22c1c7dd JL |
87 | } |
88 | ||
28647e4c | 89 | uint32 |
0ef0eba5 JL |
90 | get_word (x) |
91 | uint8 *x; | |
22c1c7dd | 92 | { |
0ef0eba5 | 93 | uint8 *a = x; |
28647e4c | 94 | return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]); |
22c1c7dd JL |
95 | } |
96 | ||
97 | void | |
28647e4c | 98 | put_byte (addr, data) |
0ef0eba5 | 99 | uint8 *addr; |
28647e4c | 100 | uint8 data; |
22c1c7dd | 101 | { |
0ef0eba5 | 102 | uint8 *a = addr; |
28647e4c | 103 | a[0] = data; |
22c1c7dd JL |
104 | } |
105 | ||
0ef0eba5 | 106 | void |
28647e4c | 107 | put_half (addr, data) |
0ef0eba5 | 108 | uint8 *addr; |
28647e4c | 109 | uint16 data; |
0ef0eba5 | 110 | { |
28647e4c JL |
111 | uint8 *a = addr; |
112 | a[0] = data & 0xff; | |
113 | a[1] = (data >> 8) & 0xff; | |
0ef0eba5 JL |
114 | } |
115 | ||
116 | void | |
28647e4c | 117 | put_word (addr, data) |
0ef0eba5 | 118 | uint8 *addr; |
28647e4c | 119 | uint32 data; |
0ef0eba5 JL |
120 | { |
121 | uint8 *a = addr; | |
28647e4c JL |
122 | a[0] = data & 0xff; |
123 | a[1] = (data >> 8) & 0xff; | |
124 | a[2] = (data >> 16) & 0xff; | |
125 | a[3] = (data >> 24) & 0xff; | |
22c1c7dd JL |
126 | } |
127 | ||
128 | static void | |
0ef0eba5 | 129 | do_format_1_2 (insn) |
22c1c7dd JL |
130 | uint32 insn; |
131 | { | |
0ef0eba5 JL |
132 | struct hash_entry *h; |
133 | printf("format 1 or 2 0x%x\n", insn); | |
134 | ||
135 | h = lookup_hash (insn); | |
136 | OP[0] = insn & 0x1f; | |
137 | OP[1] = (insn >> 11) & 0x1f; | |
138 | (h->ops->func) (); | |
22c1c7dd JL |
139 | } |
140 | ||
141 | static void | |
142 | do_format_3 (insn) | |
143 | uint32 insn; | |
144 | { | |
2108e864 | 145 | struct hash_entry *h; |
0ef0eba5 | 146 | printf("format 3 0x%x\n", insn); |
2108e864 JL |
147 | |
148 | h = lookup_hash (insn); | |
149 | OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1; | |
150 | (h->ops->func) (); | |
22c1c7dd JL |
151 | } |
152 | ||
153 | static void | |
154 | do_format_4 (insn) | |
155 | uint32 insn; | |
156 | { | |
0ef0eba5 | 157 | printf("format 4 0x%x\n", insn); |
22c1c7dd JL |
158 | } |
159 | ||
160 | static void | |
161 | do_format_5 (insn) | |
162 | uint32 insn; | |
163 | { | |
e9b6cbac | 164 | struct hash_entry *h; |
22c1c7dd | 165 | printf("format 5 0x%x\n", insn); |
e9b6cbac JL |
166 | |
167 | h = lookup_hash (insn); | |
168 | OP[0] = ((insn & 0x3f) | (((insn >> 17) & 0x7fff) << 6)) << 1; | |
169 | OP[1] = (insn >> 11) & 0x1f; | |
170 | (h->ops->func) (); | |
22c1c7dd JL |
171 | } |
172 | ||
173 | static void | |
174 | do_format_6 (insn) | |
175 | uint32 insn; | |
176 | { | |
0ef0eba5 | 177 | struct hash_entry *h; |
22c1c7dd | 178 | printf("format 6 0x%x\n", insn); |
0ef0eba5 JL |
179 | |
180 | h = lookup_hash (insn); | |
181 | OP[0] = (insn >> 16) & 0xffff; | |
182 | OP[1] = insn & 0x1f; | |
183 | OP[2] = (insn >> 11) & 0x1f; | |
184 | (h->ops->func) (); | |
22c1c7dd JL |
185 | } |
186 | ||
187 | static void | |
188 | do_format_7 (insn) | |
189 | uint32 insn; | |
190 | { | |
28647e4c | 191 | struct hash_entry *h; |
22c1c7dd | 192 | printf("format 7 0x%x\n", insn); |
28647e4c JL |
193 | |
194 | h = lookup_hash (insn); | |
195 | OP[0] = insn & 0x1f; | |
196 | OP[1] = (insn >> 11) & 0x1f; | |
197 | OP[2] = (insn >> 16) & 0xffff; | |
198 | (h->ops->func) (); | |
22c1c7dd JL |
199 | } |
200 | ||
201 | static void | |
202 | do_format_8 (insn) | |
203 | uint32 insn; | |
204 | { | |
205 | printf("format 8 0x%x\n", insn); | |
206 | } | |
207 | ||
208 | static void | |
209 | do_formats_9_10 (insn) | |
210 | uint32 insn; | |
211 | { | |
0ef0eba5 | 212 | struct hash_entry *h; |
22c1c7dd | 213 | printf("formats 9 and 10 0x%x\n", insn); |
0ef0eba5 JL |
214 | |
215 | h = lookup_hash (insn); | |
216 | OP[0] = insn & 0x1f; | |
217 | OP[1] = (insn >> 11) & 0x1f; | |
218 | (h->ops->func) (); | |
22c1c7dd JL |
219 | } |
220 | ||
221 | void | |
222 | sim_size (power) | |
223 | int power; | |
224 | ||
225 | { | |
28647e4c | 226 | if (State.mem) |
22c1c7dd | 227 | { |
28647e4c | 228 | free (State.mem); |
22c1c7dd JL |
229 | } |
230 | ||
28647e4c JL |
231 | State.mem = (uint8 *)calloc(1,1<<MEM_SIZE); |
232 | if (!State.mem) | |
22c1c7dd JL |
233 | { |
234 | fprintf (stderr,"Memory allocation failed.\n"); | |
235 | exit(1); | |
236 | } | |
28647e4c | 237 | printf ("Allocated %d bytes memory and\n",1<<MEM_SIZE); |
22c1c7dd JL |
238 | } |
239 | ||
240 | static void | |
241 | init_system () | |
242 | { | |
28647e4c | 243 | if (!State.mem) |
22c1c7dd JL |
244 | sim_size(1); |
245 | } | |
246 | ||
247 | int | |
248 | sim_write (addr, buffer, size) | |
249 | SIM_ADDR addr; | |
250 | unsigned char *buffer; | |
251 | int size; | |
252 | { | |
253 | int i; | |
254 | init_system (); | |
255 | ||
256 | /* printf ("sim_write %d bytes to 0x%x\n",size,addr); */ | |
257 | for (i = 0; i < size; i++) | |
258 | { | |
28647e4c | 259 | State.mem[i+addr] = buffer[i]; |
22c1c7dd JL |
260 | } |
261 | return size; | |
262 | } | |
263 | ||
264 | void | |
265 | sim_open (args) | |
266 | char *args; | |
267 | { | |
268 | struct simops *s; | |
269 | struct hash_entry *h, *prev; | |
270 | if (args != NULL) | |
271 | printf ("sim_open %s\n",args); | |
272 | ||
273 | /* put all the opcodes in the hash table */ | |
274 | for (s = Simops; s->func; s++) | |
275 | { | |
276 | h = &hash_table[hash(s->opcode)]; | |
277 | ||
278 | /* go to the last entry in the chain */ | |
279 | while (h->next) | |
280 | h = h->next; | |
281 | ||
282 | if (h->ops) | |
283 | { | |
284 | h->next = calloc(1,sizeof(struct hash_entry)); | |
285 | h = h->next; | |
286 | } | |
287 | h->ops = s; | |
288 | h->mask = s->mask; | |
289 | h->opcode = s->opcode; | |
290 | } | |
291 | } | |
292 | ||
293 | ||
294 | void | |
295 | sim_close (quitting) | |
296 | int quitting; | |
297 | { | |
298 | /* nothing to do */ | |
299 | } | |
300 | ||
301 | void | |
302 | sim_set_profile (n) | |
303 | int n; | |
304 | { | |
305 | printf ("sim_set_profile %d\n",n); | |
306 | } | |
307 | ||
308 | void | |
309 | sim_set_profile_size (n) | |
310 | int n; | |
311 | { | |
312 | printf ("sim_set_profile_size %d\n",n); | |
313 | } | |
314 | ||
315 | void | |
316 | sim_resume (step, siggnal) | |
317 | int step, siggnal; | |
318 | { | |
319 | uint32 inst, opcode; | |
320 | int i; | |
321 | reg_t oldpc; | |
322 | ||
323 | /* printf ("sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */ | |
324 | ||
325 | if (step) | |
326 | State.exception = SIGTRAP; | |
327 | else | |
328 | State.exception = 0; | |
329 | ||
330 | do | |
331 | { | |
332 | inst = RLW (PC); | |
333 | oldpc = PC; | |
0ef0eba5 JL |
334 | opcode = (inst & 0x07e0) >> 5; |
335 | if ((opcode & 0x30) == 0 | |
336 | || (opcode & 0x38) == 0x10) | |
22c1c7dd | 337 | { |
0ef0eba5 | 338 | do_format_1_2 (inst & 0xffff); |
22c1c7dd JL |
339 | PC += 2; |
340 | } | |
341 | else if ((opcode & 0x3C) == 0x18 | |
342 | || (opcode & 0x3C) == 0x1C | |
343 | || (opcode & 0x3C) == 0x20 | |
344 | || (opcode & 0x3C) == 0x24 | |
345 | || (opcode & 0x3C) == 0x28) | |
346 | { | |
0ef0eba5 | 347 | do_format_4 (inst & 0xffff); |
22c1c7dd JL |
348 | PC += 2; |
349 | } | |
0ef0eba5 | 350 | else if ((opcode & 0x3C) == 0x23) |
22c1c7dd | 351 | { |
0ef0eba5 JL |
352 | do_format_3 (inst & 0xffff); |
353 | /* No PC update, it's done in the instruction. */ | |
22c1c7dd JL |
354 | } |
355 | else if ((opcode & 0x38) == 0x30) | |
356 | { | |
357 | do_format_6 (inst); | |
358 | PC += 4; | |
359 | } | |
360 | else if ((opcode & 0x3C) == 0x38) | |
361 | { | |
362 | do_format_7 (inst); | |
363 | PC += 4; | |
364 | } | |
365 | else if ((opcode & 0x3E) == 0x3C) | |
366 | { | |
367 | do_format_5 (inst); | |
e9b6cbac | 368 | /* No PC update, it's done in the instruction. */ |
22c1c7dd | 369 | } |
0ef0eba5 | 370 | else if ((opcode & 0x3F) == 0x3E) |
22c1c7dd JL |
371 | { |
372 | do_format_8 (inst); | |
373 | PC += 4; | |
374 | } | |
375 | else | |
376 | { | |
377 | do_formats_9_10 (inst); | |
378 | PC += 4; | |
379 | } | |
380 | } | |
381 | while (!State.exception); | |
382 | } | |
383 | ||
384 | int | |
385 | sim_trace () | |
386 | { | |
387 | printf ("sim_trace\n"); | |
388 | return 0; | |
389 | } | |
390 | ||
391 | void | |
392 | sim_info (verbose) | |
393 | int verbose; | |
394 | { | |
395 | printf ("sim_info\n"); | |
396 | } | |
397 | ||
398 | void | |
399 | sim_create_inferior (start_address, argv, env) | |
400 | SIM_ADDR start_address; | |
401 | char **argv; | |
402 | char **env; | |
403 | { | |
404 | printf ("sim_create_inferior: PC=0x%x\n",start_address); | |
405 | PC = start_address; | |
406 | } | |
407 | ||
408 | ||
409 | void | |
410 | sim_kill () | |
411 | { | |
412 | /* nothing to do */ | |
413 | } | |
414 | ||
415 | void | |
416 | sim_set_callbacks(p) | |
417 | host_callback *p; | |
418 | { | |
419 | printf ("sim_set_callbacks\n"); | |
420 | /* callback = p; */ | |
421 | } | |
422 | ||
423 | void | |
424 | sim_stop_reason (reason, sigrc) | |
425 | enum sim_stop *reason; | |
426 | int *sigrc; | |
427 | { | |
428 | /* printf ("sim_stop_reason: PC=0x%x\n",PC); */ | |
429 | ||
430 | if (State.exception == SIGQUIT) | |
431 | { | |
432 | *reason = sim_exited; | |
433 | *sigrc = State.exception; | |
434 | } | |
435 | else | |
436 | { | |
437 | *reason = sim_stopped; | |
438 | *sigrc = State.exception; | |
439 | } | |
440 | } | |
441 | ||
442 | void | |
443 | sim_fetch_register (rn, memory) | |
444 | int rn; | |
445 | unsigned char *memory; | |
446 | { | |
447 | *(uint32 *)memory = State.regs[rn]; | |
448 | /* printf ("sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */ | |
449 | } | |
450 | ||
451 | void | |
452 | sim_store_register (rn, memory) | |
453 | int rn; | |
454 | unsigned char *memory; | |
455 | { | |
456 | State.regs[rn]= *(uint32 *)memory; | |
457 | /* printf ("store: r%d=0x%x\n",rn,State.regs[rn]); */ | |
458 | } | |
459 | ||
460 | sim_read (addr, buffer, size) | |
461 | SIM_ADDR addr; | |
462 | unsigned char *buffer; | |
463 | int size; | |
464 | { | |
465 | int i; | |
466 | for (i = 0; i < size; i++) | |
467 | { | |
28647e4c | 468 | buffer[i] = State.mem[addr + i]; |
22c1c7dd JL |
469 | } |
470 | return size; | |
471 | } | |
472 | ||
473 | void | |
474 | sim_do_command (cmd) | |
475 | char *cmd; | |
476 | { | |
477 | printf("sim_do_command: %s\n",cmd); | |
478 | } | |
479 | ||
480 | int | |
481 | sim_load (prog, from_tty) | |
482 | char *prog; | |
483 | int from_tty; | |
484 | { | |
485 | /* Return nonzero so GDB will handle it. */ | |
486 | return 1; | |
487 | } |