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