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