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