]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/d10v/interp.c
Power10 bignum operands
[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,
ea086965 681 "sim_%s %d bytes: 0x%08lx (%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 */
67954606 706 return xfer_mem (sd, addr, buffer, size, 1);
c906108c
SS
707}
708
709int
11558abc 710sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c
SS
711{
712 /* FIXME: this should be performing a virtual transfer */
67954606 713 return xfer_mem (sd, addr, buffer, size, 0);
c906108c
SS
714}
715
27b97b40
MF
716static sim_cia
717d10v_pc_get (sim_cpu *cpu)
718{
719 return PC;
720}
721
722static void
723d10v_pc_set (sim_cpu *cpu, sim_cia pc)
724{
67954606 725 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
726 SET_PC (pc);
727}
728
541ebcee
MF
729static void
730free_state (SIM_DESC sd)
731{
732 if (STATE_MODULES (sd) != NULL)
733 sim_module_uninstall (sd);
734 sim_cpu_free_all (sd);
735 sim_state_free (sd);
736}
737
e1211e55
MF
738static int d10v_reg_fetch (SIM_CPU *, int, unsigned char *, int);
739static int d10v_reg_store (SIM_CPU *, int, unsigned char *, int);
740
c906108c 741SIM_DESC
2e3d4f4d
MF
742sim_open (SIM_OPEN_KIND kind, host_callback *cb,
743 struct bfd *abfd, char * const *argv)
c906108c
SS
744{
745 struct simops *s;
746 struct hash_entry *h;
747 static int init_p = 0;
748 char **p;
27b97b40 749 int i;
541ebcee
MF
750 SIM_DESC sd = sim_state_alloc (kind, cb);
751 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
c906108c 752
541ebcee
MF
753 /* The cpu data is kept in a separately allocated chunk of memory. */
754 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
755 {
756 free_state (sd);
757 return 0;
758 }
759
760 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
761 {
762 free_state (sd);
763 return 0;
764 }
765
77cf2ef5 766 /* The parser will print an error message for us, so we silently return. */
541ebcee
MF
767 if (sim_parse_args (sd, argv) != SIM_RC_OK)
768 {
769 free_state (sd);
770 return 0;
771 }
772
773 /* Check for/establish the a reference program image. */
774 if (sim_analyze_program (sd,
775 (STATE_PROG_ARGV (sd) != NULL
776 ? *STATE_PROG_ARGV (sd)
777 : NULL), abfd) != SIM_RC_OK)
778 {
779 free_state (sd);
780 return 0;
781 }
782
783 /* Configure/verify the target byte order and other runtime
784 configuration options. */
785 if (sim_config (sd) != SIM_RC_OK)
786 {
787 sim_module_uninstall (sd);
788 return 0;
789 }
790
791 if (sim_post_argv_init (sd) != SIM_RC_OK)
792 {
793 /* Uninstall the modules to avoid memory leaks,
794 file descriptor leaks, etc. */
795 sim_module_uninstall (sd);
796 return 0;
797 }
798
27b97b40
MF
799 /* CPU specific initialization. */
800 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
801 {
802 SIM_CPU *cpu = STATE_CPU (sd, i);
803
e1211e55
MF
804 CPU_REG_FETCH (cpu) = d10v_reg_fetch;
805 CPU_REG_STORE (cpu) = d10v_reg_store;
27b97b40
MF
806 CPU_PC_FETCH (cpu) = d10v_pc_get;
807 CPU_PC_STORE (cpu) = d10v_pc_set;
808 }
809
cff3e48b 810 old_segment_mapping = 0;
c906108c 811
4ce44c66
JM
812 /* NOTE: This argument parsing is only effective when this function
813 is called by GDB. Standalone argument parsing is handled by
814 sim/common/run.c. */
c906108c
SS
815 for (p = argv + 1; *p; ++p)
816 {
cff3e48b
JM
817 if (strcmp (*p, "-oldseg") == 0)
818 old_segment_mapping = 1;
c906108c 819#ifdef DEBUG
cff3e48b 820 else if (strcmp (*p, "-t") == 0)
c906108c 821 d10v_debug = DEBUG;
4ce44c66
JM
822 else if (strncmp (*p, "-t", 2) == 0)
823 d10v_debug = atoi (*p + 2);
c906108c 824#endif
c906108c
SS
825 }
826
827 /* put all the opcodes in the hash table */
828 if (!init_p++)
829 {
830 for (s = Simops; s->func; s++)
831 {
832 h = &hash_table[hash(s->opcode,s->format)];
833
834 /* go to the last entry in the chain */
835 while (h->next)
836 h = h->next;
837
838 if (h->ops)
839 {
840 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
841 if (!h->next)
842 perror ("malloc failure");
843
844 h = h->next;
845 }
846 h->ops = s;
847 h->mask = s->mask;
848 h->opcode = s->opcode;
849 h->size = s->is_long;
850 }
851 }
852
853 /* reset the processor state */
4ce44c66
JM
854 if (!State.mem.data[0])
855 sim_size (1);
c906108c 856
541ebcee 857 return sd;
c906108c
SS
858}
859
c906108c 860uint8 *
67954606 861dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16 offset)
c906108c 862{
4ce44c66
JM
863 unsigned long phys;
864 uint8 *mem;
865 int phys_size;
c906108c 866
4ce44c66
JM
867 /* Note: DMEM address range is 0..0x10000. Calling code can compute
868 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
869 is uint16 this is modulo'ed onto 0x0e5d. */
c906108c 870
67954606 871 phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
4ce44c66
JM
872 dmap_register);
873 if (phys_size == 0)
aadc1740
MF
874 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
875 mem = map_memory (sd, cpu, phys);
c906108c 876#ifdef DEBUG
4ce44c66
JM
877 if ((d10v_debug & DEBUG_MEMORY))
878 {
e9b0081f
MF
879 sim_io_printf
880 (sd,
4ce44c66
JM
881 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
882 offset, last_from,
883 phys, phys_size, last_to,
884 (long) mem, last_segname);
c906108c 885 }
4ce44c66
JM
886#endif
887 return mem;
c906108c
SS
888}
889
c906108c 890uint8 *
67954606 891imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
c906108c 892{
4ce44c66
JM
893 unsigned long phys;
894 uint8 *mem;
67954606 895 int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
f6684c31 896 imap_register);
4ce44c66 897 if (phys_size == 0)
aadc1740 898 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
67954606 899 mem = map_memory (sd, cpu, phys);
4ce44c66
JM
900#ifdef DEBUG
901 if ((d10v_debug & DEBUG_MEMORY))
902 {
e9b0081f
MF
903 sim_io_printf
904 (sd,
4ce44c66
JM
905 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
906 offset, last_from,
907 phys, phys_size, last_to,
908 (long) mem, last_segname);
909 }
910#endif
911 return mem;
c906108c
SS
912}
913
aadc1740
MF
914static void
915step_once (SIM_DESC sd, SIM_CPU *cpu)
c906108c
SS
916{
917 uint32 inst;
918 uint8 *iaddr;
919
aadc1740 920 /* TODO: Unindent this block. */
c906108c 921 {
67954606 922 iaddr = imem_addr (sd, cpu, (uint32)PC << 2);
c906108c
SS
923
924 inst = get_longword( iaddr );
925
926 State.pc_changed = 0;
927 ins_type_counters[ (int)INS_CYCLES ]++;
928
929 switch (inst & 0xC0000000)
930 {
931 case 0xC0000000:
932 /* long instruction */
67954606 933 do_long (sd, cpu, inst & 0x3FFFFFFF);
c906108c
SS
934 break;
935 case 0x80000000:
936 /* R -> L */
67954606 937 do_2_short (sd, cpu, inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
c906108c
SS
938 break;
939 case 0x40000000:
940 /* L -> R */
67954606 941 do_2_short (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
c906108c
SS
942 break;
943 case 0:
67954606 944 do_parallel (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
c906108c
SS
945 break;
946 }
947
948 /* If the PC of the current instruction matches RPT_E then
949 schedule a branch to the loop start. If one of those
950 instructions happens to be a branch, than that instruction
951 will be ignored */
952 if (!State.pc_changed)
953 {
954 if (PSW_RP && PC == RPT_E)
955 {
956 /* Note: The behavour of a branch instruction at RPT_E
957 is implementation dependant, this simulator takes the
958 branch. Branching to RPT_E is valid, the instruction
959 must be executed before the loop is taken. */
960 if (RPT_C == 1)
961 {
962 SET_PSW_RP (0);
963 SET_RPT_C (0);
964 SET_PC (PC + 1);
965 }
966 else
967 {
968 SET_RPT_C (RPT_C - 1);
969 SET_PC (RPT_S);
970 }
971 }
972 else
973 SET_PC (PC + 1);
974 }
975
976 /* Check for a breakpoint trap on this instruction. This
977 overrides any pending branches or loops */
978 if (PSW_DB && PC == IBA)
979 {
980 SET_BPC (PC);
981 SET_BPSW (PSW);
982 SET_PSW (PSW & PSW_SM_BIT);
983 SET_PC (SDBT_VECTOR_START);
984 }
985
986 /* Writeback all the DATA / PC changes */
987 SLOT_FLUSH ();
c906108c 988 }
aadc1740
MF
989}
990
991void
992sim_engine_run (SIM_DESC sd,
993 int next_cpu_nr, /* ignore */
994 int nr_cpus, /* ignore */
995 int siggnal)
996{
997 sim_cpu *cpu;
998
999 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1000
1001 cpu = STATE_CPU (sd, 0);
1002
1003 switch (siggnal)
1004 {
1005 case 0:
1006 break;
1007 case GDB_SIGNAL_BUS:
1008 SET_BPC (PC);
1009 SET_BPSW (PSW);
1010 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1011 JMP (AE_VECTOR_START);
1012 SLOT_FLUSH ();
1013 break;
1014 case GDB_SIGNAL_ILL:
1015 SET_BPC (PC);
1016 SET_BPSW (PSW);
1017 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1018 JMP (RIE_VECTOR_START);
1019 SLOT_FLUSH ();
1020 break;
1021 default:
1022 /* just ignore it */
1023 break;
1024 }
1025
1026 while (1)
1027 {
1028 step_once (sd, cpu);
1029 if (sim_events_tick (sd))
1030 sim_events_process (sd);
1031 }
c906108c
SS
1032}
1033
c906108c 1034void
11558abc 1035sim_info (SIM_DESC sd, int verbose)
c906108c
SS
1036{
1037 char buf1[40];
1038 char buf2[40];
1039 char buf3[40];
1040 char buf4[40];
1041 char buf5[40];
1042 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1043 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1044 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1045 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1046 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1047
1048 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1049 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1050 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1051 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1052 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1053
1054 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1055 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1056 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1057 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1058 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1059 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1060 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1061 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1062 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1063 unsigned long total = (unknown + left_total + right_total + ins_long);
1064
1065 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1066 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1067 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1068 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1069 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1070 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1071
e9b0081f
MF
1072 sim_io_printf (sd,
1073 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1074 size, add_commas (buf1, sizeof (buf1), left_total),
1075 normal_size, add_commas (buf2, sizeof (buf2), left),
1076 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1077 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1078 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1079
1080 sim_io_printf (sd,
1081 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1082 size, add_commas (buf1, sizeof (buf1), right_total),
1083 normal_size, add_commas (buf2, sizeof (buf2), right),
1084 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1085 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1086 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
c906108c
SS
1087
1088 if (ins_long)
e9b0081f
MF
1089 sim_io_printf (sd,
1090 "executed %*s long instruction(s)\n",
1091 size, add_commas (buf1, sizeof (buf1), ins_long));
c906108c
SS
1092
1093 if (parallel)
e9b0081f
MF
1094 sim_io_printf (sd,
1095 "executed %*s parallel instruction(s)\n",
1096 size, add_commas (buf1, sizeof (buf1), parallel));
c906108c
SS
1097
1098 if (leftright)
e9b0081f
MF
1099 sim_io_printf (sd,
1100 "executed %*s instruction(s) encoded L->R\n",
1101 size, add_commas (buf1, sizeof (buf1), leftright));
c906108c
SS
1102
1103 if (rightleft)
e9b0081f
MF
1104 sim_io_printf (sd,
1105 "executed %*s instruction(s) encoded R->L\n",
1106 size, add_commas (buf1, sizeof (buf1), rightleft));
c906108c
SS
1107
1108 if (unknown)
e9b0081f
MF
1109 sim_io_printf (sd,
1110 "executed %*s unknown instruction(s)\n",
1111 size, add_commas (buf1, sizeof (buf1), unknown));
c906108c
SS
1112
1113 if (cond_true)
e9b0081f
MF
1114 sim_io_printf (sd,
1115 "executed %*s instruction(s) due to EXExxx condition being true\n",
1116 size, add_commas (buf1, sizeof (buf1), cond_true));
c906108c
SS
1117
1118 if (cond_false)
e9b0081f
MF
1119 sim_io_printf (sd,
1120 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1121 size, add_commas (buf1, sizeof (buf1), cond_false));
c906108c
SS
1122
1123 if (cond_jump)
e9b0081f
MF
1124 sim_io_printf (sd,
1125 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1126 size, add_commas (buf1, sizeof (buf1), cond_jump));
c906108c 1127
e9b0081f
MF
1128 sim_io_printf (sd,
1129 "executed %*s cycle(s)\n",
1130 size, add_commas (buf1, sizeof (buf1), cycles));
c906108c 1131
e9b0081f
MF
1132 sim_io_printf (sd,
1133 "executed %*s total instructions\n",
1134 size, add_commas (buf1, sizeof (buf1), total));
c906108c
SS
1135}
1136
1137SIM_RC
2e3d4f4d
MF
1138sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1139 char * const *argv, char * const *env)
c906108c
SS
1140{
1141 bfd_vma start_address;
1142
1143 /* reset all state information */
11558abc 1144 memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs);
c906108c 1145
1aa5e64f
EZ
1146 /* There was a hack here to copy the values of argc and argv into r0
1147 and r1. The values were also saved into some high memory that
1148 won't be overwritten by the stack (0x7C00). The reason for doing
1149 this was to allow the 'run' program to accept arguments. Without
1150 the hack, this is not possible anymore. If the simulator is run
1151 from the debugger, arguments cannot be passed in, so this makes
1152 no difference. */
1153
c906108c
SS
1154 /* set PC */
1155 if (abfd != NULL)
1156 start_address = bfd_get_start_address (abfd);
1157 else
1158 start_address = 0xffc0 << 2;
1159#ifdef DEBUG
1160 if (d10v_debug)
e9b0081f 1161 sim_io_printf (sd, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
c906108c 1162#endif
67954606
MF
1163 {
1164 SIM_CPU *cpu = STATE_CPU (sd, 0);
1165 SET_CREG (PC_CR, start_address >> 2);
1166 }
c906108c 1167
4ce44c66
JM
1168 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1169 initializes imap0 and imap1 to 0x1000 as part of its ROM
1170 initialization. */
cff3e48b 1171 if (old_segment_mapping)
c906108c 1172 {
4ce44c66 1173 /* External memory startup. This is the HARD reset state. */
67954606
MF
1174 set_imap_register (sd, 0, 0x0000);
1175 set_imap_register (sd, 1, 0x007f);
1176 set_dmap_register (sd, 0, 0x2000);
1177 set_dmap_register (sd, 1, 0x2000);
1178 set_dmap_register (sd, 2, 0x0000); /* Old DMAP */
1179 set_dmap_register (sd, 3, 0x0000);
c906108c
SS
1180 }
1181 else
1182 {
4ce44c66 1183 /* Internal memory startup. This is the ROM intialized state. */
67954606
MF
1184 set_imap_register (sd, 0, 0x1000);
1185 set_imap_register (sd, 1, 0x1000);
1186 set_dmap_register (sd, 0, 0x2000);
1187 set_dmap_register (sd, 1, 0x2000);
1188 set_dmap_register (sd, 2, 0x2000); /* DMAP2 initial internal value is
1189 0x2000 on the new board. */
1190 set_dmap_register (sd, 3, 0x0000);
c906108c
SS
1191 }
1192
1193 SLOT_FLUSH ();
1194 return SIM_RC_OK;
1195}
1196
e1211e55
MF
1197static int
1198d10v_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1199{
e1211e55 1200 SIM_DESC sd = CPU_STATE (cpu);
4ce44c66 1201 int size;
983b727e 1202 switch ((enum sim_d10v_regs) rn)
4ce44c66 1203 {
18c0df9e
AC
1204 case SIM_D10V_R0_REGNUM:
1205 case SIM_D10V_R1_REGNUM:
1206 case SIM_D10V_R2_REGNUM:
1207 case SIM_D10V_R3_REGNUM:
1208 case SIM_D10V_R4_REGNUM:
1209 case SIM_D10V_R5_REGNUM:
1210 case SIM_D10V_R6_REGNUM:
1211 case SIM_D10V_R7_REGNUM:
1212 case SIM_D10V_R8_REGNUM:
1213 case SIM_D10V_R9_REGNUM:
1214 case SIM_D10V_R10_REGNUM:
1215 case SIM_D10V_R11_REGNUM:
1216 case SIM_D10V_R12_REGNUM:
1217 case SIM_D10V_R13_REGNUM:
1218 case SIM_D10V_R14_REGNUM:
1219 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1220 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1221 size = 2;
18c0df9e
AC
1222 break;
1223 case SIM_D10V_CR0_REGNUM:
1224 case SIM_D10V_CR1_REGNUM:
1225 case SIM_D10V_CR2_REGNUM:
1226 case SIM_D10V_CR3_REGNUM:
1227 case SIM_D10V_CR4_REGNUM:
1228 case SIM_D10V_CR5_REGNUM:
1229 case SIM_D10V_CR6_REGNUM:
1230 case SIM_D10V_CR7_REGNUM:
1231 case SIM_D10V_CR8_REGNUM:
1232 case SIM_D10V_CR9_REGNUM:
1233 case SIM_D10V_CR10_REGNUM:
1234 case SIM_D10V_CR11_REGNUM:
1235 case SIM_D10V_CR12_REGNUM:
1236 case SIM_D10V_CR13_REGNUM:
1237 case SIM_D10V_CR14_REGNUM:
1238 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1239 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1240 size = 2;
18c0df9e
AC
1241 break;
1242 case SIM_D10V_A0_REGNUM:
1243 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1244 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1245 size = 8;
18c0df9e
AC
1246 break;
1247 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1248 /* PSW_SM indicates that the current SP is the USER
1249 stack-pointer. */
1250 WRITE_16 (memory, spi_register ());
1251 size = 2;
18c0df9e
AC
1252 break;
1253 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1254 /* PSW_SM indicates that the current SP is the USER
1255 stack-pointer. */
1256 WRITE_16 (memory, spu_register ());
1257 size = 2;
18c0df9e
AC
1258 break;
1259 case SIM_D10V_IMAP0_REGNUM:
1260 case SIM_D10V_IMAP1_REGNUM:
67954606 1261 WRITE_16 (memory, imap_register (sd, cpu, NULL, rn - SIM_D10V_IMAP0_REGNUM));
4ce44c66 1262 size = 2;
18c0df9e
AC
1263 break;
1264 case SIM_D10V_DMAP0_REGNUM:
1265 case SIM_D10V_DMAP1_REGNUM:
1266 case SIM_D10V_DMAP2_REGNUM:
1267 case SIM_D10V_DMAP3_REGNUM:
67954606 1268 WRITE_16 (memory, dmap_register (sd, cpu, NULL, rn - SIM_D10V_DMAP0_REGNUM));
4ce44c66 1269 size = 2;
18c0df9e
AC
1270 break;
1271 case SIM_D10V_TS2_DMAP_REGNUM:
1272 size = 0;
1273 break;
1274 default:
1275 size = 0;
1276 break;
4ce44c66 1277 }
4ce44c66 1278 return size;
c906108c
SS
1279}
1280
e1211e55
MF
1281static int
1282d10v_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1283{
e1211e55 1284 SIM_DESC sd = CPU_STATE (cpu);
4ce44c66 1285 int size;
983b727e 1286 switch ((enum sim_d10v_regs) rn)
4ce44c66 1287 {
18c0df9e
AC
1288 case SIM_D10V_R0_REGNUM:
1289 case SIM_D10V_R1_REGNUM:
1290 case SIM_D10V_R2_REGNUM:
1291 case SIM_D10V_R3_REGNUM:
1292 case SIM_D10V_R4_REGNUM:
1293 case SIM_D10V_R5_REGNUM:
1294 case SIM_D10V_R6_REGNUM:
1295 case SIM_D10V_R7_REGNUM:
1296 case SIM_D10V_R8_REGNUM:
1297 case SIM_D10V_R9_REGNUM:
1298 case SIM_D10V_R10_REGNUM:
1299 case SIM_D10V_R11_REGNUM:
1300 case SIM_D10V_R12_REGNUM:
1301 case SIM_D10V_R13_REGNUM:
1302 case SIM_D10V_R14_REGNUM:
1303 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1304 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1305 size = 2;
18c0df9e
AC
1306 break;
1307 case SIM_D10V_CR0_REGNUM:
1308 case SIM_D10V_CR1_REGNUM:
1309 case SIM_D10V_CR2_REGNUM:
1310 case SIM_D10V_CR3_REGNUM:
1311 case SIM_D10V_CR4_REGNUM:
1312 case SIM_D10V_CR5_REGNUM:
1313 case SIM_D10V_CR6_REGNUM:
1314 case SIM_D10V_CR7_REGNUM:
1315 case SIM_D10V_CR8_REGNUM:
1316 case SIM_D10V_CR9_REGNUM:
1317 case SIM_D10V_CR10_REGNUM:
1318 case SIM_D10V_CR11_REGNUM:
1319 case SIM_D10V_CR12_REGNUM:
1320 case SIM_D10V_CR13_REGNUM:
1321 case SIM_D10V_CR14_REGNUM:
1322 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1323 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1324 size = 2;
18c0df9e
AC
1325 break;
1326 case SIM_D10V_A0_REGNUM:
1327 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1328 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1329 size = 8;
18c0df9e
AC
1330 break;
1331 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1332 /* PSW_SM indicates that the current SP is the USER
1333 stack-pointer. */
1334 set_spi_register (READ_16 (memory));
1335 size = 2;
18c0df9e
AC
1336 break;
1337 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1338 set_spu_register (READ_16 (memory));
1339 size = 2;
18c0df9e
AC
1340 break;
1341 case SIM_D10V_IMAP0_REGNUM:
1342 case SIM_D10V_IMAP1_REGNUM:
67954606 1343 set_imap_register (sd, rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
4ce44c66 1344 size = 2;
18c0df9e
AC
1345 break;
1346 case SIM_D10V_DMAP0_REGNUM:
1347 case SIM_D10V_DMAP1_REGNUM:
1348 case SIM_D10V_DMAP2_REGNUM:
1349 case SIM_D10V_DMAP3_REGNUM:
67954606 1350 set_dmap_register (sd, rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
4ce44c66 1351 size = 2;
18c0df9e
AC
1352 break;
1353 case SIM_D10V_TS2_DMAP_REGNUM:
1354 size = 0;
1355 break;
1356 default:
1357 size = 0;
1358 break;
4ce44c66 1359 }
c906108c 1360 SLOT_FLUSH ();
4ce44c66 1361 return size;
c906108c 1362}