]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/d10v/interp.c
sim: common: clean up asprintf includes a bit
[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
34unsigned long ins_type_counters[ (int)INS_MAX ];
35
36uint16 OP[4];
37
bdca5ee4 38static long hash (long insn, int format);
67954606 39static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint32 ins, int size);
bdca5ee4 40static void get_operands (struct simops *s, uint32 ins);
67954606
MF
41static void do_long (SIM_DESC, SIM_CPU *, uint32 ins);
42static void do_2_short (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2, enum _leftright leftright);
43static void do_parallel (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2);
bdca5ee4 44static char *add_commas (char *buf, int sizeof_buf, unsigned long value);
67954606 45static INLINE uint8 *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr);
c906108c 46
c906108c
SS
47#define MAX_HASH 63
48struct hash_entry
49{
50 struct hash_entry *next;
51 uint32 opcode;
52 uint32 mask;
53 int size;
54 struct simops *ops;
55};
56
57struct hash_entry hash_table[MAX_HASH+1];
58
59INLINE static long
11558abc 60hash (long insn, int format)
c906108c
SS
61{
62 if (format & LONG_OPCODE)
63 return ((insn & 0x3F000000) >> 24);
64 else
65 return((insn & 0x7E00) >> 9);
66}
67
68INLINE static struct hash_entry *
67954606 69lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint32 ins, int size)
c906108c
SS
70{
71 struct hash_entry *h;
72
73 if (size)
74 h = &hash_table[(ins & 0x3F000000) >> 24];
75 else
76 h = &hash_table[(ins & 0x7E00) >> 9];
77
78 while ((ins & h->mask) != h->opcode || h->size != size)
79 {
80 if (h->next == NULL)
aadc1740 81 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
c906108c
SS
82 h = h->next;
83 }
84 return (h);
85}
86
87INLINE static void
88get_operands (struct simops *s, uint32 ins)
89{
90 int i, shift, bits, flags;
91 uint32 mask;
92 for (i=0; i < s->numops; i++)
93 {
94 shift = s->operands[3*i];
95 bits = s->operands[3*i+1];
96 flags = s->operands[3*i+2];
97 mask = 0x7FFFFFFF >> (31 - bits);
98 OP[i] = (ins >> shift) & mask;
99 }
100 /* FIXME: for tracing, update values that need to be updated each
101 instruction decode cycle */
102 State.trace.psw = PSW;
103}
104
c906108c 105static void
67954606 106do_long (SIM_DESC sd, SIM_CPU *cpu, uint32 ins)
c906108c
SS
107{
108 struct hash_entry *h;
109#ifdef DEBUG
110 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f 111 sim_io_printf (sd, "do_long 0x%x\n", ins);
c906108c 112#endif
67954606 113 h = lookup_hash (sd, cpu, ins, 1);
4ce44c66
JM
114 if (h == NULL)
115 return;
c906108c
SS
116 get_operands (h->ops, ins);
117 State.ins_type = INS_LONG;
118 ins_type_counters[ (int)State.ins_type ]++;
67954606 119 (h->ops->func) (sd, cpu);
c906108c
SS
120}
121
122static void
67954606 123do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2, enum _leftright leftright)
c906108c
SS
124{
125 struct hash_entry *h;
126 enum _ins_type first, second;
127
128#ifdef DEBUG
129 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f
MF
130 sim_io_printf (sd, "do_2_short 0x%x (%s) -> 0x%x\n", ins1,
131 leftright ? "left" : "right", ins2);
c906108c
SS
132#endif
133
134 if (leftright == LEFT_FIRST)
135 {
136 first = INS_LEFT;
137 second = INS_RIGHT;
138 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
139 }
140 else
141 {
142 first = INS_RIGHT;
143 second = INS_LEFT;
144 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
145 }
146
147 /* Issue the first instruction */
67954606 148 h = lookup_hash (sd, cpu, ins1, 0);
4ce44c66
JM
149 if (h == NULL)
150 return;
c906108c
SS
151 get_operands (h->ops, ins1);
152 State.ins_type = first;
153 ins_type_counters[ (int)State.ins_type ]++;
67954606 154 (h->ops->func) (sd, cpu);
c906108c
SS
155
156 /* Issue the second instruction (if the PC hasn't changed) */
aadc1740 157 if (!State.pc_changed)
c906108c
SS
158 {
159 /* finish any existing instructions */
160 SLOT_FLUSH ();
67954606 161 h = lookup_hash (sd, cpu, ins2, 0);
4ce44c66
JM
162 if (h == NULL)
163 return;
c906108c
SS
164 get_operands (h->ops, ins2);
165 State.ins_type = second;
166 ins_type_counters[ (int)State.ins_type ]++;
167 ins_type_counters[ (int)INS_CYCLES ]++;
67954606 168 (h->ops->func) (sd, cpu);
c906108c 169 }
aadc1740 170 else
c906108c
SS
171 ins_type_counters[ (int)INS_COND_JUMP ]++;
172}
173
174static void
67954606 175do_parallel (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2)
c906108c
SS
176{
177 struct hash_entry *h1, *h2;
178#ifdef DEBUG
179 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f 180 sim_io_printf (sd, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
c906108c
SS
181#endif
182 ins_type_counters[ (int)INS_PARALLEL ]++;
67954606 183 h1 = lookup_hash (sd, cpu, ins1, 0);
4ce44c66
JM
184 if (h1 == NULL)
185 return;
67954606 186 h2 = lookup_hash (sd, cpu, ins2, 0);
4ce44c66
JM
187 if (h2 == NULL)
188 return;
c906108c
SS
189
190 if (h1->ops->exec_type == PARONLY)
191 {
192 get_operands (h1->ops, ins1);
193 State.ins_type = INS_LEFT_COND_TEST;
194 ins_type_counters[ (int)State.ins_type ]++;
67954606 195 (h1->ops->func) (sd, cpu);
c906108c
SS
196 if (State.exe)
197 {
198 ins_type_counters[ (int)INS_COND_TRUE ]++;
199 get_operands (h2->ops, ins2);
200 State.ins_type = INS_RIGHT_COND_EXE;
201 ins_type_counters[ (int)State.ins_type ]++;
67954606 202 (h2->ops->func) (sd, cpu);
c906108c
SS
203 }
204 else
205 ins_type_counters[ (int)INS_COND_FALSE ]++;
206 }
207 else if (h2->ops->exec_type == PARONLY)
208 {
209 get_operands (h2->ops, ins2);
210 State.ins_type = INS_RIGHT_COND_TEST;
211 ins_type_counters[ (int)State.ins_type ]++;
67954606 212 (h2->ops->func) (sd, cpu);
c906108c
SS
213 if (State.exe)
214 {
215 ins_type_counters[ (int)INS_COND_TRUE ]++;
216 get_operands (h1->ops, ins1);
217 State.ins_type = INS_LEFT_COND_EXE;
218 ins_type_counters[ (int)State.ins_type ]++;
67954606 219 (h1->ops->func) (sd, cpu);
c906108c
SS
220 }
221 else
222 ins_type_counters[ (int)INS_COND_FALSE ]++;
223 }
224 else
225 {
226 get_operands (h1->ops, ins1);
227 State.ins_type = INS_LEFT_PARALLEL;
228 ins_type_counters[ (int)State.ins_type ]++;
67954606 229 (h1->ops->func) (sd, cpu);
aadc1740
MF
230 get_operands (h2->ops, ins2);
231 State.ins_type = INS_RIGHT_PARALLEL;
232 ins_type_counters[ (int)State.ins_type ]++;
233 (h2->ops->func) (sd, cpu);
c906108c
SS
234 }
235}
236
237static char *
11558abc 238add_commas (char *buf, int sizeof_buf, unsigned long value)
c906108c
SS
239{
240 int comma = 3;
241 char *endbuf = buf + sizeof_buf - 1;
242
243 *--endbuf = '\0';
244 do {
245 if (comma-- == 0)
246 {
247 *--endbuf = ',';
248 comma = 2;
249 }
250
251 *--endbuf = (value % 10) + '0';
252 } while ((value /= 10) != 0);
253
254 return endbuf;
255}
256
aadc1740 257static void
11558abc 258sim_size (int power)
c906108c
SS
259{
260 int i;
4ce44c66 261 for (i = 0; i < IMEM_SEGMENTS; i++)
c906108c 262 {
4ce44c66
JM
263 if (State.mem.insn[i])
264 free (State.mem.insn[i]);
c906108c 265 }
4ce44c66 266 for (i = 0; i < DMEM_SEGMENTS; i++)
c906108c 267 {
4ce44c66
JM
268 if (State.mem.data[i])
269 free (State.mem.data[i]);
c906108c 270 }
4ce44c66
JM
271 for (i = 0; i < UMEM_SEGMENTS; i++)
272 {
273 if (State.mem.unif[i])
274 free (State.mem.unif[i]);
275 }
276 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
277 registers. */
278 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
279}
280
281/* For tracing - leave info on last access around. */
282static char *last_segname = "invalid";
283static char *last_from = "invalid";
284static char *last_to = "invalid";
285
286enum
287 {
288 IMAP0_OFFSET = 0xff00,
289 DMAP0_OFFSET = 0xff08,
290 DMAP2_SHADDOW = 0xff04,
291 DMAP2_OFFSET = 0xff0c
292 };
293
294static void
67954606 295set_dmap_register (SIM_DESC sd, int reg_nr, unsigned long value)
4ce44c66 296{
67954606 297 uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
4ce44c66
JM
298 + DMAP0_OFFSET + 2 * reg_nr);
299 WRITE_16 (raw, value);
c906108c 300#ifdef DEBUG
4ce44c66 301 if ((d10v_debug & DEBUG_MEMORY))
c906108c 302 {
e9b0081f 303 sim_io_printf (sd, "mem: dmap%d=0x%04lx\n", reg_nr, value);
4ce44c66
JM
304 }
305#endif
306}
c906108c 307
4ce44c66 308static unsigned long
67954606 309dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
4ce44c66 310{
67954606 311 uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
4ce44c66
JM
312 + DMAP0_OFFSET + 2 * reg_nr);
313 return READ_16 (raw);
314}
315
316static void
67954606 317set_imap_register (SIM_DESC sd, int reg_nr, unsigned long value)
4ce44c66 318{
67954606 319 uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
4ce44c66
JM
320 + IMAP0_OFFSET + 2 * reg_nr);
321 WRITE_16 (raw, value);
322#ifdef DEBUG
323 if ((d10v_debug & DEBUG_MEMORY))
324 {
e9b0081f 325 sim_io_printf (sd, "mem: imap%d=0x%04lx\n", reg_nr, value);
c906108c
SS
326 }
327#endif
328}
329
4ce44c66 330static unsigned long
67954606 331imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
4ce44c66 332{
67954606 333 uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
4ce44c66
JM
334 + IMAP0_OFFSET + 2 * reg_nr);
335 return READ_16 (raw);
336}
c906108c 337
4ce44c66
JM
338enum
339 {
340 HELD_SPI_IDX = 0,
341 HELD_SPU_IDX = 1
342 };
343
344static unsigned long
345spu_register (void)
c906108c 346{
4ce44c66
JM
347 if (PSW_SM)
348 return GPR (SP_IDX);
349 else
350 return HELD_SP (HELD_SPU_IDX);
351}
c906108c 352
4ce44c66
JM
353static unsigned long
354spi_register (void)
355{
356 if (!PSW_SM)
357 return GPR (SP_IDX);
358 else
359 return HELD_SP (HELD_SPI_IDX);
360}
361
362static void
363set_spi_register (unsigned long value)
364{
365 if (!PSW_SM)
366 SET_GPR (SP_IDX, value);
367 SET_HELD_SP (HELD_SPI_IDX, value);
368}
369
370static void
371set_spu_register (unsigned long value)
372{
373 if (PSW_SM)
374 SET_GPR (SP_IDX, value);
375 SET_HELD_SP (HELD_SPU_IDX, value);
376}
377
378/* Given a virtual address in the DMAP address space, translate it
379 into a physical address. */
380
6637a426 381static unsigned long
67954606
MF
382sim_d10v_translate_dmap_addr (SIM_DESC sd,
383 SIM_CPU *cpu,
384 unsigned long offset,
4ce44c66
JM
385 int nr_bytes,
386 unsigned long *phys,
f6684c31 387 void *regcache,
67954606
MF
388 unsigned long (*dmap_register) (SIM_DESC,
389 SIM_CPU *,
390 void *regcache,
f6684c31 391 int reg_nr))
4ce44c66
JM
392{
393 short map;
394 int regno;
395 last_from = "logical-data";
396 if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)
c906108c 397 {
4ce44c66
JM
398 /* Logical address out side of data segments, not supported */
399 return 0;
400 }
401 regno = (offset / DMAP_BLOCK_SIZE);
402 offset = (offset % DMAP_BLOCK_SIZE);
403 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
404 {
405 /* Don't cross a BLOCK boundary */
406 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
407 }
67954606 408 map = dmap_register (sd, cpu, regcache, regno);
4ce44c66
JM
409 if (regno == 3)
410 {
411 /* Always maps to data memory */
412 int iospi = (offset / 0x1000) % 4;
413 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
414 last_to = "io-space";
415 *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
416 }
417 else
418 {
419 int sp = ((map & 0x3000) >> 12);
420 int segno = (map & 0x3ff);
421 switch (sp)
c906108c 422 {
4ce44c66
JM
423 case 0: /* 00: Unified memory */
424 *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
425 last_to = "unified";
426 break;
427 case 1: /* 01: Instruction Memory */
428 *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
429 last_to = "chip-insn";
430 break;
431 case 2: /* 10: Internal data memory */
432 *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
433 last_to = "chip-data";
434 break;
435 case 3: /* 11: Reserved */
436 return 0;
c906108c
SS
437 }
438 }
4ce44c66
JM
439 return nr_bytes;
440}
c906108c 441
4ce44c66
JM
442/* Given a virtual address in the IMAP address space, translate it
443 into a physical address. */
cff3e48b 444
6637a426 445static unsigned long
67954606
MF
446sim_d10v_translate_imap_addr (SIM_DESC sd,
447 SIM_CPU *cpu,
448 unsigned long offset,
4ce44c66
JM
449 int nr_bytes,
450 unsigned long *phys,
f6684c31 451 void *regcache,
67954606
MF
452 unsigned long (*imap_register) (SIM_DESC,
453 SIM_CPU *,
454 void *regcache,
f6684c31 455 int reg_nr))
4ce44c66
JM
456{
457 short map;
458 int regno;
459 int sp;
460 int segno;
461 last_from = "logical-insn";
462 if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
463 {
464 /* Logical address outside of IMAP segments, not supported */
465 return 0;
466 }
467 regno = (offset / IMAP_BLOCK_SIZE);
468 offset = (offset % IMAP_BLOCK_SIZE);
469 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
470 {
471 /* Don't cross a BLOCK boundary */
472 nr_bytes = IMAP_BLOCK_SIZE - offset;
473 }
67954606 474 map = imap_register (sd, cpu, regcache, regno);
4ce44c66
JM
475 sp = (map & 0x3000) >> 12;
476 segno = (map & 0x007f);
477 switch (sp)
478 {
479 case 0: /* 00: unified memory */
480 *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
481 last_to = "unified";
482 break;
483 case 1: /* 01: instruction memory */
484 *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
485 last_to = "chip-insn";
486 break;
487 case 2: /*10*/
488 /* Reserved. */
489 return 0;
490 case 3: /* 11: for testing - instruction memory */
491 offset = (offset % 0x800);
492 *phys = SIM_D10V_MEMORY_INSN + offset;
493 if (offset + nr_bytes > 0x800)
494 /* don't cross VM boundary */
495 nr_bytes = 0x800 - offset;
496 last_to = "test-insn";
497 break;
498 }
499 return nr_bytes;
500}
cff3e48b 501
6637a426 502static unsigned long
67954606
MF
503sim_d10v_translate_addr (SIM_DESC sd,
504 SIM_CPU *cpu,
505 unsigned long memaddr,
4ce44c66
JM
506 int nr_bytes,
507 unsigned long *targ_addr,
f6684c31 508 void *regcache,
67954606
MF
509 unsigned long (*dmap_register) (SIM_DESC,
510 SIM_CPU *,
511 void *regcache,
f6684c31 512 int reg_nr),
67954606
MF
513 unsigned long (*imap_register) (SIM_DESC,
514 SIM_CPU *,
515 void *regcache,
f6684c31 516 int reg_nr))
4ce44c66
JM
517{
518 unsigned long phys;
519 unsigned long seg;
520 unsigned long off;
cff3e48b 521
4ce44c66
JM
522 last_from = "unknown";
523 last_to = "unknown";
cff3e48b 524
4ce44c66
JM
525 seg = (memaddr >> 24);
526 off = (memaddr & 0xffffffL);
c906108c 527
cff3e48b
JM
528 /* However, if we've asked to use the previous generation of segment
529 mapping, rearrange the segments as follows. */
530
531 if (old_segment_mapping)
532 {
4ce44c66 533 switch (seg)
cff3e48b
JM
534 {
535 case 0x00: /* DMAP translated memory */
4ce44c66 536 seg = 0x10;
cff3e48b
JM
537 break;
538 case 0x01: /* IMAP translated memory */
4ce44c66 539 seg = 0x11;
cff3e48b
JM
540 break;
541 case 0x10: /* On-chip data memory */
4ce44c66 542 seg = 0x02;
cff3e48b
JM
543 break;
544 case 0x11: /* On-chip insn memory */
4ce44c66 545 seg = 0x01;
cff3e48b
JM
546 break;
547 case 0x12: /* Unified memory */
4ce44c66 548 seg = 0x00;
cff3e48b
JM
549 break;
550 }
551 }
552
4ce44c66 553 switch (seg)
c906108c 554 {
4ce44c66
JM
555 case 0x00: /* Physical unified memory */
556 last_from = "phys-unified";
557 last_to = "unified";
558 phys = SIM_D10V_MEMORY_UNIFIED + off;
559 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
560 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
561 break;
c906108c 562
4ce44c66
JM
563 case 0x01: /* Physical instruction memory */
564 last_from = "phys-insn";
565 last_to = "chip-insn";
566 phys = SIM_D10V_MEMORY_INSN + off;
567 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
568 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
569 break;
c906108c 570
4ce44c66
JM
571 case 0x02: /* Physical data memory segment */
572 last_from = "phys-data";
573 last_to = "chip-data";
574 phys = SIM_D10V_MEMORY_DATA + off;
575 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
576 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
577 break;
578
579 case 0x10: /* in logical data address segment */
67954606
MF
580 nr_bytes = sim_d10v_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys,
581 regcache, dmap_register);
4ce44c66
JM
582 break;
583
584 case 0x11: /* in logical instruction address segment */
67954606
MF
585 nr_bytes = sim_d10v_translate_imap_addr (sd, cpu, off, nr_bytes, &phys,
586 regcache, imap_register);
4ce44c66
JM
587 break;
588
589 default:
590 return 0;
591 }
592
593 *targ_addr = phys;
594 return nr_bytes;
595}
596
597/* Return a pointer into the raw buffer designated by phys_addr. It
598 is assumed that the client has already ensured that the access
599 isn't going to cross a segment boundary. */
600
601uint8 *
67954606 602map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
4ce44c66
JM
603{
604 uint8 **memory;
605 uint8 *raw;
606 unsigned offset;
607 int segment = ((phys_addr >> 24) & 0xff);
608
609 switch (segment)
610 {
611
612 case 0x00: /* Unified memory */
c906108c 613 {
4ce44c66
JM
614 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
615 last_segname = "umem";
c906108c
SS
616 break;
617 }
4ce44c66 618
cff3e48b 619 case 0x01: /* On-chip insn memory */
c906108c 620 {
4ce44c66
JM
621 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
622 last_segname = "imem";
c906108c
SS
623 break;
624 }
4ce44c66
JM
625
626 case 0x02: /* On-chip data memory */
c906108c 627 {
4ce44c66 628 if ((phys_addr & 0xff00) == 0xff00)
c906108c 629 {
4ce44c66
JM
630 phys_addr = (phys_addr & 0xffff);
631 if (phys_addr == DMAP2_SHADDOW)
c906108c 632 {
4ce44c66
JM
633 phys_addr = DMAP2_OFFSET;
634 last_segname = "dmap";
c906108c 635 }
4ce44c66
JM
636 else
637 last_segname = "reg";
c906108c 638 }
4ce44c66
JM
639 else
640 last_segname = "dmem";
641 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
c906108c
SS
642 break;
643 }
4ce44c66 644
c906108c 645 default:
4ce44c66
JM
646 /* OOPS! */
647 last_segname = "scrap";
aadc1740 648 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
c906108c 649 }
4ce44c66
JM
650
651 if (*memory == NULL)
aadc1740 652 *memory = xcalloc (1, SEGMENT_SIZE);
4ce44c66
JM
653
654 offset = (phys_addr % SEGMENT_SIZE);
655 raw = *memory + offset;
656 return raw;
657}
658
659/* Transfer data to/from simulated memory. Since a bug in either the
660 simulated program or in gdb or the simulator itself may cause a
661 bogus address to be passed in, we need to do some sanity checking
662 on addresses to make sure they are within bounds. When an address
663 fails the bounds check, treat it as a zero length read/write rather
664 than aborting the entire run. */
665
666static int
67954606
MF
667xfer_mem (SIM_DESC sd,
668 SIM_ADDR virt,
4ce44c66
JM
669 unsigned char *buffer,
670 int size,
671 int write_p)
672{
ea086965
AC
673 uint8 *memory;
674 unsigned long phys;
675 int phys_size;
67954606 676 phys_size = sim_d10v_translate_addr (sd, NULL, virt, size, &phys, NULL,
ea086965
AC
677 dmap_register, imap_register);
678 if (phys_size == 0)
679 return 0;
4ce44c66 680
67954606 681 memory = map_memory (sd, NULL, phys);
4ce44c66
JM
682
683#ifdef DEBUG
ea086965
AC
684 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
685 {
e9b0081f
MF
686 sim_io_printf
687 (sd,
ea086965 688 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
e9b0081f 689 write_p ? "write" : "read",
ea086965
AC
690 phys_size, virt, last_from,
691 phys, last_to,
692 (long) memory, last_segname);
693 }
4ce44c66
JM
694#endif
695
ea086965
AC
696 if (write_p)
697 {
698 memcpy (memory, buffer, phys_size);
c906108c 699 }
ea086965
AC
700 else
701 {
702 memcpy (buffer, memory, phys_size);
703 }
704
705 return phys_size;
c906108c
SS
706}
707
708
709int
11558abc 710sim_write (SIM_DESC sd, SIM_ADDR addr, const 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, 1);
c906108c
SS
714}
715
716int
11558abc 717sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c
SS
718{
719 /* FIXME: this should be performing a virtual transfer */
67954606 720 return xfer_mem (sd, addr, buffer, size, 0);
c906108c
SS
721}
722
27b97b40
MF
723static sim_cia
724d10v_pc_get (sim_cpu *cpu)
725{
726 return PC;
727}
728
729static void
730d10v_pc_set (sim_cpu *cpu, sim_cia pc)
731{
67954606 732 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
733 SET_PC (pc);
734}
735
541ebcee
MF
736static void
737free_state (SIM_DESC sd)
738{
739 if (STATE_MODULES (sd) != NULL)
740 sim_module_uninstall (sd);
741 sim_cpu_free_all (sd);
742 sim_state_free (sd);
743}
744
e1211e55
MF
745static int d10v_reg_fetch (SIM_CPU *, int, unsigned char *, int);
746static int d10v_reg_store (SIM_CPU *, int, unsigned char *, int);
747
c906108c 748SIM_DESC
2e3d4f4d
MF
749sim_open (SIM_OPEN_KIND kind, host_callback *cb,
750 struct bfd *abfd, char * const *argv)
c906108c
SS
751{
752 struct simops *s;
753 struct hash_entry *h;
754 static int init_p = 0;
755 char **p;
27b97b40 756 int i;
541ebcee
MF
757 SIM_DESC sd = sim_state_alloc (kind, cb);
758 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
c906108c 759
541ebcee
MF
760 /* The cpu data is kept in a separately allocated chunk of memory. */
761 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
762 {
763 free_state (sd);
764 return 0;
765 }
766
767 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
768 {
769 free_state (sd);
770 return 0;
771 }
772
77cf2ef5 773 /* The parser will print an error message for us, so we silently return. */
541ebcee
MF
774 if (sim_parse_args (sd, argv) != SIM_RC_OK)
775 {
776 free_state (sd);
777 return 0;
778 }
779
780 /* Check for/establish the a reference program image. */
781 if (sim_analyze_program (sd,
782 (STATE_PROG_ARGV (sd) != NULL
783 ? *STATE_PROG_ARGV (sd)
784 : NULL), abfd) != SIM_RC_OK)
785 {
786 free_state (sd);
787 return 0;
788 }
789
790 /* Configure/verify the target byte order and other runtime
791 configuration options. */
792 if (sim_config (sd) != SIM_RC_OK)
793 {
794 sim_module_uninstall (sd);
795 return 0;
796 }
797
798 if (sim_post_argv_init (sd) != SIM_RC_OK)
799 {
800 /* Uninstall the modules to avoid memory leaks,
801 file descriptor leaks, etc. */
802 sim_module_uninstall (sd);
803 return 0;
804 }
805
27b97b40
MF
806 /* CPU specific initialization. */
807 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
808 {
809 SIM_CPU *cpu = STATE_CPU (sd, i);
810
e1211e55
MF
811 CPU_REG_FETCH (cpu) = d10v_reg_fetch;
812 CPU_REG_STORE (cpu) = d10v_reg_store;
27b97b40
MF
813 CPU_PC_FETCH (cpu) = d10v_pc_get;
814 CPU_PC_STORE (cpu) = d10v_pc_set;
815 }
816
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 863
541ebcee 864 return sd;
c906108c
SS
865}
866
c906108c 867uint8 *
67954606 868dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16 offset)
c906108c 869{
4ce44c66
JM
870 unsigned long phys;
871 uint8 *mem;
872 int phys_size;
c906108c 873
4ce44c66
JM
874 /* Note: DMEM address range is 0..0x10000. Calling code can compute
875 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
876 is uint16 this is modulo'ed onto 0x0e5d. */
c906108c 877
67954606 878 phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
4ce44c66
JM
879 dmap_register);
880 if (phys_size == 0)
aadc1740
MF
881 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
882 mem = map_memory (sd, cpu, phys);
c906108c 883#ifdef DEBUG
4ce44c66
JM
884 if ((d10v_debug & DEBUG_MEMORY))
885 {
e9b0081f
MF
886 sim_io_printf
887 (sd,
4ce44c66
JM
888 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
889 offset, last_from,
890 phys, phys_size, last_to,
891 (long) mem, last_segname);
c906108c 892 }
4ce44c66
JM
893#endif
894 return mem;
c906108c
SS
895}
896
c906108c 897uint8 *
67954606 898imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
c906108c 899{
4ce44c66
JM
900 unsigned long phys;
901 uint8 *mem;
67954606 902 int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
f6684c31 903 imap_register);
4ce44c66 904 if (phys_size == 0)
aadc1740 905 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
67954606 906 mem = map_memory (sd, cpu, phys);
4ce44c66
JM
907#ifdef DEBUG
908 if ((d10v_debug & DEBUG_MEMORY))
909 {
e9b0081f
MF
910 sim_io_printf
911 (sd,
4ce44c66
JM
912 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
913 offset, last_from,
914 phys, phys_size, last_to,
915 (long) mem, last_segname);
916 }
917#endif
918 return mem;
c906108c
SS
919}
920
aadc1740
MF
921static void
922step_once (SIM_DESC sd, SIM_CPU *cpu)
c906108c
SS
923{
924 uint32 inst;
925 uint8 *iaddr;
926
aadc1740 927 /* TODO: Unindent this block. */
c906108c 928 {
67954606 929 iaddr = imem_addr (sd, cpu, (uint32)PC << 2);
c906108c
SS
930
931 inst = get_longword( iaddr );
932
933 State.pc_changed = 0;
934 ins_type_counters[ (int)INS_CYCLES ]++;
935
936 switch (inst & 0xC0000000)
937 {
938 case 0xC0000000:
939 /* long instruction */
67954606 940 do_long (sd, cpu, inst & 0x3FFFFFFF);
c906108c
SS
941 break;
942 case 0x80000000:
943 /* R -> L */
67954606 944 do_2_short (sd, cpu, inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
c906108c
SS
945 break;
946 case 0x40000000:
947 /* L -> R */
67954606 948 do_2_short (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
c906108c
SS
949 break;
950 case 0:
67954606 951 do_parallel (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
c906108c
SS
952 break;
953 }
954
955 /* If the PC of the current instruction matches RPT_E then
956 schedule a branch to the loop start. If one of those
957 instructions happens to be a branch, than that instruction
958 will be ignored */
959 if (!State.pc_changed)
960 {
961 if (PSW_RP && PC == RPT_E)
962 {
963 /* Note: The behavour of a branch instruction at RPT_E
964 is implementation dependant, this simulator takes the
965 branch. Branching to RPT_E is valid, the instruction
966 must be executed before the loop is taken. */
967 if (RPT_C == 1)
968 {
969 SET_PSW_RP (0);
970 SET_RPT_C (0);
971 SET_PC (PC + 1);
972 }
973 else
974 {
975 SET_RPT_C (RPT_C - 1);
976 SET_PC (RPT_S);
977 }
978 }
979 else
980 SET_PC (PC + 1);
981 }
982
983 /* Check for a breakpoint trap on this instruction. This
984 overrides any pending branches or loops */
985 if (PSW_DB && PC == IBA)
986 {
987 SET_BPC (PC);
988 SET_BPSW (PSW);
989 SET_PSW (PSW & PSW_SM_BIT);
990 SET_PC (SDBT_VECTOR_START);
991 }
992
993 /* Writeback all the DATA / PC changes */
994 SLOT_FLUSH ();
c906108c 995 }
aadc1740
MF
996}
997
998void
999sim_engine_run (SIM_DESC sd,
1000 int next_cpu_nr, /* ignore */
1001 int nr_cpus, /* ignore */
1002 int siggnal)
1003{
1004 sim_cpu *cpu;
1005
1006 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1007
1008 cpu = STATE_CPU (sd, 0);
1009
1010 switch (siggnal)
1011 {
1012 case 0:
1013 break;
1014 case GDB_SIGNAL_BUS:
1015 SET_BPC (PC);
1016 SET_BPSW (PSW);
1017 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1018 JMP (AE_VECTOR_START);
1019 SLOT_FLUSH ();
1020 break;
1021 case GDB_SIGNAL_ILL:
1022 SET_BPC (PC);
1023 SET_BPSW (PSW);
1024 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1025 JMP (RIE_VECTOR_START);
1026 SLOT_FLUSH ();
1027 break;
1028 default:
1029 /* just ignore it */
1030 break;
1031 }
1032
1033 while (1)
1034 {
1035 step_once (sd, cpu);
1036 if (sim_events_tick (sd))
1037 sim_events_process (sd);
1038 }
c906108c
SS
1039}
1040
c906108c 1041void
11558abc 1042sim_info (SIM_DESC sd, int verbose)
c906108c
SS
1043{
1044 char buf1[40];
1045 char buf2[40];
1046 char buf3[40];
1047 char buf4[40];
1048 char buf5[40];
1049 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1050 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1051 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1052 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1053 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1054
1055 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1056 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1057 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1058 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1059 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1060
1061 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1062 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1063 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1064 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1065 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1066 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1067 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1068 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1069 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1070 unsigned long total = (unknown + left_total + right_total + ins_long);
1071
1072 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1073 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1074 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1075 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1076 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1077 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1078
e9b0081f
MF
1079 sim_io_printf (sd,
1080 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1081 size, add_commas (buf1, sizeof (buf1), left_total),
1082 normal_size, add_commas (buf2, sizeof (buf2), left),
1083 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1084 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1085 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1086
1087 sim_io_printf (sd,
1088 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1089 size, add_commas (buf1, sizeof (buf1), right_total),
1090 normal_size, add_commas (buf2, sizeof (buf2), right),
1091 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1092 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1093 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
c906108c
SS
1094
1095 if (ins_long)
e9b0081f
MF
1096 sim_io_printf (sd,
1097 "executed %*s long instruction(s)\n",
1098 size, add_commas (buf1, sizeof (buf1), ins_long));
c906108c
SS
1099
1100 if (parallel)
e9b0081f
MF
1101 sim_io_printf (sd,
1102 "executed %*s parallel instruction(s)\n",
1103 size, add_commas (buf1, sizeof (buf1), parallel));
c906108c
SS
1104
1105 if (leftright)
e9b0081f
MF
1106 sim_io_printf (sd,
1107 "executed %*s instruction(s) encoded L->R\n",
1108 size, add_commas (buf1, sizeof (buf1), leftright));
c906108c
SS
1109
1110 if (rightleft)
e9b0081f
MF
1111 sim_io_printf (sd,
1112 "executed %*s instruction(s) encoded R->L\n",
1113 size, add_commas (buf1, sizeof (buf1), rightleft));
c906108c
SS
1114
1115 if (unknown)
e9b0081f
MF
1116 sim_io_printf (sd,
1117 "executed %*s unknown instruction(s)\n",
1118 size, add_commas (buf1, sizeof (buf1), unknown));
c906108c
SS
1119
1120 if (cond_true)
e9b0081f
MF
1121 sim_io_printf (sd,
1122 "executed %*s instruction(s) due to EXExxx condition being true\n",
1123 size, add_commas (buf1, sizeof (buf1), cond_true));
c906108c
SS
1124
1125 if (cond_false)
e9b0081f
MF
1126 sim_io_printf (sd,
1127 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1128 size, add_commas (buf1, sizeof (buf1), cond_false));
c906108c
SS
1129
1130 if (cond_jump)
e9b0081f
MF
1131 sim_io_printf (sd,
1132 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1133 size, add_commas (buf1, sizeof (buf1), cond_jump));
c906108c 1134
e9b0081f
MF
1135 sim_io_printf (sd,
1136 "executed %*s cycle(s)\n",
1137 size, add_commas (buf1, sizeof (buf1), cycles));
c906108c 1138
e9b0081f
MF
1139 sim_io_printf (sd,
1140 "executed %*s total instructions\n",
1141 size, add_commas (buf1, sizeof (buf1), total));
c906108c
SS
1142}
1143
1144SIM_RC
2e3d4f4d
MF
1145sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1146 char * const *argv, char * const *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)
e9b0081f 1168 sim_io_printf (sd, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
c906108c 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
e1211e55
MF
1204static int
1205d10v_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1206{
e1211e55 1207 SIM_DESC sd = CPU_STATE (cpu);
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
e1211e55
MF
1288static int
1289d10v_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1290{
e1211e55 1291 SIM_DESC sd = CPU_STATE (cpu);
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}