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