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