]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/d10v/interp.c
Fix changelog typo.
[thirdparty/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
c906108c
SS
1#include <signal.h>
2#include "sysdep.h"
3#include "bfd.h"
3c25f8c7
AC
4#include "gdb/callback.h"
5#include "gdb/remote-sim.h"
c906108c
SS
6
7#include "d10v_sim.h"
b91b96f4 8#include "gdb/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 */
0aaa4a81 52extern int (*deprecated_ui_loop_hook) PARAMS ((int signo));
7a292a7a
SS
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 365static unsigned long
f6684c31 366dmap_register (void *regcache, int reg_nr)
4ce44c66
JM
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 388static unsigned long
f6684c31 389imap_register (void *regcache, int reg_nr)
4ce44c66
JM
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,
f6684c31
AC
443 void *regcache,
444 unsigned long (*dmap_register) (void *regcache,
445 int reg_nr))
4ce44c66
JM
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 }
f6684c31 462 map = dmap_register (regcache, regno);
4ce44c66
JM
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,
f6684c31
AC
503 void *regcache,
504 unsigned long (*imap_register) (void *regcache,
505 int reg_nr))
4ce44c66
JM
506{
507 short map;
508 int regno;
509 int sp;
510 int segno;
511 last_from = "logical-insn";
512 if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
513 {
514 /* Logical address outside of IMAP segments, not supported */
515 return 0;
516 }
517 regno = (offset / IMAP_BLOCK_SIZE);
518 offset = (offset % IMAP_BLOCK_SIZE);
519 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
520 {
521 /* Don't cross a BLOCK boundary */
522 nr_bytes = IMAP_BLOCK_SIZE - offset;
523 }
f6684c31 524 map = imap_register (regcache, regno);
4ce44c66
JM
525 sp = (map & 0x3000) >> 12;
526 segno = (map & 0x007f);
527 switch (sp)
528 {
529 case 0: /* 00: unified memory */
530 *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
531 last_to = "unified";
532 break;
533 case 1: /* 01: instruction memory */
534 *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
535 last_to = "chip-insn";
536 break;
537 case 2: /*10*/
538 /* Reserved. */
539 return 0;
540 case 3: /* 11: for testing - instruction memory */
541 offset = (offset % 0x800);
542 *phys = SIM_D10V_MEMORY_INSN + offset;
543 if (offset + nr_bytes > 0x800)
544 /* don't cross VM boundary */
545 nr_bytes = 0x800 - offset;
546 last_to = "test-insn";
547 break;
548 }
549 return nr_bytes;
550}
cff3e48b 551
4ce44c66
JM
552unsigned long
553sim_d10v_translate_addr (unsigned long memaddr,
554 int nr_bytes,
555 unsigned long *targ_addr,
f6684c31
AC
556 void *regcache,
557 unsigned long (*dmap_register) (void *regcache,
558 int reg_nr),
559 unsigned long (*imap_register) (void *regcache,
560 int reg_nr))
4ce44c66
JM
561{
562 unsigned long phys;
563 unsigned long seg;
564 unsigned long off;
cff3e48b 565
4ce44c66
JM
566 last_from = "unknown";
567 last_to = "unknown";
cff3e48b 568
4ce44c66
JM
569 seg = (memaddr >> 24);
570 off = (memaddr & 0xffffffL);
c906108c 571
cff3e48b
JM
572 /* However, if we've asked to use the previous generation of segment
573 mapping, rearrange the segments as follows. */
574
575 if (old_segment_mapping)
576 {
4ce44c66 577 switch (seg)
cff3e48b
JM
578 {
579 case 0x00: /* DMAP translated memory */
4ce44c66 580 seg = 0x10;
cff3e48b
JM
581 break;
582 case 0x01: /* IMAP translated memory */
4ce44c66 583 seg = 0x11;
cff3e48b
JM
584 break;
585 case 0x10: /* On-chip data memory */
4ce44c66 586 seg = 0x02;
cff3e48b
JM
587 break;
588 case 0x11: /* On-chip insn memory */
4ce44c66 589 seg = 0x01;
cff3e48b
JM
590 break;
591 case 0x12: /* Unified memory */
4ce44c66 592 seg = 0x00;
cff3e48b
JM
593 break;
594 }
595 }
596
4ce44c66 597 switch (seg)
c906108c 598 {
4ce44c66
JM
599 case 0x00: /* Physical unified memory */
600 last_from = "phys-unified";
601 last_to = "unified";
602 phys = SIM_D10V_MEMORY_UNIFIED + off;
603 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
604 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
605 break;
c906108c 606
4ce44c66
JM
607 case 0x01: /* Physical instruction memory */
608 last_from = "phys-insn";
609 last_to = "chip-insn";
610 phys = SIM_D10V_MEMORY_INSN + off;
611 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
612 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
613 break;
c906108c 614
4ce44c66
JM
615 case 0x02: /* Physical data memory segment */
616 last_from = "phys-data";
617 last_to = "chip-data";
618 phys = SIM_D10V_MEMORY_DATA + off;
619 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
620 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
621 break;
622
623 case 0x10: /* in logical data address segment */
f6684c31 624 nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys, regcache,
4ce44c66
JM
625 dmap_register);
626 break;
627
628 case 0x11: /* in logical instruction address segment */
f6684c31 629 nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys, regcache,
4ce44c66
JM
630 imap_register);
631 break;
632
633 default:
634 return 0;
635 }
636
637 *targ_addr = phys;
638 return nr_bytes;
639}
640
641/* Return a pointer into the raw buffer designated by phys_addr. It
642 is assumed that the client has already ensured that the access
643 isn't going to cross a segment boundary. */
644
645uint8 *
646map_memory (unsigned phys_addr)
647{
648 uint8 **memory;
649 uint8 *raw;
650 unsigned offset;
651 int segment = ((phys_addr >> 24) & 0xff);
652
653 switch (segment)
654 {
655
656 case 0x00: /* Unified memory */
c906108c 657 {
4ce44c66
JM
658 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
659 last_segname = "umem";
c906108c
SS
660 break;
661 }
4ce44c66 662
cff3e48b 663 case 0x01: /* On-chip insn memory */
c906108c 664 {
4ce44c66
JM
665 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
666 last_segname = "imem";
c906108c
SS
667 break;
668 }
4ce44c66
JM
669
670 case 0x02: /* On-chip data memory */
c906108c 671 {
4ce44c66 672 if ((phys_addr & 0xff00) == 0xff00)
c906108c 673 {
4ce44c66
JM
674 phys_addr = (phys_addr & 0xffff);
675 if (phys_addr == DMAP2_SHADDOW)
c906108c 676 {
4ce44c66
JM
677 phys_addr = DMAP2_OFFSET;
678 last_segname = "dmap";
c906108c 679 }
4ce44c66
JM
680 else
681 last_segname = "reg";
c906108c 682 }
4ce44c66
JM
683 else
684 last_segname = "dmem";
685 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
c906108c
SS
686 break;
687 }
4ce44c66 688
c906108c 689 default:
4ce44c66
JM
690 /* OOPS! */
691 last_segname = "scrap";
692 return State.mem.fault;
c906108c 693 }
4ce44c66
JM
694
695 if (*memory == NULL)
c906108c 696 {
4ce44c66
JM
697 *memory = calloc (1, SEGMENT_SIZE);
698 if (*memory == NULL)
699 {
700 (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");
701 return State.mem.fault;
702 }
c906108c 703 }
4ce44c66
JM
704
705 offset = (phys_addr % SEGMENT_SIZE);
706 raw = *memory + offset;
707 return raw;
708}
709
710/* Transfer data to/from simulated memory. Since a bug in either the
711 simulated program or in gdb or the simulator itself may cause a
712 bogus address to be passed in, we need to do some sanity checking
713 on addresses to make sure they are within bounds. When an address
714 fails the bounds check, treat it as a zero length read/write rather
715 than aborting the entire run. */
716
717static int
718xfer_mem (SIM_ADDR virt,
719 unsigned char *buffer,
720 int size,
721 int write_p)
722{
ea086965
AC
723 uint8 *memory;
724 unsigned long phys;
725 int phys_size;
726 phys_size = sim_d10v_translate_addr (virt, size, &phys, NULL,
727 dmap_register, imap_register);
728 if (phys_size == 0)
729 return 0;
4ce44c66 730
ea086965 731 memory = map_memory (phys);
4ce44c66
JM
732
733#ifdef DEBUG
ea086965
AC
734 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
735 {
736 (*d10v_callback->printf_filtered)
737 (d10v_callback,
738 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
4ce44c66 739 (write_p ? "write" : "read"),
ea086965
AC
740 phys_size, virt, last_from,
741 phys, last_to,
742 (long) memory, last_segname);
743 }
4ce44c66
JM
744#endif
745
ea086965
AC
746 if (write_p)
747 {
748 memcpy (memory, buffer, phys_size);
c906108c 749 }
ea086965
AC
750 else
751 {
752 memcpy (buffer, memory, phys_size);
753 }
754
755 return phys_size;
c906108c
SS
756}
757
758
759int
760sim_write (sd, addr, buffer, size)
761 SIM_DESC sd;
762 SIM_ADDR addr;
763 unsigned char *buffer;
764 int size;
765{
766 /* FIXME: this should be performing a virtual transfer */
767 return xfer_mem( addr, buffer, size, 1);
768}
769
770int
771sim_read (sd, addr, buffer, size)
772 SIM_DESC sd;
773 SIM_ADDR addr;
774 unsigned char *buffer;
775 int size;
776{
777 /* FIXME: this should be performing a virtual transfer */
778 return xfer_mem( addr, buffer, size, 0);
779}
780
781
782SIM_DESC
783sim_open (kind, callback, abfd, argv)
784 SIM_OPEN_KIND kind;
785 host_callback *callback;
6b4a8935 786 struct bfd *abfd;
c906108c
SS
787 char **argv;
788{
789 struct simops *s;
790 struct hash_entry *h;
791 static int init_p = 0;
792 char **p;
793
794 sim_kind = kind;
795 d10v_callback = callback;
796 myname = argv[0];
cff3e48b 797 old_segment_mapping = 0;
c906108c 798
4ce44c66
JM
799 /* NOTE: This argument parsing is only effective when this function
800 is called by GDB. Standalone argument parsing is handled by
801 sim/common/run.c. */
c906108c
SS
802 for (p = argv + 1; *p; ++p)
803 {
cff3e48b
JM
804 if (strcmp (*p, "-oldseg") == 0)
805 old_segment_mapping = 1;
c906108c 806#ifdef DEBUG
cff3e48b 807 else if (strcmp (*p, "-t") == 0)
c906108c 808 d10v_debug = DEBUG;
4ce44c66
JM
809 else if (strncmp (*p, "-t", 2) == 0)
810 d10v_debug = atoi (*p + 2);
c906108c 811#endif
cff3e48b 812 else
c906108c
SS
813 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
814 }
815
816 /* put all the opcodes in the hash table */
817 if (!init_p++)
818 {
819 for (s = Simops; s->func; s++)
820 {
821 h = &hash_table[hash(s->opcode,s->format)];
822
823 /* go to the last entry in the chain */
824 while (h->next)
825 h = h->next;
826
827 if (h->ops)
828 {
829 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
830 if (!h->next)
831 perror ("malloc failure");
832
833 h = h->next;
834 }
835 h->ops = s;
836 h->mask = s->mask;
837 h->opcode = s->opcode;
838 h->size = s->is_long;
839 }
840 }
841
842 /* reset the processor state */
4ce44c66
JM
843 if (!State.mem.data[0])
844 sim_size (1);
c906108c
SS
845 sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
846
847 /* Fudge our descriptor. */
848 return (SIM_DESC) 1;
849}
850
851
852void
853sim_close (sd, quitting)
854 SIM_DESC sd;
855 int quitting;
856{
857 if (prog_bfd != NULL && prog_bfd_was_opened_p)
858 {
859 bfd_close (prog_bfd);
860 prog_bfd = NULL;
861 prog_bfd_was_opened_p = 0;
862 }
863}
864
865void
866sim_set_profile (n)
867 int n;
868{
869 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
870}
871
872void
873sim_set_profile_size (n)
874 int n;
875{
876 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
877}
878
c906108c 879uint8 *
4ce44c66 880dmem_addr (uint16 offset)
c906108c 881{
4ce44c66
JM
882 unsigned long phys;
883 uint8 *mem;
884 int phys_size;
c906108c 885
4ce44c66
JM
886 /* Note: DMEM address range is 0..0x10000. Calling code can compute
887 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
888 is uint16 this is modulo'ed onto 0x0e5d. */
c906108c 889
f6684c31 890 phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys, NULL,
4ce44c66
JM
891 dmap_register);
892 if (phys_size == 0)
c906108c 893 {
4ce44c66 894 mem = State.mem.fault;
c906108c 895 }
4ce44c66
JM
896 else
897 mem = map_memory (phys);
c906108c 898#ifdef DEBUG
4ce44c66
JM
899 if ((d10v_debug & DEBUG_MEMORY))
900 {
901 (*d10v_callback->printf_filtered)
902 (d10v_callback,
903 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
904 offset, last_from,
905 phys, phys_size, last_to,
906 (long) mem, last_segname);
c906108c 907 }
4ce44c66
JM
908#endif
909 return mem;
c906108c
SS
910}
911
c906108c 912uint8 *
4ce44c66 913imem_addr (uint32 offset)
c906108c 914{
4ce44c66
JM
915 unsigned long phys;
916 uint8 *mem;
f6684c31
AC
917 int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, NULL,
918 imap_register);
4ce44c66
JM
919 if (phys_size == 0)
920 {
921 return State.mem.fault;
922 }
923 mem = map_memory (phys);
924#ifdef DEBUG
925 if ((d10v_debug & DEBUG_MEMORY))
926 {
927 (*d10v_callback->printf_filtered)
928 (d10v_callback,
929 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
930 offset, last_from,
931 phys, phys_size, last_to,
932 (long) mem, last_segname);
933 }
934#endif
935 return mem;
c906108c
SS
936}
937
c906108c
SS
938static int stop_simulator = 0;
939
940int
941sim_stop (sd)
942 SIM_DESC sd;
943{
944 stop_simulator = 1;
945 return 1;
946}
947
948
949/* Run (or resume) the program. */
950void
951sim_resume (sd, step, siggnal)
952 SIM_DESC sd;
953 int step, siggnal;
954{
955 uint32 inst;
956 uint8 *iaddr;
957
958/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
959 State.exception = 0;
960 if (step)
961 sim_stop (sd);
962
7fc5b5ad
AC
963 switch (siggnal)
964 {
965 case 0:
966 break;
967#ifdef SIGBUS
968 case SIGBUS:
969#endif
970 case SIGSEGV:
971 SET_BPC (PC);
972 SET_BPSW (PSW);
973 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
974 JMP (AE_VECTOR_START);
975 SLOT_FLUSH ();
976 break;
27842f65
AC
977 case SIGILL:
978 SET_BPC (PC);
979 SET_BPSW (PSW);
980 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
981 JMP (RIE_VECTOR_START);
982 SLOT_FLUSH ();
983 break;
7fc5b5ad
AC
984 default:
985 /* just ignore it */
986 break;
987 }
988
c906108c
SS
989 do
990 {
991 iaddr = imem_addr ((uint32)PC << 2);
4ce44c66 992 if (iaddr == State.mem.fault)
c906108c
SS
993 {
994 State.exception = SIGBUS;
995 break;
996 }
997
998 inst = get_longword( iaddr );
999
1000 State.pc_changed = 0;
1001 ins_type_counters[ (int)INS_CYCLES ]++;
1002
1003 switch (inst & 0xC0000000)
1004 {
1005 case 0xC0000000:
1006 /* long instruction */
1007 do_long (inst & 0x3FFFFFFF);
1008 break;
1009 case 0x80000000:
1010 /* R -> L */
1011 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
1012 break;
1013 case 0x40000000:
1014 /* L -> R */
1015 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
1016 break;
1017 case 0:
1018 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
1019 break;
1020 }
1021
1022 /* If the PC of the current instruction matches RPT_E then
1023 schedule a branch to the loop start. If one of those
1024 instructions happens to be a branch, than that instruction
1025 will be ignored */
1026 if (!State.pc_changed)
1027 {
1028 if (PSW_RP && PC == RPT_E)
1029 {
1030 /* Note: The behavour of a branch instruction at RPT_E
1031 is implementation dependant, this simulator takes the
1032 branch. Branching to RPT_E is valid, the instruction
1033 must be executed before the loop is taken. */
1034 if (RPT_C == 1)
1035 {
1036 SET_PSW_RP (0);
1037 SET_RPT_C (0);
1038 SET_PC (PC + 1);
1039 }
1040 else
1041 {
1042 SET_RPT_C (RPT_C - 1);
1043 SET_PC (RPT_S);
1044 }
1045 }
1046 else
1047 SET_PC (PC + 1);
1048 }
1049
1050 /* Check for a breakpoint trap on this instruction. This
1051 overrides any pending branches or loops */
1052 if (PSW_DB && PC == IBA)
1053 {
1054 SET_BPC (PC);
1055 SET_BPSW (PSW);
1056 SET_PSW (PSW & PSW_SM_BIT);
1057 SET_PC (SDBT_VECTOR_START);
1058 }
1059
1060 /* Writeback all the DATA / PC changes */
1061 SLOT_FLUSH ();
1062
7a292a7a 1063#ifdef NEED_UI_LOOP_HOOK
0aaa4a81 1064 if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
7a292a7a
SS
1065 {
1066 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
0aaa4a81 1067 deprecated_ui_loop_hook (0);
7a292a7a
SS
1068 }
1069#endif /* NEED_UI_LOOP_HOOK */
c906108c
SS
1070 }
1071 while ( !State.exception && !stop_simulator);
1072
1073 if (step && !State.exception)
1074 State.exception = SIGTRAP;
1075}
1076
baa7ae6f
AC
1077void
1078sim_set_trace (void)
c906108c
SS
1079{
1080#ifdef DEBUG
1081 d10v_debug = DEBUG;
1082#endif
c906108c
SS
1083}
1084
1085void
1086sim_info (sd, verbose)
1087 SIM_DESC sd;
1088 int verbose;
1089{
1090 char buf1[40];
1091 char buf2[40];
1092 char buf3[40];
1093 char buf4[40];
1094 char buf5[40];
1095 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1096 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1097 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1098 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1099 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1100
1101 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1102 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1103 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1104 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1105 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1106
1107 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1108 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1109 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1110 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1111 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1112 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1113 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1114 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1115 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1116 unsigned long total = (unknown + left_total + right_total + ins_long);
1117
1118 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1119 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1120 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1121 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1122 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1123 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1124
1125 (*d10v_callback->printf_filtered) (d10v_callback,
1126 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1127 size, add_commas (buf1, sizeof (buf1), left_total),
1128 normal_size, add_commas (buf2, sizeof (buf2), left),
1129 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1130 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1131 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1132
1133 (*d10v_callback->printf_filtered) (d10v_callback,
1134 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1135 size, add_commas (buf1, sizeof (buf1), right_total),
1136 normal_size, add_commas (buf2, sizeof (buf2), right),
1137 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1138 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1139 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1140
1141 if (ins_long)
1142 (*d10v_callback->printf_filtered) (d10v_callback,
1143 "executed %*s long instruction(s)\n",
1144 size, add_commas (buf1, sizeof (buf1), ins_long));
1145
1146 if (parallel)
1147 (*d10v_callback->printf_filtered) (d10v_callback,
1148 "executed %*s parallel instruction(s)\n",
1149 size, add_commas (buf1, sizeof (buf1), parallel));
1150
1151 if (leftright)
1152 (*d10v_callback->printf_filtered) (d10v_callback,
1153 "executed %*s instruction(s) encoded L->R\n",
1154 size, add_commas (buf1, sizeof (buf1), leftright));
1155
1156 if (rightleft)
1157 (*d10v_callback->printf_filtered) (d10v_callback,
1158 "executed %*s instruction(s) encoded R->L\n",
1159 size, add_commas (buf1, sizeof (buf1), rightleft));
1160
1161 if (unknown)
1162 (*d10v_callback->printf_filtered) (d10v_callback,
1163 "executed %*s unknown instruction(s)\n",
1164 size, add_commas (buf1, sizeof (buf1), unknown));
1165
1166 if (cond_true)
1167 (*d10v_callback->printf_filtered) (d10v_callback,
1168 "executed %*s instruction(s) due to EXExxx condition being true\n",
1169 size, add_commas (buf1, sizeof (buf1), cond_true));
1170
1171 if (cond_false)
1172 (*d10v_callback->printf_filtered) (d10v_callback,
1173 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1174 size, add_commas (buf1, sizeof (buf1), cond_false));
1175
1176 if (cond_jump)
1177 (*d10v_callback->printf_filtered) (d10v_callback,
1178 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1179 size, add_commas (buf1, sizeof (buf1), cond_jump));
1180
1181 (*d10v_callback->printf_filtered) (d10v_callback,
1182 "executed %*s cycle(s)\n",
1183 size, add_commas (buf1, sizeof (buf1), cycles));
1184
1185 (*d10v_callback->printf_filtered) (d10v_callback,
1186 "executed %*s total instructions\n",
1187 size, add_commas (buf1, sizeof (buf1), total));
1188}
1189
1190SIM_RC
1191sim_create_inferior (sd, abfd, argv, env)
1192 SIM_DESC sd;
6b4a8935 1193 struct bfd *abfd;
c906108c
SS
1194 char **argv;
1195 char **env;
1196{
1197 bfd_vma start_address;
1198
1199 /* reset all state information */
4ce44c66 1200 memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
c906108c 1201
1aa5e64f
EZ
1202 /* There was a hack here to copy the values of argc and argv into r0
1203 and r1. The values were also saved into some high memory that
1204 won't be overwritten by the stack (0x7C00). The reason for doing
1205 this was to allow the 'run' program to accept arguments. Without
1206 the hack, this is not possible anymore. If the simulator is run
1207 from the debugger, arguments cannot be passed in, so this makes
1208 no difference. */
1209
c906108c
SS
1210 /* set PC */
1211 if (abfd != NULL)
1212 start_address = bfd_get_start_address (abfd);
1213 else
1214 start_address = 0xffc0 << 2;
1215#ifdef DEBUG
1216 if (d10v_debug)
1217 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1218#endif
1219 SET_CREG (PC_CR, start_address >> 2);
1220
4ce44c66
JM
1221 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1222 initializes imap0 and imap1 to 0x1000 as part of its ROM
1223 initialization. */
cff3e48b 1224 if (old_segment_mapping)
c906108c 1225 {
4ce44c66
JM
1226 /* External memory startup. This is the HARD reset state. */
1227 set_imap_register (0, 0x0000);
1228 set_imap_register (1, 0x007f);
1229 set_dmap_register (0, 0x2000);
1230 set_dmap_register (1, 0x2000);
1231 set_dmap_register (2, 0x0000); /* Old DMAP */
1232 set_dmap_register (3, 0x0000);
c906108c
SS
1233 }
1234 else
1235 {
4ce44c66
JM
1236 /* Internal memory startup. This is the ROM intialized state. */
1237 set_imap_register (0, 0x1000);
1238 set_imap_register (1, 0x1000);
1239 set_dmap_register (0, 0x2000);
1240 set_dmap_register (1, 0x2000);
ba744a4f
AC
1241 set_dmap_register (2, 0x2000); /* DMAP2 initial internal value is
1242 0x2000 on the new board. */
4ce44c66 1243 set_dmap_register (3, 0x0000);
c906108c
SS
1244 }
1245
1246 SLOT_FLUSH ();
1247 return SIM_RC_OK;
1248}
1249
1250
1251void
1252sim_set_callbacks (p)
1253 host_callback *p;
1254{
1255 d10v_callback = p;
1256}
1257
1258void
1259sim_stop_reason (sd, reason, sigrc)
1260 SIM_DESC sd;
1261 enum sim_stop *reason;
1262 int *sigrc;
1263{
1264/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1265
1266 switch (State.exception)
1267 {
1268 case SIG_D10V_STOP: /* stop instruction */
1269 *reason = sim_exited;
1270 *sigrc = 0;
1271 break;
1272
1273 case SIG_D10V_EXIT: /* exit trap */
1274 *reason = sim_exited;
1275 *sigrc = GPR (0);
1276 break;
1277
7fc5b5ad
AC
1278 case SIG_D10V_BUS:
1279 *reason = sim_stopped;
1280#ifdef SIGBUS
1281 *sigrc = SIGBUS;
1282#else
1283 *sigrc = SIGSEGV;
1284#endif
1285 break;
1286
c906108c
SS
1287 default: /* some signal */
1288 *reason = sim_stopped;
1289 if (stop_simulator && !State.exception)
1290 *sigrc = SIGINT;
1291 else
1292 *sigrc = State.exception;
1293 break;
1294 }
1295
1296 stop_simulator = 0;
1297}
1298
1299int
1300sim_fetch_register (sd, rn, memory, length)
1301 SIM_DESC sd;
1302 int rn;
1303 unsigned char *memory;
1304 int length;
1305{
4ce44c66 1306 int size;
983b727e 1307 switch ((enum sim_d10v_regs) rn)
4ce44c66 1308 {
18c0df9e
AC
1309 case SIM_D10V_R0_REGNUM:
1310 case SIM_D10V_R1_REGNUM:
1311 case SIM_D10V_R2_REGNUM:
1312 case SIM_D10V_R3_REGNUM:
1313 case SIM_D10V_R4_REGNUM:
1314 case SIM_D10V_R5_REGNUM:
1315 case SIM_D10V_R6_REGNUM:
1316 case SIM_D10V_R7_REGNUM:
1317 case SIM_D10V_R8_REGNUM:
1318 case SIM_D10V_R9_REGNUM:
1319 case SIM_D10V_R10_REGNUM:
1320 case SIM_D10V_R11_REGNUM:
1321 case SIM_D10V_R12_REGNUM:
1322 case SIM_D10V_R13_REGNUM:
1323 case SIM_D10V_R14_REGNUM:
1324 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1325 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1326 size = 2;
18c0df9e
AC
1327 break;
1328 case SIM_D10V_CR0_REGNUM:
1329 case SIM_D10V_CR1_REGNUM:
1330 case SIM_D10V_CR2_REGNUM:
1331 case SIM_D10V_CR3_REGNUM:
1332 case SIM_D10V_CR4_REGNUM:
1333 case SIM_D10V_CR5_REGNUM:
1334 case SIM_D10V_CR6_REGNUM:
1335 case SIM_D10V_CR7_REGNUM:
1336 case SIM_D10V_CR8_REGNUM:
1337 case SIM_D10V_CR9_REGNUM:
1338 case SIM_D10V_CR10_REGNUM:
1339 case SIM_D10V_CR11_REGNUM:
1340 case SIM_D10V_CR12_REGNUM:
1341 case SIM_D10V_CR13_REGNUM:
1342 case SIM_D10V_CR14_REGNUM:
1343 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1344 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1345 size = 2;
18c0df9e
AC
1346 break;
1347 case SIM_D10V_A0_REGNUM:
1348 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1349 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1350 size = 8;
18c0df9e
AC
1351 break;
1352 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1353 /* PSW_SM indicates that the current SP is the USER
1354 stack-pointer. */
1355 WRITE_16 (memory, spi_register ());
1356 size = 2;
18c0df9e
AC
1357 break;
1358 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1359 /* PSW_SM indicates that the current SP is the USER
1360 stack-pointer. */
1361 WRITE_16 (memory, spu_register ());
1362 size = 2;
18c0df9e
AC
1363 break;
1364 case SIM_D10V_IMAP0_REGNUM:
1365 case SIM_D10V_IMAP1_REGNUM:
f6684c31 1366 WRITE_16 (memory, imap_register (NULL, rn - SIM_D10V_IMAP0_REGNUM));
4ce44c66 1367 size = 2;
18c0df9e
AC
1368 break;
1369 case SIM_D10V_DMAP0_REGNUM:
1370 case SIM_D10V_DMAP1_REGNUM:
1371 case SIM_D10V_DMAP2_REGNUM:
1372 case SIM_D10V_DMAP3_REGNUM:
f6684c31 1373 WRITE_16 (memory, dmap_register (NULL, rn - SIM_D10V_DMAP0_REGNUM));
4ce44c66 1374 size = 2;
18c0df9e
AC
1375 break;
1376 case SIM_D10V_TS2_DMAP_REGNUM:
1377 size = 0;
1378 break;
1379 default:
1380 size = 0;
1381 break;
4ce44c66 1382 }
4ce44c66 1383 return size;
c906108c
SS
1384}
1385
1386int
1387sim_store_register (sd, rn, memory, length)
1388 SIM_DESC sd;
1389 int rn;
1390 unsigned char *memory;
1391 int length;
1392{
4ce44c66 1393 int size;
983b727e 1394 switch ((enum sim_d10v_regs) rn)
4ce44c66 1395 {
18c0df9e
AC
1396 case SIM_D10V_R0_REGNUM:
1397 case SIM_D10V_R1_REGNUM:
1398 case SIM_D10V_R2_REGNUM:
1399 case SIM_D10V_R3_REGNUM:
1400 case SIM_D10V_R4_REGNUM:
1401 case SIM_D10V_R5_REGNUM:
1402 case SIM_D10V_R6_REGNUM:
1403 case SIM_D10V_R7_REGNUM:
1404 case SIM_D10V_R8_REGNUM:
1405 case SIM_D10V_R9_REGNUM:
1406 case SIM_D10V_R10_REGNUM:
1407 case SIM_D10V_R11_REGNUM:
1408 case SIM_D10V_R12_REGNUM:
1409 case SIM_D10V_R13_REGNUM:
1410 case SIM_D10V_R14_REGNUM:
1411 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1412 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1413 size = 2;
18c0df9e
AC
1414 break;
1415 case SIM_D10V_CR0_REGNUM:
1416 case SIM_D10V_CR1_REGNUM:
1417 case SIM_D10V_CR2_REGNUM:
1418 case SIM_D10V_CR3_REGNUM:
1419 case SIM_D10V_CR4_REGNUM:
1420 case SIM_D10V_CR5_REGNUM:
1421 case SIM_D10V_CR6_REGNUM:
1422 case SIM_D10V_CR7_REGNUM:
1423 case SIM_D10V_CR8_REGNUM:
1424 case SIM_D10V_CR9_REGNUM:
1425 case SIM_D10V_CR10_REGNUM:
1426 case SIM_D10V_CR11_REGNUM:
1427 case SIM_D10V_CR12_REGNUM:
1428 case SIM_D10V_CR13_REGNUM:
1429 case SIM_D10V_CR14_REGNUM:
1430 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1431 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1432 size = 2;
18c0df9e
AC
1433 break;
1434 case SIM_D10V_A0_REGNUM:
1435 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1436 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1437 size = 8;
18c0df9e
AC
1438 break;
1439 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1440 /* PSW_SM indicates that the current SP is the USER
1441 stack-pointer. */
1442 set_spi_register (READ_16 (memory));
1443 size = 2;
18c0df9e
AC
1444 break;
1445 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1446 set_spu_register (READ_16 (memory));
1447 size = 2;
18c0df9e
AC
1448 break;
1449 case SIM_D10V_IMAP0_REGNUM:
1450 case SIM_D10V_IMAP1_REGNUM:
4ce44c66
JM
1451 set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
1452 size = 2;
18c0df9e
AC
1453 break;
1454 case SIM_D10V_DMAP0_REGNUM:
1455 case SIM_D10V_DMAP1_REGNUM:
1456 case SIM_D10V_DMAP2_REGNUM:
1457 case SIM_D10V_DMAP3_REGNUM:
4ce44c66
JM
1458 set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
1459 size = 2;
18c0df9e
AC
1460 break;
1461 case SIM_D10V_TS2_DMAP_REGNUM:
1462 size = 0;
1463 break;
1464 default:
1465 size = 0;
1466 break;
4ce44c66 1467 }
c906108c 1468 SLOT_FLUSH ();
4ce44c66 1469 return size;
c906108c
SS
1470}
1471
1472
1473void
1474sim_do_command (sd, cmd)
1475 SIM_DESC sd;
1476 char *cmd;
1477{
1478 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
1479}
1480
1481SIM_RC
1482sim_load (sd, prog, abfd, from_tty)
1483 SIM_DESC sd;
1484 char *prog;
1485 bfd *abfd;
1486 int from_tty;
1487{
1488 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1489
1490 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1491 {
1492 bfd_close (prog_bfd);
1493 prog_bfd_was_opened_p = 0;
1494 }
1495 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
1496 sim_kind == SIM_OPEN_DEBUG,
1497 1/*LMA*/, sim_write);
1498 if (prog_bfd == NULL)
1499 return SIM_RC_FAIL;
1500 prog_bfd_was_opened_p = abfd == NULL;
1501 return SIM_RC_OK;
1502}