Commit | Line | Data |
---|---|---|
05ccbdfd JL |
1 | #include <signal.h> |
2 | #include "sysdep.h" | |
3 | #include "bfd.h" | |
4 | ||
5 | #include "mn10300_sim.h" | |
6 | ||
7 | #ifndef INLINE | |
8 | #ifdef __GNUC__ | |
9 | #define INLINE inline | |
10 | #else | |
11 | #define INLINE | |
12 | #endif | |
13 | #endif | |
14 | ||
15 | host_callback *mn10300_callback; | |
16 | int mn10300_debug; | |
6cc6987e DE |
17 | static SIM_OPEN_KIND sim_kind; |
18 | static char *myname; | |
05ccbdfd | 19 | |
d2523010 | 20 | static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int)); |
05ccbdfd JL |
21 | static long hash PARAMS ((long)); |
22 | static void init_system PARAMS ((void)); | |
05ccbdfd JL |
23 | #define MAX_HASH 63 |
24 | ||
25 | struct hash_entry | |
26 | { | |
27 | struct hash_entry *next; | |
28 | long opcode; | |
29 | long mask; | |
30 | struct simops *ops; | |
31 | }; | |
32 | ||
33 | struct hash_entry hash_table[MAX_HASH+1]; | |
34 | ||
35 | ||
d2523010 JL |
36 | /* This probably doesn't do a very good job at bucket filling, but |
37 | it's simple... */ | |
05ccbdfd JL |
38 | static INLINE long |
39 | hash(insn) | |
40 | long insn; | |
41 | { | |
d2523010 JL |
42 | /* These are one byte insns. */ |
43 | if ((insn & 0xffffff00) == 0) | |
44 | { | |
45 | if ((insn & 0xf0) == 0x00 | |
46 | || (insn & 0xf0) == 0x40) | |
47 | return (insn & 0xf3) & 0x3f; | |
48 | ||
49 | if ((insn & 0xf0) == 0x10 | |
50 | || (insn & 0xf0) == 0x30 | |
51 | || (insn & 0xf0) == 0x50) | |
52 | return (insn & 0xfc) & 0x3f; | |
53 | ||
54 | if ((insn & 0xf0) == 0x60 | |
55 | || (insn & 0xf0) == 0x70 | |
56 | || (insn & 0xf0) == 0x80 | |
57 | || (insn & 0xf0) == 0x90 | |
58 | || (insn & 0xf0) == 0xa0 | |
59 | || (insn & 0xf0) == 0xb0 | |
60 | || (insn & 0xf0) == 0xe0) | |
61 | return (insn & 0xf0) & 0x3f; | |
62 | ||
63 | return (insn & 0xff) & 0x3f; | |
64 | } | |
65 | ||
66 | /* These are two byte insns */ | |
67 | if ((insn & 0xffff0000) == 0) | |
68 | { | |
69 | if ((insn & 0xf000) == 0x2000 | |
70 | || (insn & 0xf000) == 0x5000) | |
71 | return ((insn & 0xfc00) >> 8) & 0x3f; | |
72 | ||
73 | if ((insn & 0xf000) == 0x4000) | |
74 | return ((insn & 0xf300) >> 8) & 0x3f; | |
75 | ||
76 | if ((insn & 0xf000) == 0x8000 | |
77 | || (insn & 0xf000) == 0x9000 | |
78 | || (insn & 0xf000) == 0xa000 | |
79 | || (insn & 0xf000) == 0xb000) | |
80 | return ((insn & 0xf000) >> 8) & 0x3f; | |
81 | ||
82 | return ((insn & 0xff00) >> 8) & 0x3f; | |
83 | } | |
84 | ||
85 | /* These are three byte insns. */ | |
86 | if ((insn & 0xff000000) == 0) | |
87 | { | |
88 | if ((insn & 0xf00000) == 0x000000) | |
89 | return ((insn & 0xf30000) >> 16) & 0x3f; | |
90 | ||
91 | if ((insn & 0xf00000) == 0x200000 | |
92 | || (insn & 0xf00000) == 0x300000) | |
93 | return ((insn & 0xfc0000) >> 16) & 0x3f; | |
94 | ||
95 | return ((insn & 0xff0000) >> 16) & 0x3f; | |
96 | } | |
97 | ||
98 | /* These are four byte or larger insns. */ | |
99 | return ((insn & 0xff000000) >> 24) & 0x3f; | |
05ccbdfd JL |
100 | } |
101 | ||
102 | static struct hash_entry * | |
d2523010 | 103 | lookup_hash (ins, length) |
05ccbdfd | 104 | uint32 ins; |
d2523010 | 105 | int length; |
05ccbdfd JL |
106 | { |
107 | struct hash_entry *h; | |
108 | ||
109 | h = &hash_table[hash(ins)]; | |
110 | ||
d2523010 JL |
111 | while ((ins & h->mask) != h->opcode |
112 | || (length != h->ops->length)) | |
05ccbdfd JL |
113 | { |
114 | if (h->next == NULL) | |
115 | { | |
116 | (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC); | |
117 | exit(1); | |
118 | } | |
119 | h = h->next; | |
120 | } | |
121 | return (h); | |
122 | } | |
123 | ||
124 | /* FIXME These would more efficient to use than load_mem/store_mem, | |
125 | but need to be changed to use the memory map. */ | |
126 | ||
127 | uint8 | |
128 | get_byte (x) | |
129 | uint8 *x; | |
130 | { | |
131 | return *x; | |
132 | } | |
133 | ||
134 | uint16 | |
135 | get_half (x) | |
136 | uint8 *x; | |
137 | { | |
138 | uint8 *a = x; | |
139 | return (a[1] << 8) + (a[0]); | |
140 | } | |
141 | ||
142 | uint32 | |
143 | get_word (x) | |
144 | uint8 *x; | |
145 | { | |
146 | uint8 *a = x; | |
147 | return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]); | |
148 | } | |
149 | ||
150 | void | |
151 | put_byte (addr, data) | |
152 | uint8 *addr; | |
153 | uint8 data; | |
154 | { | |
155 | uint8 *a = addr; | |
156 | a[0] = data; | |
157 | } | |
158 | ||
159 | void | |
160 | put_half (addr, data) | |
161 | uint8 *addr; | |
162 | uint16 data; | |
163 | { | |
164 | uint8 *a = addr; | |
165 | a[0] = data & 0xff; | |
166 | a[1] = (data >> 8) & 0xff; | |
167 | } | |
168 | ||
169 | void | |
170 | put_word (addr, data) | |
171 | uint8 *addr; | |
172 | uint32 data; | |
173 | { | |
174 | uint8 *a = addr; | |
175 | a[0] = data & 0xff; | |
176 | a[1] = (data >> 8) & 0xff; | |
177 | a[2] = (data >> 16) & 0xff; | |
178 | a[3] = (data >> 24) & 0xff; | |
179 | } | |
180 | ||
181 | ||
d2523010 JL |
182 | uint32 |
183 | load_mem_big (addr, len) | |
184 | SIM_ADDR addr; | |
185 | int len; | |
186 | { | |
187 | uint8 *p = addr + State.mem; | |
188 | ||
189 | switch (len) | |
190 | { | |
191 | case 1: | |
192 | return p[0]; | |
193 | case 2: | |
194 | return p[0] << 8 | p[1]; | |
195 | case 3: | |
196 | return p[0] << 16 | p[1] << 8 | p[2]; | |
197 | case 4: | |
198 | return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; | |
199 | default: | |
200 | abort (); | |
201 | } | |
202 | } | |
203 | ||
05ccbdfd JL |
204 | uint32 |
205 | load_mem (addr, len) | |
206 | SIM_ADDR addr; | |
207 | int len; | |
208 | { | |
209 | uint8 *p = addr + State.mem; | |
210 | ||
211 | switch (len) | |
212 | { | |
213 | case 1: | |
214 | return p[0]; | |
215 | case 2: | |
216 | return p[1] << 8 | p[0]; | |
d2523010 JL |
217 | case 3: |
218 | return p[2] << 16 | p[1] << 8 | p[0]; | |
05ccbdfd JL |
219 | case 4: |
220 | return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; | |
221 | default: | |
222 | abort (); | |
223 | } | |
224 | } | |
225 | ||
226 | void | |
227 | store_mem (addr, len, data) | |
228 | SIM_ADDR addr; | |
229 | int len; | |
230 | uint32 data; | |
231 | { | |
232 | uint8 *p = addr + State.mem; | |
233 | ||
234 | switch (len) | |
235 | { | |
236 | case 1: | |
237 | p[0] = data; | |
238 | return; | |
239 | case 2: | |
240 | p[0] = data; | |
241 | p[1] = data >> 8; | |
242 | return; | |
243 | case 4: | |
244 | p[0] = data; | |
245 | p[1] = data >> 8; | |
246 | p[2] = data >> 16; | |
247 | p[3] = data >> 24; | |
248 | return; | |
249 | default: | |
250 | abort (); | |
251 | } | |
252 | } | |
253 | ||
254 | void | |
255 | sim_size (power) | |
256 | int power; | |
257 | ||
258 | { | |
259 | if (State.mem) | |
260 | free (State.mem); | |
261 | ||
262 | State.mem = (uint8 *) calloc (1, 1 << power); | |
263 | if (!State.mem) | |
264 | { | |
265 | (*mn10300_callback->printf_filtered) (mn10300_callback, "Allocation of main memory failed.\n"); | |
266 | exit (1); | |
267 | } | |
268 | } | |
269 | ||
270 | static void | |
271 | init_system () | |
272 | { | |
273 | if (!State.mem) | |
6cc6987e | 274 | sim_size(19); |
05ccbdfd JL |
275 | } |
276 | ||
277 | int | |
6cc6987e DE |
278 | sim_write (sd, addr, buffer, size) |
279 | SIM_DESC sd; | |
05ccbdfd JL |
280 | SIM_ADDR addr; |
281 | unsigned char *buffer; | |
282 | int size; | |
283 | { | |
284 | int i; | |
285 | ||
286 | init_system (); | |
287 | ||
288 | for (i = 0; i < size; i++) | |
289 | store_mem (addr + i, 1, buffer[i]); | |
290 | ||
291 | return size; | |
292 | } | |
293 | ||
6cc6987e DE |
294 | SIM_DESC |
295 | sim_open (kind,argv) | |
296 | SIM_OPEN_KIND kind; | |
297 | char **argv; | |
05ccbdfd JL |
298 | { |
299 | struct simops *s; | |
300 | struct hash_entry *h; | |
6cc6987e DE |
301 | char **p; |
302 | ||
303 | sim_kind = kind; | |
304 | myname = argv[0]; | |
305 | ||
306 | for (p = argv + 1; *p; ++p) | |
05ccbdfd | 307 | { |
6cc6987e DE |
308 | if (strcmp (*p, "-E") == 0) |
309 | ++p; /* ignore endian spec */ | |
310 | else | |
05ccbdfd | 311 | #ifdef DEBUG |
6cc6987e | 312 | if (strcmp (*p, "-t") == 0) |
05ccbdfd JL |
313 | mn10300_debug = DEBUG; |
314 | else | |
315 | #endif | |
6cc6987e | 316 | (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR: unsupported option(s): %s\n",*p); |
05ccbdfd JL |
317 | } |
318 | ||
319 | /* put all the opcodes in the hash table */ | |
320 | for (s = Simops; s->func; s++) | |
321 | { | |
322 | h = &hash_table[hash(s->opcode)]; | |
323 | ||
324 | /* go to the last entry in the chain */ | |
325 | while (h->next) | |
326 | h = h->next; | |
327 | ||
328 | if (h->ops) | |
329 | { | |
330 | h->next = calloc(1,sizeof(struct hash_entry)); | |
331 | h = h->next; | |
332 | } | |
333 | h->ops = s; | |
334 | h->mask = s->mask; | |
335 | h->opcode = s->opcode; | |
336 | } | |
6cc6987e DE |
337 | |
338 | /* fudge our descriptor for now */ | |
339 | return (SIM_DESC) 1; | |
05ccbdfd JL |
340 | } |
341 | ||
342 | ||
343 | void | |
6cc6987e DE |
344 | sim_close (sd, quitting) |
345 | SIM_DESC sd; | |
05ccbdfd JL |
346 | int quitting; |
347 | { | |
348 | /* nothing to do */ | |
349 | } | |
350 | ||
351 | void | |
352 | sim_set_profile (n) | |
353 | int n; | |
354 | { | |
355 | (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile %d\n", n); | |
356 | } | |
357 | ||
358 | void | |
359 | sim_set_profile_size (n) | |
360 | int n; | |
361 | { | |
362 | (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile_size %d\n", n); | |
363 | } | |
364 | ||
365 | void | |
6cc6987e DE |
366 | sim_resume (sd, step, siggnal) |
367 | SIM_DESC sd; | |
05ccbdfd JL |
368 | int step, siggnal; |
369 | { | |
7c52bf32 | 370 | uint32 inst; |
05ccbdfd | 371 | reg_t oldpc; |
d2523010 | 372 | struct hash_entry *h; |
05ccbdfd JL |
373 | |
374 | if (step) | |
375 | State.exception = SIGTRAP; | |
376 | else | |
377 | State.exception = 0; | |
378 | ||
379 | do | |
380 | { | |
d2523010 JL |
381 | unsigned long insn, extension; |
382 | ||
05ccbdfd | 383 | /* Fetch the current instruction. */ |
d2523010 | 384 | inst = load_mem_big (PC, 1); |
05ccbdfd | 385 | oldpc = PC; |
05ccbdfd | 386 | |
d2523010 JL |
387 | /* These are one byte insns. */ |
388 | if ((inst & 0xf3) == 0x00 | |
389 | || (inst & 0xf0) == 0x10 | |
390 | || (inst & 0xfc) == 0x3c | |
391 | || (inst & 0xf3) == 0x41 | |
392 | || (inst & 0xf3) == 0x40 | |
393 | || (inst & 0xfc) == 0x50 | |
394 | || (inst & 0xfc) == 0x54 | |
395 | || (inst & 0xf0) == 0x60 | |
396 | || (inst & 0xf0) == 0x70 | |
397 | || ((inst & 0xf0) == 0x80 | |
398 | && (inst & 0x0c) >> 2 != (inst & 0x03)) | |
399 | || ((inst & 0xf0) == 0x90 | |
400 | && (inst & 0x0c) >> 2 != (inst & 0x03)) | |
401 | || ((inst & 0xf0) == 0xa0 | |
402 | && (inst & 0x0c) >> 2 != (inst & 0x03)) | |
403 | || ((inst & 0xf0) == 0xb0 | |
404 | && (inst & 0x0c) >> 2 != (inst & 0x03)) | |
405 | || (inst & 0xff) == 0xcb | |
406 | || (inst & 0xfc) == 0xd0 | |
407 | || (inst & 0xfc) == 0xd4 | |
408 | || (inst & 0xfc) == 0xd8 | |
6cc6987e DE |
409 | || (inst & 0xf0) == 0xe0 |
410 | || (inst & 0xff) == 0xff) | |
d2523010 JL |
411 | { |
412 | insn = inst; | |
413 | h = lookup_hash (insn, 1); | |
414 | extension = 0; | |
415 | (h->ops->func)(insn, extension); | |
416 | PC += 1; | |
417 | } | |
418 | ||
419 | /* These are two byte insns. */ | |
420 | else if ((inst & 0xf0) == 0x80 | |
421 | || (inst & 0xf0) == 0x90 | |
422 | || (inst & 0xf0) == 0xa0 | |
423 | || (inst & 0xf0) == 0xb0 | |
424 | || (inst & 0xfc) == 0x20 | |
425 | || (inst & 0xfc) == 0x28 | |
426 | || (inst & 0xf3) == 0x43 | |
427 | || (inst & 0xf3) == 0x42 | |
428 | || (inst & 0xfc) == 0x58 | |
429 | || (inst & 0xfc) == 0x5c | |
430 | || ((inst & 0xf0) == 0xc0 | |
431 | && (inst & 0xff) != 0xcb | |
432 | && (inst & 0xff) != 0xcc | |
433 | && (inst & 0xff) != 0xcd) | |
434 | || (inst & 0xff) == 0xf0 | |
435 | || (inst & 0xff) == 0xf1 | |
436 | || (inst & 0xff) == 0xf2 | |
437 | || (inst & 0xff) == 0xf3 | |
438 | || (inst & 0xff) == 0xf4 | |
439 | || (inst & 0xff) == 0xf5 | |
440 | || (inst & 0xff) == 0xf6) | |
441 | { | |
442 | insn = load_mem_big (PC, 2); | |
443 | h = lookup_hash (insn, 2); | |
444 | extension = 0; | |
445 | (h->ops->func)(insn, extension); | |
446 | PC += 2; | |
447 | } | |
448 | ||
449 | /* These are three byte insns. */ | |
450 | else if ((inst & 0xff) == 0xf8 | |
451 | || (inst & 0xff) == 0xcc | |
452 | || (inst & 0xff) == 0xf9 | |
453 | || (inst & 0xf3) == 0x01 | |
454 | || (inst & 0xf3) == 0x02 | |
455 | || (inst & 0xf3) == 0x03 | |
456 | || (inst & 0xfc) == 0x24 | |
457 | || (inst & 0xfc) == 0x2c | |
458 | || (inst & 0xfc) == 0x30 | |
459 | || (inst & 0xfc) == 0x34 | |
460 | || (inst & 0xfc) == 0x38 | |
461 | || (inst & 0xff) == 0xde | |
462 | || (inst & 0xff) == 0xdf | |
463 | || (inst & 0xff) == 0xcc) | |
464 | { | |
465 | insn = load_mem_big (PC, 3); | |
466 | h = lookup_hash (insn, 3); | |
467 | extension = 0; | |
6cc6987e DE |
468 | /* If it's a format D1 insn, "ret", or "retf" insn, then |
469 | there's no need to worry about endianness. Others have | |
470 | a 16bit immediate in little endian form that we need to | |
471 | extract. */ | |
472 | if (h->ops->format == FMT_D1 | |
473 | || h->opcode == 0xdf0000 | |
474 | || h->opcode == 0xde0000) | |
475 | (h->ops->func)(insn, extension); | |
476 | else | |
477 | { | |
478 | insn &= 0xff0000; | |
479 | insn |= load_mem (PC + 1, 2); | |
480 | (h->ops->func)(insn, extension); | |
481 | } | |
d2523010 JL |
482 | PC += 3; |
483 | } | |
484 | ||
485 | /* These are four byte insns. */ | |
486 | else if ((inst & 0xff) == 0xfa | |
487 | || (inst & 0xff) == 0xfb) | |
488 | { | |
489 | insn = load_mem_big (PC, 4); | |
490 | h = lookup_hash (insn, 4); | |
491 | extension = 0; | |
6cc6987e DE |
492 | /* This must be a format D2 insn; a small number of such insns |
493 | don't have any 16bit immediates (they instead have two 8 bit | |
494 | immediates). */ | |
495 | if (h->opcode == 0xfaf80000 | |
496 | || h->opcode == 0xfaf00000 | |
497 | || h->opcode == 0xfaf40000) | |
498 | (h->ops->func)(insn, extension); | |
499 | else | |
500 | { | |
501 | insn &= 0xffff0000; | |
502 | insn |= load_mem (PC + 2, 2); | |
503 | (h->ops->func)(insn, extension); | |
504 | } | |
d2523010 JL |
505 | PC += 4; |
506 | } | |
507 | ||
508 | /* These are five byte insns. */ | |
509 | else if ((inst & 0xff) == 0xcd | |
510 | || (inst & 0xff) == 0xdc) | |
511 | { | |
512 | insn = load_mem_big (PC, 4); | |
513 | h = lookup_hash (insn, 5); | |
6cc6987e DE |
514 | |
515 | /* This must be a format S4 insn. */ | |
516 | if (h->opcode == 0xdc000000) | |
517 | { | |
518 | /* A "jmp" instruction with a 32bit immediate stored | |
519 | in little endian form. */ | |
520 | unsigned long temp; | |
521 | temp = load_mem (PC + 1, 4); | |
522 | insn &= 0xff000000; | |
523 | insn |= (temp & 0xffffff00) >> 8; | |
524 | extension = temp & 0xff; | |
525 | } | |
526 | else | |
527 | { | |
528 | /* A "call" instruction with a 16bit immediate in little | |
529 | endian form. */ | |
530 | unsigned long temp; | |
531 | temp = load_mem (PC + 1, 2); | |
532 | insn &= 0xff0000ff; | |
533 | insn |= temp << 8; | |
534 | extension = load_mem (PC + 4, 1); | |
535 | } | |
d2523010 JL |
536 | (h->ops->func)(insn, extension); |
537 | PC += 5; | |
538 | } | |
539 | ||
540 | /* These are six byte insns. */ | |
541 | else if ((inst & 0xff) == 0xfd | |
542 | || (inst & 0xff) == 0xfc) | |
543 | { | |
6cc6987e DE |
544 | unsigned long temp; |
545 | ||
d2523010 JL |
546 | insn = load_mem_big (PC, 4); |
547 | h = lookup_hash (insn, 6); | |
6cc6987e DE |
548 | |
549 | temp = load_mem (PC + 2, 4); | |
550 | insn &= 0xffff0000; | |
551 | insn |= (temp >> 16) & 0xffff; | |
552 | extension = temp & 0xffff; | |
d2523010 JL |
553 | (h->ops->func)(insn, extension); |
554 | PC += 6; | |
555 | } | |
556 | ||
557 | /* Else its a seven byte insns (in theory). */ | |
558 | else | |
05ccbdfd | 559 | { |
d2523010 JL |
560 | insn = load_mem_big (PC, 4); |
561 | h = lookup_hash (insn, 7); | |
6cc6987e DE |
562 | |
563 | if (h->ops->format == FMT_S6) | |
564 | { | |
565 | unsigned long temp; | |
566 | ||
567 | temp = load_mem (PC + 1, 4); | |
568 | insn &= 0xff000000; | |
569 | insn |= (temp >> 8) & 0xffffff; | |
570 | ||
571 | extension = (temp & 0xff) << 16; | |
572 | extension |= load_mem (PC + 5, 1) << 8; | |
573 | extension |= load_mem (PC + 6, 1); | |
574 | } | |
575 | else | |
576 | { | |
577 | unsigned long temp; | |
578 | ||
579 | temp = load_mem (PC + 2, 4); | |
580 | insn &= 0xffff0000; | |
581 | insn |= (temp >> 16) & 0xffff; | |
582 | extension = (temp & 0xffff) << 8; | |
583 | extension = load_mem (PC + 6, 1); | |
584 | } | |
d2523010 JL |
585 | (h->ops->func)(insn, extension); |
586 | PC += 7; | |
05ccbdfd JL |
587 | } |
588 | } | |
589 | while (!State.exception); | |
590 | } | |
591 | ||
592 | int | |
6cc6987e DE |
593 | sim_trace (sd) |
594 | SIM_DESC sd; | |
05ccbdfd JL |
595 | { |
596 | #ifdef DEBUG | |
597 | mn10300_debug = DEBUG; | |
598 | #endif | |
6cc6987e | 599 | sim_resume (sd, 0, 0); |
05ccbdfd JL |
600 | return 1; |
601 | } | |
602 | ||
603 | void | |
6cc6987e DE |
604 | sim_info (sd, verbose) |
605 | SIM_DESC sd; | |
05ccbdfd JL |
606 | int verbose; |
607 | { | |
608 | (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_info\n"); | |
609 | } | |
610 | ||
6cc6987e DE |
611 | SIM_RC |
612 | sim_create_inferior (sd, argv, env) | |
613 | SIM_DESC sd; | |
05ccbdfd JL |
614 | char **argv; |
615 | char **env; | |
616 | { | |
6cc6987e | 617 | return SIM_RC_OK; |
05ccbdfd JL |
618 | } |
619 | ||
620 | void | |
6cc6987e DE |
621 | sim_kill (sd) |
622 | SIM_DESC sd; | |
05ccbdfd JL |
623 | { |
624 | /* nothing to do */ | |
625 | } | |
626 | ||
627 | void | |
6cc6987e DE |
628 | sim_set_callbacks (sd, p) |
629 | SIM_DESC sd; | |
05ccbdfd JL |
630 | host_callback *p; |
631 | { | |
632 | mn10300_callback = p; | |
633 | } | |
634 | ||
635 | /* All the code for exiting, signals, etc needs to be revamped. | |
636 | ||
637 | This is enough to get c-torture limping though. */ | |
638 | ||
639 | void | |
6cc6987e DE |
640 | sim_stop_reason (sd, reason, sigrc) |
641 | SIM_DESC sd; | |
05ccbdfd JL |
642 | enum sim_stop *reason; |
643 | int *sigrc; | |
644 | { | |
645 | *reason = sim_stopped; | |
646 | if (State.exception == SIGQUIT) | |
647 | *sigrc = 0; | |
648 | else | |
649 | *sigrc = State.exception; | |
650 | } | |
651 | ||
652 | void | |
6cc6987e DE |
653 | sim_fetch_register (sd, rn, memory) |
654 | SIM_DESC sd; | |
05ccbdfd JL |
655 | int rn; |
656 | unsigned char *memory; | |
657 | { | |
658 | put_word (memory, State.regs[rn]); | |
659 | } | |
660 | ||
661 | void | |
6cc6987e DE |
662 | sim_store_register (sd, rn, memory) |
663 | SIM_DESC sd; | |
05ccbdfd JL |
664 | int rn; |
665 | unsigned char *memory; | |
666 | { | |
667 | State.regs[rn] = get_word (memory); | |
668 | } | |
669 | ||
670 | int | |
6cc6987e DE |
671 | sim_read (sd, addr, buffer, size) |
672 | SIM_DESC sd; | |
05ccbdfd JL |
673 | SIM_ADDR addr; |
674 | unsigned char *buffer; | |
675 | int size; | |
676 | { | |
677 | int i; | |
678 | for (i = 0; i < size; i++) | |
679 | buffer[i] = load_mem (addr + i, 1); | |
680 | ||
681 | return size; | |
682 | } | |
683 | ||
684 | void | |
6cc6987e DE |
685 | sim_do_command (sd, cmd) |
686 | SIM_DESC sd; | |
05ccbdfd JL |
687 | char *cmd; |
688 | { | |
689 | (*mn10300_callback->printf_filtered) (mn10300_callback, "\"%s\" is not a valid mn10300 simulator command.\n", cmd); | |
690 | } | |
691 | ||
6cc6987e DE |
692 | SIM_RC |
693 | sim_load (sd, prog, abfd, from_tty) | |
694 | SIM_DESC sd; | |
05ccbdfd | 695 | char *prog; |
6cc6987e | 696 | bfd *abfd; |
05ccbdfd JL |
697 | int from_tty; |
698 | { | |
6cc6987e DE |
699 | extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ |
700 | bfd *prog_bfd; | |
701 | ||
702 | prog_bfd = sim_load_file (sd, myname, mn10300_callback, prog, abfd, | |
703 | sim_kind == SIM_OPEN_DEBUG); | |
704 | if (prog_bfd == NULL) | |
705 | return SIM_RC_FAIL; | |
706 | PC = bfd_get_start_address (prog_bfd); | |
707 | if (abfd == NULL) | |
708 | bfd_close (prog_bfd); | |
709 | return SIM_RC_OK; | |
05ccbdfd | 710 | } |