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