]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/d10v/interp.c
2000-02-22 H.J. Lu <hjl@gnu.org>
[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
7fc5b5ad
AC
968 switch (siggnal)
969 {
970 case 0:
971 break;
972#ifdef SIGBUS
973 case SIGBUS:
974#endif
975 case SIGSEGV:
976 SET_BPC (PC);
977 SET_BPSW (PSW);
978 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
979 JMP (AE_VECTOR_START);
980 SLOT_FLUSH ();
981 break;
982 default:
983 /* just ignore it */
984 break;
985 }
986
c906108c
SS
987 do
988 {
989 iaddr = imem_addr ((uint32)PC << 2);
4ce44c66 990 if (iaddr == State.mem.fault)
c906108c
SS
991 {
992 State.exception = SIGBUS;
993 break;
994 }
995
996 inst = get_longword( iaddr );
997
998 State.pc_changed = 0;
999 ins_type_counters[ (int)INS_CYCLES ]++;
1000
1001 switch (inst & 0xC0000000)
1002 {
1003 case 0xC0000000:
1004 /* long instruction */
1005 do_long (inst & 0x3FFFFFFF);
1006 break;
1007 case 0x80000000:
1008 /* R -> L */
1009 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
1010 break;
1011 case 0x40000000:
1012 /* L -> R */
1013 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
1014 break;
1015 case 0:
1016 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
1017 break;
1018 }
1019
1020 /* If the PC of the current instruction matches RPT_E then
1021 schedule a branch to the loop start. If one of those
1022 instructions happens to be a branch, than that instruction
1023 will be ignored */
1024 if (!State.pc_changed)
1025 {
1026 if (PSW_RP && PC == RPT_E)
1027 {
1028 /* Note: The behavour of a branch instruction at RPT_E
1029 is implementation dependant, this simulator takes the
1030 branch. Branching to RPT_E is valid, the instruction
1031 must be executed before the loop is taken. */
1032 if (RPT_C == 1)
1033 {
1034 SET_PSW_RP (0);
1035 SET_RPT_C (0);
1036 SET_PC (PC + 1);
1037 }
1038 else
1039 {
1040 SET_RPT_C (RPT_C - 1);
1041 SET_PC (RPT_S);
1042 }
1043 }
1044 else
1045 SET_PC (PC + 1);
1046 }
1047
1048 /* Check for a breakpoint trap on this instruction. This
1049 overrides any pending branches or loops */
1050 if (PSW_DB && PC == IBA)
1051 {
1052 SET_BPC (PC);
1053 SET_BPSW (PSW);
1054 SET_PSW (PSW & PSW_SM_BIT);
1055 SET_PC (SDBT_VECTOR_START);
1056 }
1057
1058 /* Writeback all the DATA / PC changes */
1059 SLOT_FLUSH ();
1060
7a292a7a
SS
1061#ifdef NEED_UI_LOOP_HOOK
1062 if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
1063 {
1064 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1065 ui_loop_hook (0);
1066 }
1067#endif /* NEED_UI_LOOP_HOOK */
c906108c
SS
1068 }
1069 while ( !State.exception && !stop_simulator);
1070
1071 if (step && !State.exception)
1072 State.exception = SIGTRAP;
1073}
1074
1075int
1076sim_trace (sd)
1077 SIM_DESC sd;
1078{
7fc5b5ad
AC
1079 enum sim_stop reason;
1080 static int sigrc = 0;
c906108c
SS
1081#ifdef DEBUG
1082 d10v_debug = DEBUG;
1083#endif
7fc5b5ad
AC
1084 /* NOTE: SIGRC starts with zero and is then, always the value
1085 returned by the last sim_stop_reason() call. */
1086 sim_resume (sd, 0, sigrc);
1087 sim_stop_reason (sd, &reason, &sigrc);
1088 return (reason != sim_stopped || sigrc != SIGINT);
c906108c
SS
1089}
1090
1091void
1092sim_info (sd, verbose)
1093 SIM_DESC sd;
1094 int verbose;
1095{
1096 char buf1[40];
1097 char buf2[40];
1098 char buf3[40];
1099 char buf4[40];
1100 char buf5[40];
1101 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1102 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1103 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1104 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1105 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1106
1107 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1108 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1109 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1110 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1111 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1112
1113 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1114 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1115 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1116 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1117 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1118 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1119 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1120 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1121 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1122 unsigned long total = (unknown + left_total + right_total + ins_long);
1123
1124 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1125 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1126 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1127 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1128 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1129 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1130
1131 (*d10v_callback->printf_filtered) (d10v_callback,
1132 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1133 size, add_commas (buf1, sizeof (buf1), left_total),
1134 normal_size, add_commas (buf2, sizeof (buf2), left),
1135 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1136 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1137 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1138
1139 (*d10v_callback->printf_filtered) (d10v_callback,
1140 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1141 size, add_commas (buf1, sizeof (buf1), right_total),
1142 normal_size, add_commas (buf2, sizeof (buf2), right),
1143 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1144 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1145 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1146
1147 if (ins_long)
1148 (*d10v_callback->printf_filtered) (d10v_callback,
1149 "executed %*s long instruction(s)\n",
1150 size, add_commas (buf1, sizeof (buf1), ins_long));
1151
1152 if (parallel)
1153 (*d10v_callback->printf_filtered) (d10v_callback,
1154 "executed %*s parallel instruction(s)\n",
1155 size, add_commas (buf1, sizeof (buf1), parallel));
1156
1157 if (leftright)
1158 (*d10v_callback->printf_filtered) (d10v_callback,
1159 "executed %*s instruction(s) encoded L->R\n",
1160 size, add_commas (buf1, sizeof (buf1), leftright));
1161
1162 if (rightleft)
1163 (*d10v_callback->printf_filtered) (d10v_callback,
1164 "executed %*s instruction(s) encoded R->L\n",
1165 size, add_commas (buf1, sizeof (buf1), rightleft));
1166
1167 if (unknown)
1168 (*d10v_callback->printf_filtered) (d10v_callback,
1169 "executed %*s unknown instruction(s)\n",
1170 size, add_commas (buf1, sizeof (buf1), unknown));
1171
1172 if (cond_true)
1173 (*d10v_callback->printf_filtered) (d10v_callback,
1174 "executed %*s instruction(s) due to EXExxx condition being true\n",
1175 size, add_commas (buf1, sizeof (buf1), cond_true));
1176
1177 if (cond_false)
1178 (*d10v_callback->printf_filtered) (d10v_callback,
1179 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1180 size, add_commas (buf1, sizeof (buf1), cond_false));
1181
1182 if (cond_jump)
1183 (*d10v_callback->printf_filtered) (d10v_callback,
1184 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1185 size, add_commas (buf1, sizeof (buf1), cond_jump));
1186
1187 (*d10v_callback->printf_filtered) (d10v_callback,
1188 "executed %*s cycle(s)\n",
1189 size, add_commas (buf1, sizeof (buf1), cycles));
1190
1191 (*d10v_callback->printf_filtered) (d10v_callback,
1192 "executed %*s total instructions\n",
1193 size, add_commas (buf1, sizeof (buf1), total));
1194}
1195
1196SIM_RC
1197sim_create_inferior (sd, abfd, argv, env)
1198 SIM_DESC sd;
1199 struct _bfd *abfd;
1200 char **argv;
1201 char **env;
1202{
1203 bfd_vma start_address;
1204
1205 /* reset all state information */
4ce44c66 1206 memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
c906108c
SS
1207
1208 if (argv)
1209 {
1210 /* a hack to set r0/r1 with argc/argv */
1211 /* some high memory that won't be overwritten by the stack soon */
1212 bfd_vma addr = 0x7C00;
1213 int p = 20;
1214 int i = 0;
1215 while (argv[i])
1216 {
1217 int size = strlen (argv[i]) + 1;
1218 SW (addr + 2*i, addr + p);
1219 sim_write (sd, addr + 0, argv[i], size);
1220 p += size;
1221 i++;
1222 }
1223 SET_GPR (0, addr);
1224 SET_GPR (1, i);
1225 }
1226
1227 /* set PC */
1228 if (abfd != NULL)
1229 start_address = bfd_get_start_address (abfd);
1230 else
1231 start_address = 0xffc0 << 2;
1232#ifdef DEBUG
1233 if (d10v_debug)
1234 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1235#endif
1236 SET_CREG (PC_CR, start_address >> 2);
1237
4ce44c66
JM
1238 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1239 initializes imap0 and imap1 to 0x1000 as part of its ROM
1240 initialization. */
cff3e48b 1241 if (old_segment_mapping)
c906108c 1242 {
4ce44c66
JM
1243 /* External memory startup. This is the HARD reset state. */
1244 set_imap_register (0, 0x0000);
1245 set_imap_register (1, 0x007f);
1246 set_dmap_register (0, 0x2000);
1247 set_dmap_register (1, 0x2000);
1248 set_dmap_register (2, 0x0000); /* Old DMAP */
1249 set_dmap_register (3, 0x0000);
c906108c
SS
1250 }
1251 else
1252 {
4ce44c66
JM
1253 /* Internal memory startup. This is the ROM intialized state. */
1254 set_imap_register (0, 0x1000);
1255 set_imap_register (1, 0x1000);
1256 set_dmap_register (0, 0x2000);
1257 set_dmap_register (1, 0x2000);
1258 set_dmap_register (2, 0x0000); /* Old DMAP, Value is not 0x2000 */
1259 set_dmap_register (3, 0x0000);
c906108c
SS
1260 }
1261
1262 SLOT_FLUSH ();
1263 return SIM_RC_OK;
1264}
1265
1266
1267void
1268sim_set_callbacks (p)
1269 host_callback *p;
1270{
1271 d10v_callback = p;
1272}
1273
1274void
1275sim_stop_reason (sd, reason, sigrc)
1276 SIM_DESC sd;
1277 enum sim_stop *reason;
1278 int *sigrc;
1279{
1280/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1281
1282 switch (State.exception)
1283 {
1284 case SIG_D10V_STOP: /* stop instruction */
1285 *reason = sim_exited;
1286 *sigrc = 0;
1287 break;
1288
1289 case SIG_D10V_EXIT: /* exit trap */
1290 *reason = sim_exited;
1291 *sigrc = GPR (0);
1292 break;
1293
7fc5b5ad
AC
1294 case SIG_D10V_BUS:
1295 *reason = sim_stopped;
1296#ifdef SIGBUS
1297 *sigrc = SIGBUS;
1298#else
1299 *sigrc = SIGSEGV;
1300#endif
1301 break;
1302
c906108c
SS
1303 default: /* some signal */
1304 *reason = sim_stopped;
1305 if (stop_simulator && !State.exception)
1306 *sigrc = SIGINT;
1307 else
1308 *sigrc = State.exception;
1309 break;
1310 }
1311
1312 stop_simulator = 0;
1313}
1314
1315int
1316sim_fetch_register (sd, rn, memory, length)
1317 SIM_DESC sd;
1318 int rn;
1319 unsigned char *memory;
1320 int length;
1321{
4ce44c66
JM
1322 int size;
1323 if (rn < 0)
1324 size = 0;
1325 else if (rn >= SIM_D10V_R0_REGNUM
1326 && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1327 {
1328 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1329 size = 2;
1330 }
1331 else if (rn >= SIM_D10V_CR0_REGNUM
1332 && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1333 {
1334 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1335 size = 2;
1336 }
1337 else if (rn >= SIM_D10V_A0_REGNUM
1338 && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1339 {
1340 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1341 size = 8;
1342 }
1343 else if (rn == SIM_D10V_SPI_REGNUM)
1344 {
1345 /* PSW_SM indicates that the current SP is the USER
1346 stack-pointer. */
1347 WRITE_16 (memory, spi_register ());
1348 size = 2;
1349 }
1350 else if (rn == SIM_D10V_SPU_REGNUM)
1351 {
1352 /* PSW_SM indicates that the current SP is the USER
1353 stack-pointer. */
1354 WRITE_16 (memory, spu_register ());
1355 size = 2;
1356 }
1357 else if (rn >= SIM_D10V_IMAP0_REGNUM
1358 && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1359 {
1360 WRITE_16 (memory, imap_register (rn - SIM_D10V_IMAP0_REGNUM));
1361 size = 2;
1362 }
1363 else if (rn >= SIM_D10V_DMAP0_REGNUM
1364 && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1365 {
1366 WRITE_16 (memory, dmap_register (rn - SIM_D10V_DMAP0_REGNUM));
1367 size = 2;
1368 }
c906108c 1369 else
4ce44c66
JM
1370 size = 0;
1371 return size;
c906108c
SS
1372}
1373
1374int
1375sim_store_register (sd, rn, memory, length)
1376 SIM_DESC sd;
1377 int rn;
1378 unsigned char *memory;
1379 int length;
1380{
4ce44c66
JM
1381 int size;
1382 if (rn < 0)
1383 size = 0;
1384 else if (rn >= SIM_D10V_R0_REGNUM
1385 && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1386 {
1387 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1388 size = 2;
1389 }
1390 else if (rn >= SIM_D10V_CR0_REGNUM
1391 && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1392 {
1393 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1394 size = 2;
1395 }
1396 else if (rn >= SIM_D10V_A0_REGNUM
1397 && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1398 {
1399 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1400 size = 8;
1401 }
1402 else if (rn == SIM_D10V_SPI_REGNUM)
1403 {
1404 /* PSW_SM indicates that the current SP is the USER
1405 stack-pointer. */
1406 set_spi_register (READ_16 (memory));
1407 size = 2;
1408 }
1409 else if (rn == SIM_D10V_SPU_REGNUM)
1410 {
1411 set_spu_register (READ_16 (memory));
1412 size = 2;
1413 }
1414 else if (rn >= SIM_D10V_IMAP0_REGNUM
1415 && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1416 {
1417 set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
1418 size = 2;
1419 }
1420 else if (rn >= SIM_D10V_DMAP0_REGNUM
1421 && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1422 {
1423 set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
1424 size = 2;
1425 }
c906108c 1426 else
4ce44c66 1427 size = 0;
c906108c 1428 SLOT_FLUSH ();
4ce44c66 1429 return size;
c906108c
SS
1430}
1431
1432
1433void
1434sim_do_command (sd, cmd)
1435 SIM_DESC sd;
1436 char *cmd;
1437{
1438 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
1439}
1440
1441SIM_RC
1442sim_load (sd, prog, abfd, from_tty)
1443 SIM_DESC sd;
1444 char *prog;
1445 bfd *abfd;
1446 int from_tty;
1447{
1448 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1449
1450 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1451 {
1452 bfd_close (prog_bfd);
1453 prog_bfd_was_opened_p = 0;
1454 }
1455 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
1456 sim_kind == SIM_OPEN_DEBUG,
1457 1/*LMA*/, sim_write);
1458 if (prog_bfd == NULL)
1459 return SIM_RC_FAIL;
1460 prog_bfd_was_opened_p = abfd == NULL;
1461 return SIM_RC_OK;
1462}