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