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