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