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