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