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