]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/d10v/interp.c
*** empty log message ***
[thirdparty/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
c906108c
SS
1#include <signal.h>
2#include "sysdep.h"
3#include "bfd.h"
4#include "callback.h"
5#include "remote-sim.h"
6
7#include "d10v_sim.h"
4ce44c66 8#include "sim-d10v.h"
c906108c
SS
9
10enum _leftright { LEFT_FIRST, RIGHT_FIRST };
11
12static char *myname;
13static SIM_OPEN_KIND sim_kind;
14int d10v_debug;
cff3e48b
JM
15
16/* Set this to true to get the previous segment layout. */
17
18int old_segment_mapping;
19
c906108c
SS
20host_callback *d10v_callback;
21unsigned long ins_type_counters[ (int)INS_MAX ];
22
23uint16 OP[4];
24
25static int init_text_p = 0;
26/* non-zero if we opened prog_bfd */
27static int prog_bfd_was_opened_p;
28bfd *prog_bfd;
29asection *text;
30bfd_vma text_start;
31bfd_vma text_end;
32
33static long hash PARAMS ((long insn, int format));
34static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
35static void get_operands PARAMS ((struct simops *s, uint32 ins));
36static void do_long PARAMS ((uint32 ins));
37static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
38static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
39static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
40extern void sim_set_profile PARAMS ((int n));
41extern void sim_set_profile_size PARAMS ((int n));
4ce44c66 42static INLINE uint8 *map_memory (unsigned phys_addr);
c906108c 43
7a292a7a
SS
44#ifdef NEED_UI_LOOP_HOOK
45/* How often to run the ui_loop update, when in use */
46#define UI_LOOP_POLL_INTERVAL 0x14000
47
48/* Counter for the ui_loop_hook update */
49static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
50
51/* Actual hook to call to run through gdb's gui event loop */
52extern int (*ui_loop_hook) PARAMS ((int signo));
53#endif /* NEED_UI_LOOP_HOOK */
54
c906108c
SS
55#ifndef INLINE
56#if defined(__GNUC__) && defined(__OPTIMIZE__)
57#define INLINE __inline__
58#else
59#define INLINE
60#endif
61#endif
62
63#define MAX_HASH 63
64struct hash_entry
65{
66 struct hash_entry *next;
67 uint32 opcode;
68 uint32 mask;
69 int size;
70 struct simops *ops;
71};
72
73struct hash_entry hash_table[MAX_HASH+1];
74
75INLINE static long
76hash(insn, format)
77 long insn;
78 int format;
79{
80 if (format & LONG_OPCODE)
81 return ((insn & 0x3F000000) >> 24);
82 else
83 return((insn & 0x7E00) >> 9);
84}
85
86INLINE static struct hash_entry *
87lookup_hash (ins, size)
88 uint32 ins;
89 int size;
90{
91 struct hash_entry *h;
92
93 if (size)
94 h = &hash_table[(ins & 0x3F000000) >> 24];
95 else
96 h = &hash_table[(ins & 0x7E00) >> 9];
97
98 while ((ins & h->mask) != h->opcode || h->size != size)
99 {
100 if (h->next == NULL)
101 {
4ce44c66 102 State.exception = SIGILL;
c3f6f71d 103 State.pc_changed = 1; /* Don't increment the PC. */
4ce44c66 104 return NULL;
c906108c
SS
105 }
106 h = h->next;
107 }
108 return (h);
109}
110
111INLINE static void
112get_operands (struct simops *s, uint32 ins)
113{
114 int i, shift, bits, flags;
115 uint32 mask;
116 for (i=0; i < s->numops; i++)
117 {
118 shift = s->operands[3*i];
119 bits = s->operands[3*i+1];
120 flags = s->operands[3*i+2];
121 mask = 0x7FFFFFFF >> (31 - bits);
122 OP[i] = (ins >> shift) & mask;
123 }
124 /* FIXME: for tracing, update values that need to be updated each
125 instruction decode cycle */
126 State.trace.psw = PSW;
127}
128
129bfd_vma
130decode_pc ()
131{
132 asection *s;
133 if (!init_text_p && prog_bfd != NULL)
134 {
135 init_text_p = 1;
136 for (s = prog_bfd->sections; s; s = s->next)
137 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
138 {
139 text = s;
140 text_start = bfd_get_section_vma (prog_bfd, s);
141 text_end = text_start + bfd_section_size (prog_bfd, s);
142 break;
143 }
144 }
145
146 return (PC << 2) + text_start;
147}
148
149static void
150do_long (ins)
151 uint32 ins;
152{
153 struct hash_entry *h;
154#ifdef DEBUG
155 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
156 (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
157#endif
158 h = lookup_hash (ins, 1);
4ce44c66
JM
159 if (h == NULL)
160 return;
c906108c
SS
161 get_operands (h->ops, ins);
162 State.ins_type = INS_LONG;
163 ins_type_counters[ (int)State.ins_type ]++;
164 (h->ops->func)();
165}
166
167static void
168do_2_short (ins1, ins2, leftright)
169 uint16 ins1, ins2;
170 enum _leftright leftright;
171{
172 struct hash_entry *h;
173 enum _ins_type first, second;
174
175#ifdef DEBUG
176 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
177 (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
178 ins1, (leftright) ? "left" : "right", ins2);
179#endif
180
181 if (leftright == LEFT_FIRST)
182 {
183 first = INS_LEFT;
184 second = INS_RIGHT;
185 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
186 }
187 else
188 {
189 first = INS_RIGHT;
190 second = INS_LEFT;
191 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
192 }
193
194 /* Issue the first instruction */
195 h = lookup_hash (ins1, 0);
4ce44c66
JM
196 if (h == NULL)
197 return;
c906108c
SS
198 get_operands (h->ops, ins1);
199 State.ins_type = first;
200 ins_type_counters[ (int)State.ins_type ]++;
201 (h->ops->func)();
202
203 /* Issue the second instruction (if the PC hasn't changed) */
204 if (!State.pc_changed && !State.exception)
205 {
206 /* finish any existing instructions */
207 SLOT_FLUSH ();
208 h = lookup_hash (ins2, 0);
4ce44c66
JM
209 if (h == NULL)
210 return;
c906108c
SS
211 get_operands (h->ops, ins2);
212 State.ins_type = second;
213 ins_type_counters[ (int)State.ins_type ]++;
214 ins_type_counters[ (int)INS_CYCLES ]++;
215 (h->ops->func)();
216 }
217 else if (!State.exception)
218 ins_type_counters[ (int)INS_COND_JUMP ]++;
219}
220
221static void
222do_parallel (ins1, ins2)
223 uint16 ins1, ins2;
224{
225 struct hash_entry *h1, *h2;
226#ifdef DEBUG
227 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
228 (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
229#endif
230 ins_type_counters[ (int)INS_PARALLEL ]++;
231 h1 = lookup_hash (ins1, 0);
4ce44c66
JM
232 if (h1 == NULL)
233 return;
c906108c 234 h2 = lookup_hash (ins2, 0);
4ce44c66
JM
235 if (h2 == NULL)
236 return;
c906108c
SS
237
238 if (h1->ops->exec_type == PARONLY)
239 {
240 get_operands (h1->ops, ins1);
241 State.ins_type = INS_LEFT_COND_TEST;
242 ins_type_counters[ (int)State.ins_type ]++;
243 (h1->ops->func)();
244 if (State.exe)
245 {
246 ins_type_counters[ (int)INS_COND_TRUE ]++;
247 get_operands (h2->ops, ins2);
248 State.ins_type = INS_RIGHT_COND_EXE;
249 ins_type_counters[ (int)State.ins_type ]++;
250 (h2->ops->func)();
251 }
252 else
253 ins_type_counters[ (int)INS_COND_FALSE ]++;
254 }
255 else if (h2->ops->exec_type == PARONLY)
256 {
257 get_operands (h2->ops, ins2);
258 State.ins_type = INS_RIGHT_COND_TEST;
259 ins_type_counters[ (int)State.ins_type ]++;
260 (h2->ops->func)();
261 if (State.exe)
262 {
263 ins_type_counters[ (int)INS_COND_TRUE ]++;
264 get_operands (h1->ops, ins1);
265 State.ins_type = INS_LEFT_COND_EXE;
266 ins_type_counters[ (int)State.ins_type ]++;
267 (h1->ops->func)();
268 }
269 else
270 ins_type_counters[ (int)INS_COND_FALSE ]++;
271 }
272 else
273 {
274 get_operands (h1->ops, ins1);
275 State.ins_type = INS_LEFT_PARALLEL;
276 ins_type_counters[ (int)State.ins_type ]++;
277 (h1->ops->func)();
278 if (!State.exception)
279 {
280 get_operands (h2->ops, ins2);
281 State.ins_type = INS_RIGHT_PARALLEL;
282 ins_type_counters[ (int)State.ins_type ]++;
283 (h2->ops->func)();
284 }
285 }
286}
287
288static char *
289add_commas(buf, sizeof_buf, value)
290 char *buf;
291 int sizeof_buf;
292 unsigned long value;
293{
294 int comma = 3;
295 char *endbuf = buf + sizeof_buf - 1;
296
297 *--endbuf = '\0';
298 do {
299 if (comma-- == 0)
300 {
301 *--endbuf = ',';
302 comma = 2;
303 }
304
305 *--endbuf = (value % 10) + '0';
306 } while ((value /= 10) != 0);
307
308 return endbuf;
309}
310
311void
312sim_size (power)
313 int power;
314
315{
316 int i;
4ce44c66 317 for (i = 0; i < IMEM_SEGMENTS; i++)
c906108c 318 {
4ce44c66
JM
319 if (State.mem.insn[i])
320 free (State.mem.insn[i]);
c906108c 321 }
4ce44c66 322 for (i = 0; i < DMEM_SEGMENTS; i++)
c906108c 323 {
4ce44c66
JM
324 if (State.mem.data[i])
325 free (State.mem.data[i]);
c906108c 326 }
4ce44c66
JM
327 for (i = 0; i < UMEM_SEGMENTS; i++)
328 {
329 if (State.mem.unif[i])
330 free (State.mem.unif[i]);
331 }
332 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
333 registers. */
334 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
335}
336
337/* For tracing - leave info on last access around. */
338static char *last_segname = "invalid";
339static char *last_from = "invalid";
340static char *last_to = "invalid";
341
342enum
343 {
344 IMAP0_OFFSET = 0xff00,
345 DMAP0_OFFSET = 0xff08,
346 DMAP2_SHADDOW = 0xff04,
347 DMAP2_OFFSET = 0xff0c
348 };
349
350static void
351set_dmap_register (int reg_nr, unsigned long value)
352{
353 uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
354 + DMAP0_OFFSET + 2 * reg_nr);
355 WRITE_16 (raw, value);
c906108c 356#ifdef DEBUG
4ce44c66 357 if ((d10v_debug & DEBUG_MEMORY))
c906108c 358 {
4ce44c66
JM
359 (*d10v_callback->printf_filtered)
360 (d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
361 }
362#endif
363}
c906108c 364
4ce44c66
JM
365static unsigned long
366dmap_register (int reg_nr)
367{
368 uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
369 + DMAP0_OFFSET + 2 * reg_nr);
370 return READ_16 (raw);
371}
372
373static void
374set_imap_register (int reg_nr, unsigned long value)
375{
376 uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
377 + IMAP0_OFFSET + 2 * reg_nr);
378 WRITE_16 (raw, value);
379#ifdef DEBUG
380 if ((d10v_debug & DEBUG_MEMORY))
381 {
382 (*d10v_callback->printf_filtered)
383 (d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
c906108c
SS
384 }
385#endif
386}
387
4ce44c66
JM
388static unsigned long
389imap_register (int reg_nr)
390{
391 uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
392 + IMAP0_OFFSET + 2 * reg_nr);
393 return READ_16 (raw);
394}
c906108c 395
4ce44c66
JM
396enum
397 {
398 HELD_SPI_IDX = 0,
399 HELD_SPU_IDX = 1
400 };
401
402static unsigned long
403spu_register (void)
c906108c 404{
4ce44c66
JM
405 if (PSW_SM)
406 return GPR (SP_IDX);
407 else
408 return HELD_SP (HELD_SPU_IDX);
409}
c906108c 410
4ce44c66
JM
411static unsigned long
412spi_register (void)
413{
414 if (!PSW_SM)
415 return GPR (SP_IDX);
416 else
417 return HELD_SP (HELD_SPI_IDX);
418}
419
420static void
421set_spi_register (unsigned long value)
422{
423 if (!PSW_SM)
424 SET_GPR (SP_IDX, value);
425 SET_HELD_SP (HELD_SPI_IDX, value);
426}
427
428static void
429set_spu_register (unsigned long value)
430{
431 if (PSW_SM)
432 SET_GPR (SP_IDX, value);
433 SET_HELD_SP (HELD_SPU_IDX, value);
434}
435
436/* Given a virtual address in the DMAP address space, translate it
437 into a physical address. */
438
439unsigned long
440sim_d10v_translate_dmap_addr (unsigned long offset,
441 int nr_bytes,
442 unsigned long *phys,
443 unsigned long (*dmap_register) (int reg_nr))
444{
445 short map;
446 int regno;
447 last_from = "logical-data";
448 if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)
c906108c 449 {
4ce44c66
JM
450 /* Logical address out side of data segments, not supported */
451 return 0;
452 }
453 regno = (offset / DMAP_BLOCK_SIZE);
454 offset = (offset % DMAP_BLOCK_SIZE);
455 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
456 {
457 /* Don't cross a BLOCK boundary */
458 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
459 }
460 map = dmap_register (regno);
461 if (regno == 3)
462 {
463 /* Always maps to data memory */
464 int iospi = (offset / 0x1000) % 4;
465 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
466 last_to = "io-space";
467 *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
468 }
469 else
470 {
471 int sp = ((map & 0x3000) >> 12);
472 int segno = (map & 0x3ff);
473 switch (sp)
c906108c 474 {
4ce44c66
JM
475 case 0: /* 00: Unified memory */
476 *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
477 last_to = "unified";
478 break;
479 case 1: /* 01: Instruction Memory */
480 *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
481 last_to = "chip-insn";
482 break;
483 case 2: /* 10: Internal data memory */
484 *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
485 last_to = "chip-data";
486 break;
487 case 3: /* 11: Reserved */
488 return 0;
c906108c
SS
489 }
490 }
4ce44c66
JM
491 return nr_bytes;
492}
c906108c 493
4ce44c66
JM
494/* Given a virtual address in the IMAP address space, translate it
495 into a physical address. */
cff3e48b 496
4ce44c66
JM
497unsigned long
498sim_d10v_translate_imap_addr (unsigned long offset,
499 int nr_bytes,
500 unsigned long *phys,
501 unsigned long (*imap_register) (int reg_nr))
502{
503 short map;
504 int regno;
505 int sp;
506 int segno;
507 last_from = "logical-insn";
508 if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
509 {
510 /* Logical address outside of IMAP segments, not supported */
511 return 0;
512 }
513 regno = (offset / IMAP_BLOCK_SIZE);
514 offset = (offset % IMAP_BLOCK_SIZE);
515 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
516 {
517 /* Don't cross a BLOCK boundary */
518 nr_bytes = IMAP_BLOCK_SIZE - offset;
519 }
520 map = imap_register (regno);
521 sp = (map & 0x3000) >> 12;
522 segno = (map & 0x007f);
523 switch (sp)
524 {
525 case 0: /* 00: unified memory */
526 *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
527 last_to = "unified";
528 break;
529 case 1: /* 01: instruction memory */
530 *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
531 last_to = "chip-insn";
532 break;
533 case 2: /*10*/
534 /* Reserved. */
535 return 0;
536 case 3: /* 11: for testing - instruction memory */
537 offset = (offset % 0x800);
538 *phys = SIM_D10V_MEMORY_INSN + offset;
539 if (offset + nr_bytes > 0x800)
540 /* don't cross VM boundary */
541 nr_bytes = 0x800 - offset;
542 last_to = "test-insn";
543 break;
544 }
545 return nr_bytes;
546}
cff3e48b 547
4ce44c66
JM
548unsigned long
549sim_d10v_translate_addr (unsigned long memaddr,
550 int nr_bytes,
551 unsigned long *targ_addr,
552 unsigned long (*dmap_register) (int reg_nr),
553 unsigned long (*imap_register) (int reg_nr))
554{
555 unsigned long phys;
556 unsigned long seg;
557 unsigned long off;
cff3e48b 558
4ce44c66
JM
559 last_from = "unknown";
560 last_to = "unknown";
cff3e48b 561
4ce44c66
JM
562 seg = (memaddr >> 24);
563 off = (memaddr & 0xffffffL);
c906108c 564
cff3e48b
JM
565 /* However, if we've asked to use the previous generation of segment
566 mapping, rearrange the segments as follows. */
567
568 if (old_segment_mapping)
569 {
4ce44c66 570 switch (seg)
cff3e48b
JM
571 {
572 case 0x00: /* DMAP translated memory */
4ce44c66 573 seg = 0x10;
cff3e48b
JM
574 break;
575 case 0x01: /* IMAP translated memory */
4ce44c66 576 seg = 0x11;
cff3e48b
JM
577 break;
578 case 0x10: /* On-chip data memory */
4ce44c66 579 seg = 0x02;
cff3e48b
JM
580 break;
581 case 0x11: /* On-chip insn memory */
4ce44c66 582 seg = 0x01;
cff3e48b
JM
583 break;
584 case 0x12: /* Unified memory */
4ce44c66 585 seg = 0x00;
cff3e48b
JM
586 break;
587 }
588 }
589
4ce44c66 590 switch (seg)
c906108c 591 {
4ce44c66
JM
592 case 0x00: /* Physical unified memory */
593 last_from = "phys-unified";
594 last_to = "unified";
595 phys = SIM_D10V_MEMORY_UNIFIED + off;
596 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
597 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
598 break;
c906108c 599
4ce44c66
JM
600 case 0x01: /* Physical instruction memory */
601 last_from = "phys-insn";
602 last_to = "chip-insn";
603 phys = SIM_D10V_MEMORY_INSN + off;
604 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
605 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
606 break;
c906108c 607
4ce44c66
JM
608 case 0x02: /* Physical data memory segment */
609 last_from = "phys-data";
610 last_to = "chip-data";
611 phys = SIM_D10V_MEMORY_DATA + off;
612 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
613 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
614 break;
615
616 case 0x10: /* in logical data address segment */
617 nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys,
618 dmap_register);
619 break;
620
621 case 0x11: /* in logical instruction address segment */
622 nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys,
623 imap_register);
624 break;
625
626 default:
627 return 0;
628 }
629
630 *targ_addr = phys;
631 return nr_bytes;
632}
633
634/* Return a pointer into the raw buffer designated by phys_addr. It
635 is assumed that the client has already ensured that the access
636 isn't going to cross a segment boundary. */
637
638uint8 *
639map_memory (unsigned phys_addr)
640{
641 uint8 **memory;
642 uint8 *raw;
643 unsigned offset;
644 int segment = ((phys_addr >> 24) & 0xff);
645
646 switch (segment)
647 {
648
649 case 0x00: /* Unified memory */
c906108c 650 {
4ce44c66
JM
651 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
652 last_segname = "umem";
c906108c
SS
653 break;
654 }
4ce44c66 655
cff3e48b 656 case 0x01: /* On-chip insn memory */
c906108c 657 {
4ce44c66
JM
658 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
659 last_segname = "imem";
c906108c
SS
660 break;
661 }
4ce44c66
JM
662
663 case 0x02: /* On-chip data memory */
c906108c 664 {
4ce44c66 665 if ((phys_addr & 0xff00) == 0xff00)
c906108c 666 {
4ce44c66
JM
667 phys_addr = (phys_addr & 0xffff);
668 if (phys_addr == DMAP2_SHADDOW)
c906108c 669 {
4ce44c66
JM
670 phys_addr = DMAP2_OFFSET;
671 last_segname = "dmap";
c906108c 672 }
4ce44c66
JM
673 else
674 last_segname = "reg";
c906108c 675 }
4ce44c66
JM
676 else
677 last_segname = "dmem";
678 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
c906108c
SS
679 break;
680 }
4ce44c66 681
c906108c 682 default:
4ce44c66
JM
683 /* OOPS! */
684 last_segname = "scrap";
685 return State.mem.fault;
c906108c 686 }
4ce44c66
JM
687
688 if (*memory == NULL)
c906108c 689 {
4ce44c66
JM
690 *memory = calloc (1, SEGMENT_SIZE);
691 if (*memory == NULL)
692 {
693 (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");
694 return State.mem.fault;
695 }
c906108c 696 }
4ce44c66
JM
697
698 offset = (phys_addr % SEGMENT_SIZE);
699 raw = *memory + offset;
700 return raw;
701}
702
703/* Transfer data to/from simulated memory. Since a bug in either the
704 simulated program or in gdb or the simulator itself may cause a
705 bogus address to be passed in, we need to do some sanity checking
706 on addresses to make sure they are within bounds. When an address
707 fails the bounds check, treat it as a zero length read/write rather
708 than aborting the entire run. */
709
710static int
711xfer_mem (SIM_ADDR virt,
712 unsigned char *buffer,
713 int size,
714 int write_p)
715{
716 int xfered = 0;
717
718 while (xfered < size)
c906108c 719 {
4ce44c66
JM
720 uint8 *memory;
721 unsigned long phys;
722 int phys_size;
723 phys_size = sim_d10v_translate_addr (virt, size,
724 &phys,
725 dmap_register,
726 imap_register);
727 if (phys_size == 0)
728 return xfered;
729
730 memory = map_memory (phys);
731
732#ifdef DEBUG
733 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
734 {
735 (*d10v_callback->printf_filtered)
736 (d10v_callback,
737 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
738 (write_p ? "write" : "read"),
739 phys_size, virt, last_from,
740 phys, last_to,
741 (long) memory, last_segname);
742 }
743#endif
744
745 if (write_p)
746 {
747 memcpy (memory, buffer, phys_size);
748 }
749 else
750 {
751 memcpy (buffer, memory, phys_size);
752 }
753
754 virt += phys_size;
755 buffer += phys_size;
756 xfered += phys_size;
c906108c
SS
757 }
758
759 return size;
760}
761
762
763int
764sim_write (sd, addr, buffer, size)
765 SIM_DESC sd;
766 SIM_ADDR addr;
767 unsigned char *buffer;
768 int size;
769{
770 /* FIXME: this should be performing a virtual transfer */
771 return xfer_mem( addr, buffer, size, 1);
772}
773
774int
775sim_read (sd, addr, buffer, size)
776 SIM_DESC sd;
777 SIM_ADDR addr;
778 unsigned char *buffer;
779 int size;
780{
781 /* FIXME: this should be performing a virtual transfer */
782 return xfer_mem( addr, buffer, size, 0);
783}
784
785
786SIM_DESC
787sim_open (kind, callback, abfd, argv)
788 SIM_OPEN_KIND kind;
789 host_callback *callback;
790 struct _bfd *abfd;
791 char **argv;
792{
793 struct simops *s;
794 struct hash_entry *h;
795 static int init_p = 0;
796 char **p;
797
798 sim_kind = kind;
799 d10v_callback = callback;
800 myname = argv[0];
cff3e48b 801 old_segment_mapping = 0;
c906108c 802
4ce44c66
JM
803 /* NOTE: This argument parsing is only effective when this function
804 is called by GDB. Standalone argument parsing is handled by
805 sim/common/run.c. */
c906108c
SS
806 for (p = argv + 1; *p; ++p)
807 {
cff3e48b
JM
808 if (strcmp (*p, "-oldseg") == 0)
809 old_segment_mapping = 1;
c906108c 810#ifdef DEBUG
cff3e48b 811 else if (strcmp (*p, "-t") == 0)
c906108c 812 d10v_debug = DEBUG;
4ce44c66
JM
813 else if (strncmp (*p, "-t", 2) == 0)
814 d10v_debug = atoi (*p + 2);
c906108c 815#endif
cff3e48b 816 else
c906108c
SS
817 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
818 }
819
820 /* put all the opcodes in the hash table */
821 if (!init_p++)
822 {
823 for (s = Simops; s->func; s++)
824 {
825 h = &hash_table[hash(s->opcode,s->format)];
826
827 /* go to the last entry in the chain */
828 while (h->next)
829 h = h->next;
830
831 if (h->ops)
832 {
833 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
834 if (!h->next)
835 perror ("malloc failure");
836
837 h = h->next;
838 }
839 h->ops = s;
840 h->mask = s->mask;
841 h->opcode = s->opcode;
842 h->size = s->is_long;
843 }
844 }
845
846 /* reset the processor state */
4ce44c66
JM
847 if (!State.mem.data[0])
848 sim_size (1);
c906108c
SS
849 sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
850
851 /* Fudge our descriptor. */
852 return (SIM_DESC) 1;
853}
854
855
856void
857sim_close (sd, quitting)
858 SIM_DESC sd;
859 int quitting;
860{
861 if (prog_bfd != NULL && prog_bfd_was_opened_p)
862 {
863 bfd_close (prog_bfd);
864 prog_bfd = NULL;
865 prog_bfd_was_opened_p = 0;
866 }
867}
868
869void
870sim_set_profile (n)
871 int n;
872{
873 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
874}
875
876void
877sim_set_profile_size (n)
878 int n;
879{
880 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
881}
882
c906108c 883uint8 *
4ce44c66 884dmem_addr (uint16 offset)
c906108c 885{
4ce44c66
JM
886 unsigned long phys;
887 uint8 *mem;
888 int phys_size;
c906108c 889
4ce44c66
JM
890 /* Note: DMEM address range is 0..0x10000. Calling code can compute
891 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
892 is uint16 this is modulo'ed onto 0x0e5d. */
c906108c 893
4ce44c66
JM
894 phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys,
895 dmap_register);
896 if (phys_size == 0)
c906108c 897 {
4ce44c66 898 mem = State.mem.fault;
c906108c 899 }
4ce44c66
JM
900 else
901 mem = map_memory (phys);
c906108c 902#ifdef DEBUG
4ce44c66
JM
903 if ((d10v_debug & DEBUG_MEMORY))
904 {
905 (*d10v_callback->printf_filtered)
906 (d10v_callback,
907 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
908 offset, last_from,
909 phys, phys_size, last_to,
910 (long) mem, last_segname);
c906108c 911 }
4ce44c66
JM
912#endif
913 return mem;
c906108c
SS
914}
915
c906108c 916uint8 *
4ce44c66 917imem_addr (uint32 offset)
c906108c 918{
4ce44c66
JM
919 unsigned long phys;
920 uint8 *mem;
921 int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, imap_register);
922 if (phys_size == 0)
923 {
924 return State.mem.fault;
925 }
926 mem = map_memory (phys);
927#ifdef DEBUG
928 if ((d10v_debug & DEBUG_MEMORY))
929 {
930 (*d10v_callback->printf_filtered)
931 (d10v_callback,
932 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
933 offset, last_from,
934 phys, phys_size, last_to,
935 (long) mem, last_segname);
936 }
937#endif
938 return mem;
c906108c
SS
939}
940
c906108c
SS
941static int stop_simulator = 0;
942
943int
944sim_stop (sd)
945 SIM_DESC sd;
946{
947 stop_simulator = 1;
948 return 1;
949}
950
951
952/* Run (or resume) the program. */
953void
954sim_resume (sd, step, siggnal)
955 SIM_DESC sd;
956 int step, siggnal;
957{
958 uint32 inst;
959 uint8 *iaddr;
960
961/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
962 State.exception = 0;
963 if (step)
964 sim_stop (sd);
965
7fc5b5ad
AC
966 switch (siggnal)
967 {
968 case 0:
969 break;
970#ifdef SIGBUS
971 case SIGBUS:
972#endif
973 case SIGSEGV:
974 SET_BPC (PC);
975 SET_BPSW (PSW);
976 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
977 JMP (AE_VECTOR_START);
978 SLOT_FLUSH ();
979 break;
27842f65
AC
980 case SIGILL:
981 SET_BPC (PC);
982 SET_BPSW (PSW);
983 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
984 JMP (RIE_VECTOR_START);
985 SLOT_FLUSH ();
986 break;
7fc5b5ad
AC
987 default:
988 /* just ignore it */
989 break;
990 }
991
c906108c
SS
992 do
993 {
994 iaddr = imem_addr ((uint32)PC << 2);
4ce44c66 995 if (iaddr == State.mem.fault)
c906108c
SS
996 {
997 State.exception = SIGBUS;
998 break;
999 }
1000
1001 inst = get_longword( iaddr );
1002
1003 State.pc_changed = 0;
1004 ins_type_counters[ (int)INS_CYCLES ]++;
1005
1006 switch (inst & 0xC0000000)
1007 {
1008 case 0xC0000000:
1009 /* long instruction */
1010 do_long (inst & 0x3FFFFFFF);
1011 break;
1012 case 0x80000000:
1013 /* R -> L */
1014 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
1015 break;
1016 case 0x40000000:
1017 /* L -> R */
1018 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
1019 break;
1020 case 0:
1021 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
1022 break;
1023 }
1024
1025 /* If the PC of the current instruction matches RPT_E then
1026 schedule a branch to the loop start. If one of those
1027 instructions happens to be a branch, than that instruction
1028 will be ignored */
1029 if (!State.pc_changed)
1030 {
1031 if (PSW_RP && PC == RPT_E)
1032 {
1033 /* Note: The behavour of a branch instruction at RPT_E
1034 is implementation dependant, this simulator takes the
1035 branch. Branching to RPT_E is valid, the instruction
1036 must be executed before the loop is taken. */
1037 if (RPT_C == 1)
1038 {
1039 SET_PSW_RP (0);
1040 SET_RPT_C (0);
1041 SET_PC (PC + 1);
1042 }
1043 else
1044 {
1045 SET_RPT_C (RPT_C - 1);
1046 SET_PC (RPT_S);
1047 }
1048 }
1049 else
1050 SET_PC (PC + 1);
1051 }
1052
1053 /* Check for a breakpoint trap on this instruction. This
1054 overrides any pending branches or loops */
1055 if (PSW_DB && PC == IBA)
1056 {
1057 SET_BPC (PC);
1058 SET_BPSW (PSW);
1059 SET_PSW (PSW & PSW_SM_BIT);
1060 SET_PC (SDBT_VECTOR_START);
1061 }
1062
1063 /* Writeback all the DATA / PC changes */
1064 SLOT_FLUSH ();
1065
7a292a7a
SS
1066#ifdef NEED_UI_LOOP_HOOK
1067 if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
1068 {
1069 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1070 ui_loop_hook (0);
1071 }
1072#endif /* NEED_UI_LOOP_HOOK */
c906108c
SS
1073 }
1074 while ( !State.exception && !stop_simulator);
1075
1076 if (step && !State.exception)
1077 State.exception = SIGTRAP;
1078}
1079
baa7ae6f
AC
1080void
1081sim_set_trace (void)
c906108c
SS
1082{
1083#ifdef DEBUG
1084 d10v_debug = DEBUG;
1085#endif
c906108c
SS
1086}
1087
1088void
1089sim_info (sd, verbose)
1090 SIM_DESC sd;
1091 int verbose;
1092{
1093 char buf1[40];
1094 char buf2[40];
1095 char buf3[40];
1096 char buf4[40];
1097 char buf5[40];
1098 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1099 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1100 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1101 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1102 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1103
1104 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1105 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1106 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1107 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1108 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1109
1110 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1111 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1112 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1113 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1114 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1115 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1116 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1117 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1118 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1119 unsigned long total = (unknown + left_total + right_total + ins_long);
1120
1121 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1122 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1123 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1124 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1125 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1126 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1127
1128 (*d10v_callback->printf_filtered) (d10v_callback,
1129 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1130 size, add_commas (buf1, sizeof (buf1), left_total),
1131 normal_size, add_commas (buf2, sizeof (buf2), left),
1132 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1133 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1134 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1135
1136 (*d10v_callback->printf_filtered) (d10v_callback,
1137 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1138 size, add_commas (buf1, sizeof (buf1), right_total),
1139 normal_size, add_commas (buf2, sizeof (buf2), right),
1140 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1141 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1142 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1143
1144 if (ins_long)
1145 (*d10v_callback->printf_filtered) (d10v_callback,
1146 "executed %*s long instruction(s)\n",
1147 size, add_commas (buf1, sizeof (buf1), ins_long));
1148
1149 if (parallel)
1150 (*d10v_callback->printf_filtered) (d10v_callback,
1151 "executed %*s parallel instruction(s)\n",
1152 size, add_commas (buf1, sizeof (buf1), parallel));
1153
1154 if (leftright)
1155 (*d10v_callback->printf_filtered) (d10v_callback,
1156 "executed %*s instruction(s) encoded L->R\n",
1157 size, add_commas (buf1, sizeof (buf1), leftright));
1158
1159 if (rightleft)
1160 (*d10v_callback->printf_filtered) (d10v_callback,
1161 "executed %*s instruction(s) encoded R->L\n",
1162 size, add_commas (buf1, sizeof (buf1), rightleft));
1163
1164 if (unknown)
1165 (*d10v_callback->printf_filtered) (d10v_callback,
1166 "executed %*s unknown instruction(s)\n",
1167 size, add_commas (buf1, sizeof (buf1), unknown));
1168
1169 if (cond_true)
1170 (*d10v_callback->printf_filtered) (d10v_callback,
1171 "executed %*s instruction(s) due to EXExxx condition being true\n",
1172 size, add_commas (buf1, sizeof (buf1), cond_true));
1173
1174 if (cond_false)
1175 (*d10v_callback->printf_filtered) (d10v_callback,
1176 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1177 size, add_commas (buf1, sizeof (buf1), cond_false));
1178
1179 if (cond_jump)
1180 (*d10v_callback->printf_filtered) (d10v_callback,
1181 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1182 size, add_commas (buf1, sizeof (buf1), cond_jump));
1183
1184 (*d10v_callback->printf_filtered) (d10v_callback,
1185 "executed %*s cycle(s)\n",
1186 size, add_commas (buf1, sizeof (buf1), cycles));
1187
1188 (*d10v_callback->printf_filtered) (d10v_callback,
1189 "executed %*s total instructions\n",
1190 size, add_commas (buf1, sizeof (buf1), total));
1191}
1192
1193SIM_RC
1194sim_create_inferior (sd, abfd, argv, env)
1195 SIM_DESC sd;
1196 struct _bfd *abfd;
1197 char **argv;
1198 char **env;
1199{
1200 bfd_vma start_address;
1201
1202 /* reset all state information */
4ce44c66 1203 memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
c906108c 1204
c906108c
SS
1205 /* set PC */
1206 if (abfd != NULL)
1207 start_address = bfd_get_start_address (abfd);
1208 else
1209 start_address = 0xffc0 << 2;
1210#ifdef DEBUG
1211 if (d10v_debug)
1212 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1213#endif
1214 SET_CREG (PC_CR, start_address >> 2);
1215
4ce44c66
JM
1216 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1217 initializes imap0 and imap1 to 0x1000 as part of its ROM
1218 initialization. */
cff3e48b 1219 if (old_segment_mapping)
c906108c 1220 {
4ce44c66
JM
1221 /* External memory startup. This is the HARD reset state. */
1222 set_imap_register (0, 0x0000);
1223 set_imap_register (1, 0x007f);
1224 set_dmap_register (0, 0x2000);
1225 set_dmap_register (1, 0x2000);
1226 set_dmap_register (2, 0x0000); /* Old DMAP */
1227 set_dmap_register (3, 0x0000);
c906108c
SS
1228 }
1229 else
1230 {
4ce44c66
JM
1231 /* Internal memory startup. This is the ROM intialized state. */
1232 set_imap_register (0, 0x1000);
1233 set_imap_register (1, 0x1000);
1234 set_dmap_register (0, 0x2000);
1235 set_dmap_register (1, 0x2000);
ba744a4f
AC
1236 set_dmap_register (2, 0x2000); /* DMAP2 initial internal value is
1237 0x2000 on the new board. */
4ce44c66 1238 set_dmap_register (3, 0x0000);
c906108c
SS
1239 }
1240
1241 SLOT_FLUSH ();
1242 return SIM_RC_OK;
1243}
1244
1245
1246void
1247sim_set_callbacks (p)
1248 host_callback *p;
1249{
1250 d10v_callback = p;
1251}
1252
1253void
1254sim_stop_reason (sd, reason, sigrc)
1255 SIM_DESC sd;
1256 enum sim_stop *reason;
1257 int *sigrc;
1258{
1259/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1260
1261 switch (State.exception)
1262 {
1263 case SIG_D10V_STOP: /* stop instruction */
1264 *reason = sim_exited;
1265 *sigrc = 0;
1266 break;
1267
1268 case SIG_D10V_EXIT: /* exit trap */
1269 *reason = sim_exited;
1270 *sigrc = GPR (0);
1271 break;
1272
7fc5b5ad
AC
1273 case SIG_D10V_BUS:
1274 *reason = sim_stopped;
1275#ifdef SIGBUS
1276 *sigrc = SIGBUS;
1277#else
1278 *sigrc = SIGSEGV;
1279#endif
1280 break;
1281
c906108c
SS
1282 default: /* some signal */
1283 *reason = sim_stopped;
1284 if (stop_simulator && !State.exception)
1285 *sigrc = SIGINT;
1286 else
1287 *sigrc = State.exception;
1288 break;
1289 }
1290
1291 stop_simulator = 0;
1292}
1293
1294int
1295sim_fetch_register (sd, rn, memory, length)
1296 SIM_DESC sd;
1297 int rn;
1298 unsigned char *memory;
1299 int length;
1300{
4ce44c66
JM
1301 int size;
1302 if (rn < 0)
1303 size = 0;
1304 else if (rn >= SIM_D10V_R0_REGNUM
1305 && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1306 {
1307 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1308 size = 2;
1309 }
1310 else if (rn >= SIM_D10V_CR0_REGNUM
1311 && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1312 {
1313 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1314 size = 2;
1315 }
1316 else if (rn >= SIM_D10V_A0_REGNUM
1317 && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1318 {
1319 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1320 size = 8;
1321 }
1322 else if (rn == SIM_D10V_SPI_REGNUM)
1323 {
1324 /* PSW_SM indicates that the current SP is the USER
1325 stack-pointer. */
1326 WRITE_16 (memory, spi_register ());
1327 size = 2;
1328 }
1329 else if (rn == SIM_D10V_SPU_REGNUM)
1330 {
1331 /* PSW_SM indicates that the current SP is the USER
1332 stack-pointer. */
1333 WRITE_16 (memory, spu_register ());
1334 size = 2;
1335 }
1336 else if (rn >= SIM_D10V_IMAP0_REGNUM
1337 && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1338 {
1339 WRITE_16 (memory, imap_register (rn - SIM_D10V_IMAP0_REGNUM));
1340 size = 2;
1341 }
1342 else if (rn >= SIM_D10V_DMAP0_REGNUM
1343 && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1344 {
1345 WRITE_16 (memory, dmap_register (rn - SIM_D10V_DMAP0_REGNUM));
1346 size = 2;
1347 }
c906108c 1348 else
4ce44c66
JM
1349 size = 0;
1350 return size;
c906108c
SS
1351}
1352
1353int
1354sim_store_register (sd, rn, memory, length)
1355 SIM_DESC sd;
1356 int rn;
1357 unsigned char *memory;
1358 int length;
1359{
4ce44c66
JM
1360 int size;
1361 if (rn < 0)
1362 size = 0;
1363 else if (rn >= SIM_D10V_R0_REGNUM
1364 && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1365 {
1366 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1367 size = 2;
1368 }
1369 else if (rn >= SIM_D10V_CR0_REGNUM
1370 && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1371 {
1372 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1373 size = 2;
1374 }
1375 else if (rn >= SIM_D10V_A0_REGNUM
1376 && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1377 {
1378 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1379 size = 8;
1380 }
1381 else if (rn == SIM_D10V_SPI_REGNUM)
1382 {
1383 /* PSW_SM indicates that the current SP is the USER
1384 stack-pointer. */
1385 set_spi_register (READ_16 (memory));
1386 size = 2;
1387 }
1388 else if (rn == SIM_D10V_SPU_REGNUM)
1389 {
1390 set_spu_register (READ_16 (memory));
1391 size = 2;
1392 }
1393 else if (rn >= SIM_D10V_IMAP0_REGNUM
1394 && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1395 {
1396 set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
1397 size = 2;
1398 }
1399 else if (rn >= SIM_D10V_DMAP0_REGNUM
1400 && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1401 {
1402 set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
1403 size = 2;
1404 }
c906108c 1405 else
4ce44c66 1406 size = 0;
c906108c 1407 SLOT_FLUSH ();
4ce44c66 1408 return size;
c906108c
SS
1409}
1410
1411
1412void
1413sim_do_command (sd, cmd)
1414 SIM_DESC sd;
1415 char *cmd;
1416{
1417 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
1418}
1419
1420SIM_RC
1421sim_load (sd, prog, abfd, from_tty)
1422 SIM_DESC sd;
1423 char *prog;
1424 bfd *abfd;
1425 int from_tty;
1426{
1427 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1428
1429 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1430 {
1431 bfd_close (prog_bfd);
1432 prog_bfd_was_opened_p = 0;
1433 }
1434 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
1435 sim_kind == SIM_OPEN_DEBUG,
1436 1/*LMA*/, sim_write);
1437 if (prog_bfd == NULL)
1438 return SIM_RC_FAIL;
1439 prog_bfd_was_opened_p = abfd == NULL;
1440 return SIM_RC_OK;
1441}