Automatic date update in version.in
[binutils-gdb.git] / sim / d10v / interp.c
blobf105e4fb90364770b56b53c248db3631c7437737
1 /* This must come before any other includes. */
2 #include "defs.h"
4 #include <inttypes.h>
5 #include <signal.h>
6 #include "bfd.h"
7 #include "sim/callback.h"
8 #include "sim/sim.h"
10 #include "sim-main.h"
11 #include "sim-options.h"
12 #include "sim-signal.h"
14 #include "sim/sim-d10v.h"
15 #include "gdb/signals.h"
17 #include <string.h>
18 #include <stdlib.h>
19 #include <assert.h>
21 #include "d10v-sim.h"
23 #include "target-newlib-syscall.h"
25 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
27 struct _state State;
29 int d10v_debug;
31 /* Set this to true to get the previous segment layout. */
33 int old_segment_mapping;
35 unsigned long ins_type_counters[ (int)INS_MAX ];
37 uint16_t OP[4];
39 static long hash (long insn, int format);
40 static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint32_t ins, int size);
41 static void get_operands (struct simops *s, uint32_t ins);
42 static void do_long (SIM_DESC, SIM_CPU *, uint32_t ins);
43 static void do_2_short (SIM_DESC, SIM_CPU *, uint16_t ins1, uint16_t ins2, enum _leftright leftright);
44 static void do_parallel (SIM_DESC, SIM_CPU *, uint16_t ins1, uint16_t ins2);
45 static char *add_commas (char *buf, int sizeof_buf, unsigned long value);
46 static INLINE uint8_t *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr);
48 #define MAX_HASH 63
49 struct hash_entry
51 struct hash_entry *next;
52 uint32_t opcode;
53 uint32_t mask;
54 int size;
55 struct simops *ops;
58 struct hash_entry hash_table[MAX_HASH+1];
60 INLINE static long
61 hash (long insn, int format)
63 if (format & LONG_OPCODE)
64 return ((insn & 0x3F000000) >> 24);
65 else
66 return((insn & 0x7E00) >> 9);
69 INLINE static struct hash_entry *
70 lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint32_t ins, int size)
72 struct hash_entry *h;
74 if (size)
75 h = &hash_table[(ins & 0x3F000000) >> 24];
76 else
77 h = &hash_table[(ins & 0x7E00) >> 9];
79 while ((ins & h->mask) != h->opcode || h->size != size)
81 if (h->next == NULL)
82 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
83 h = h->next;
85 return (h);
88 INLINE static void
89 get_operands (struct simops *s, uint32_t ins)
91 int i, shift, bits;
92 uint32_t mask;
93 for (i=0; i < s->numops; i++)
95 shift = s->operands[3*i];
96 bits = s->operands[3*i+1];
97 /* flags = s->operands[3*i+2]; */
98 mask = 0x7FFFFFFF >> (31 - bits);
99 OP[i] = (ins >> shift) & mask;
101 /* FIXME: for tracing, update values that need to be updated each
102 instruction decode cycle */
103 State.trace.psw = PSW;
106 static void
107 do_long (SIM_DESC sd, SIM_CPU *cpu, uint32_t ins)
109 struct hash_entry *h;
110 #ifdef DEBUG
111 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
112 sim_io_printf (sd, "do_long 0x%x\n", ins);
113 #endif
114 h = lookup_hash (sd, cpu, ins, 1);
115 if (h == NULL)
116 return;
117 get_operands (h->ops, ins);
118 State.ins_type = INS_LONG;
119 ins_type_counters[ (int)State.ins_type ]++;
120 (h->ops->func) (sd, cpu);
123 static void
124 do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16_t ins1, uint16_t ins2, enum _leftright leftright)
126 struct hash_entry *h;
127 enum _ins_type first, second;
129 #ifdef DEBUG
130 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
131 sim_io_printf (sd, "do_2_short 0x%x (%s) -> 0x%x\n", ins1,
132 leftright ? "left" : "right", ins2);
133 #endif
135 if (leftright == LEFT_FIRST)
137 first = INS_LEFT;
138 second = INS_RIGHT;
139 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
141 else
143 first = INS_RIGHT;
144 second = INS_LEFT;
145 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
148 /* Issue the first instruction */
149 h = lookup_hash (sd, cpu, ins1, 0);
150 if (h == NULL)
151 return;
152 get_operands (h->ops, ins1);
153 State.ins_type = first;
154 ins_type_counters[ (int)State.ins_type ]++;
155 (h->ops->func) (sd, cpu);
157 /* Issue the second instruction (if the PC hasn't changed) */
158 if (!State.pc_changed)
160 /* finish any existing instructions */
161 SLOT_FLUSH ();
162 h = lookup_hash (sd, cpu, ins2, 0);
163 if (h == NULL)
164 return;
165 get_operands (h->ops, ins2);
166 State.ins_type = second;
167 ins_type_counters[ (int)State.ins_type ]++;
168 ins_type_counters[ (int)INS_CYCLES ]++;
169 (h->ops->func) (sd, cpu);
171 else
172 ins_type_counters[ (int)INS_COND_JUMP ]++;
175 static void
176 do_parallel (SIM_DESC sd, SIM_CPU *cpu, uint16_t ins1, uint16_t ins2)
178 struct hash_entry *h1, *h2;
179 #ifdef DEBUG
180 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
181 sim_io_printf (sd, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
182 #endif
183 ins_type_counters[ (int)INS_PARALLEL ]++;
184 h1 = lookup_hash (sd, cpu, ins1, 0);
185 if (h1 == NULL)
186 return;
187 h2 = lookup_hash (sd, cpu, ins2, 0);
188 if (h2 == NULL)
189 return;
191 if (h1->ops->exec_type == PARONLY)
193 get_operands (h1->ops, ins1);
194 State.ins_type = INS_LEFT_COND_TEST;
195 ins_type_counters[ (int)State.ins_type ]++;
196 (h1->ops->func) (sd, cpu);
197 if (State.exe)
199 ins_type_counters[ (int)INS_COND_TRUE ]++;
200 get_operands (h2->ops, ins2);
201 State.ins_type = INS_RIGHT_COND_EXE;
202 ins_type_counters[ (int)State.ins_type ]++;
203 (h2->ops->func) (sd, cpu);
205 else
206 ins_type_counters[ (int)INS_COND_FALSE ]++;
208 else if (h2->ops->exec_type == PARONLY)
210 get_operands (h2->ops, ins2);
211 State.ins_type = INS_RIGHT_COND_TEST;
212 ins_type_counters[ (int)State.ins_type ]++;
213 (h2->ops->func) (sd, cpu);
214 if (State.exe)
216 ins_type_counters[ (int)INS_COND_TRUE ]++;
217 get_operands (h1->ops, ins1);
218 State.ins_type = INS_LEFT_COND_EXE;
219 ins_type_counters[ (int)State.ins_type ]++;
220 (h1->ops->func) (sd, cpu);
222 else
223 ins_type_counters[ (int)INS_COND_FALSE ]++;
225 else
227 get_operands (h1->ops, ins1);
228 State.ins_type = INS_LEFT_PARALLEL;
229 ins_type_counters[ (int)State.ins_type ]++;
230 (h1->ops->func) (sd, cpu);
231 get_operands (h2->ops, ins2);
232 State.ins_type = INS_RIGHT_PARALLEL;
233 ins_type_counters[ (int)State.ins_type ]++;
234 (h2->ops->func) (sd, cpu);
238 static char *
239 add_commas (char *buf, int sizeof_buf, unsigned long value)
241 int comma = 3;
242 char *endbuf = buf + sizeof_buf - 1;
244 *--endbuf = '\0';
245 do {
246 if (comma-- == 0)
248 *--endbuf = ',';
249 comma = 2;
252 *--endbuf = (value % 10) + '0';
253 } while ((value /= 10) != 0);
255 return endbuf;
258 static void
259 sim_size (int power)
261 int i;
262 for (i = 0; i < IMEM_SEGMENTS; i++)
264 if (State.mem.insn[i])
265 free (State.mem.insn[i]);
267 for (i = 0; i < DMEM_SEGMENTS; i++)
269 if (State.mem.data[i])
270 free (State.mem.data[i]);
272 for (i = 0; i < UMEM_SEGMENTS; i++)
274 if (State.mem.unif[i])
275 free (State.mem.unif[i]);
277 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
278 registers. */
279 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
282 /* For tracing - leave info on last access around. */
283 static char *last_segname = "invalid";
284 static char *last_from = "invalid";
285 static char *last_to = "invalid";
287 enum
289 IMAP0_OFFSET = 0xff00,
290 DMAP0_OFFSET = 0xff08,
291 DMAP2_SHADDOW = 0xff04,
292 DMAP2_OFFSET = 0xff0c
295 static void
296 set_dmap_register (SIM_DESC sd, int reg_nr, unsigned long value)
298 uint8_t *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
299 + DMAP0_OFFSET + 2 * reg_nr);
300 WRITE_16 (raw, value);
301 #ifdef DEBUG
302 if ((d10v_debug & DEBUG_MEMORY))
304 sim_io_printf (sd, "mem: dmap%d=0x%04lx\n", reg_nr, value);
306 #endif
309 static unsigned long
310 dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
312 uint8_t *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
313 + DMAP0_OFFSET + 2 * reg_nr);
314 return READ_16 (raw);
317 static void
318 set_imap_register (SIM_DESC sd, int reg_nr, unsigned long value)
320 uint8_t *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
321 + IMAP0_OFFSET + 2 * reg_nr);
322 WRITE_16 (raw, value);
323 #ifdef DEBUG
324 if ((d10v_debug & DEBUG_MEMORY))
326 sim_io_printf (sd, "mem: imap%d=0x%04lx\n", reg_nr, value);
328 #endif
331 static unsigned long
332 imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
334 uint8_t *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
335 + IMAP0_OFFSET + 2 * reg_nr);
336 return READ_16 (raw);
339 enum
341 HELD_SPI_IDX = 0,
342 HELD_SPU_IDX = 1
345 static unsigned long
346 spu_register (void)
348 if (PSW_SM)
349 return GPR (SP_IDX);
350 else
351 return HELD_SP (HELD_SPU_IDX);
354 static unsigned long
355 spi_register (void)
357 if (!PSW_SM)
358 return GPR (SP_IDX);
359 else
360 return HELD_SP (HELD_SPI_IDX);
363 static void
364 set_spi_register (unsigned long value)
366 if (!PSW_SM)
367 SET_GPR (SP_IDX, value);
368 SET_HELD_SP (HELD_SPI_IDX, value);
371 static void
372 set_spu_register (unsigned long value)
374 if (PSW_SM)
375 SET_GPR (SP_IDX, value);
376 SET_HELD_SP (HELD_SPU_IDX, value);
379 /* Given a virtual address in the DMAP address space, translate it
380 into a physical address. */
382 static unsigned long
383 sim_d10v_translate_dmap_addr (SIM_DESC sd,
384 SIM_CPU *cpu,
385 unsigned long offset,
386 int nr_bytes,
387 unsigned long *phys,
388 void *regcache,
389 unsigned long (*dmap_register) (SIM_DESC,
390 SIM_CPU *,
391 void *regcache,
392 int reg_nr))
394 short map;
395 int regno;
396 last_from = "logical-data";
397 if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)
399 /* Logical address out side of data segments, not supported */
400 return 0;
402 regno = (offset / DMAP_BLOCK_SIZE);
403 offset = (offset % DMAP_BLOCK_SIZE);
404 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
406 /* Don't cross a BLOCK boundary */
407 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
409 map = dmap_register (sd, cpu, regcache, regno);
410 if (regno == 3)
412 /* Always maps to data memory */
413 int iospi = (offset / 0x1000) % 4;
414 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
415 last_to = "io-space";
416 *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
418 else
420 int sp = ((map & 0x3000) >> 12);
421 int segno = (map & 0x3ff);
422 switch (sp)
424 case 0: /* 00: Unified memory */
425 *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
426 last_to = "unified";
427 break;
428 case 1: /* 01: Instruction Memory */
429 *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
430 last_to = "chip-insn";
431 break;
432 case 2: /* 10: Internal data memory */
433 *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
434 last_to = "chip-data";
435 break;
436 case 3: /* 11: Reserved */
437 return 0;
440 return nr_bytes;
443 /* Given a virtual address in the IMAP address space, translate it
444 into a physical address. */
446 static unsigned long
447 sim_d10v_translate_imap_addr (SIM_DESC sd,
448 SIM_CPU *cpu,
449 unsigned long offset,
450 int nr_bytes,
451 unsigned long *phys,
452 void *regcache,
453 unsigned long (*imap_register) (SIM_DESC,
454 SIM_CPU *,
455 void *regcache,
456 int reg_nr))
458 short map;
459 int regno;
460 int sp;
461 int segno;
462 last_from = "logical-insn";
463 if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
465 /* Logical address outside of IMAP segments, not supported */
466 return 0;
468 regno = (offset / IMAP_BLOCK_SIZE);
469 offset = (offset % IMAP_BLOCK_SIZE);
470 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
472 /* Don't cross a BLOCK boundary */
473 nr_bytes = IMAP_BLOCK_SIZE - offset;
475 map = imap_register (sd, cpu, regcache, regno);
476 sp = (map & 0x3000) >> 12;
477 segno = (map & 0x007f);
478 switch (sp)
480 case 0: /* 00: unified memory */
481 *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
482 last_to = "unified";
483 break;
484 case 1: /* 01: instruction memory */
485 *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
486 last_to = "chip-insn";
487 break;
488 case 2: /*10*/
489 /* Reserved. */
490 return 0;
491 case 3: /* 11: for testing - instruction memory */
492 offset = (offset % 0x800);
493 *phys = SIM_D10V_MEMORY_INSN + offset;
494 if (offset + nr_bytes > 0x800)
495 /* don't cross VM boundary */
496 nr_bytes = 0x800 - offset;
497 last_to = "test-insn";
498 break;
500 return nr_bytes;
503 static unsigned long
504 sim_d10v_translate_addr (SIM_DESC sd,
505 SIM_CPU *cpu,
506 unsigned long memaddr,
507 int nr_bytes,
508 unsigned long *targ_addr,
509 void *regcache,
510 unsigned long (*dmap_register) (SIM_DESC,
511 SIM_CPU *,
512 void *regcache,
513 int reg_nr),
514 unsigned long (*imap_register) (SIM_DESC,
515 SIM_CPU *,
516 void *regcache,
517 int reg_nr))
519 unsigned long phys;
520 unsigned long seg;
521 unsigned long off;
523 last_from = "unknown";
524 last_to = "unknown";
526 seg = (memaddr >> 24);
527 off = (memaddr & 0xffffffL);
529 /* However, if we've asked to use the previous generation of segment
530 mapping, rearrange the segments as follows. */
532 if (old_segment_mapping)
534 switch (seg)
536 case 0x00: /* DMAP translated memory */
537 seg = 0x10;
538 break;
539 case 0x01: /* IMAP translated memory */
540 seg = 0x11;
541 break;
542 case 0x10: /* On-chip data memory */
543 seg = 0x02;
544 break;
545 case 0x11: /* On-chip insn memory */
546 seg = 0x01;
547 break;
548 case 0x12: /* Unified memory */
549 seg = 0x00;
550 break;
554 switch (seg)
556 case 0x00: /* Physical unified memory */
557 last_from = "phys-unified";
558 last_to = "unified";
559 phys = SIM_D10V_MEMORY_UNIFIED + off;
560 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
561 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
562 break;
564 case 0x01: /* Physical instruction memory */
565 last_from = "phys-insn";
566 last_to = "chip-insn";
567 phys = SIM_D10V_MEMORY_INSN + off;
568 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
569 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
570 break;
572 case 0x02: /* Physical data memory segment */
573 last_from = "phys-data";
574 last_to = "chip-data";
575 phys = SIM_D10V_MEMORY_DATA + off;
576 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
577 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
578 break;
580 case 0x10: /* in logical data address segment */
581 nr_bytes = sim_d10v_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys,
582 regcache, dmap_register);
583 break;
585 case 0x11: /* in logical instruction address segment */
586 nr_bytes = sim_d10v_translate_imap_addr (sd, cpu, off, nr_bytes, &phys,
587 regcache, imap_register);
588 break;
590 default:
591 return 0;
594 *targ_addr = phys;
595 return nr_bytes;
598 /* Return a pointer into the raw buffer designated by phys_addr. It
599 is assumed that the client has already ensured that the access
600 isn't going to cross a segment boundary. */
602 uint8_t *
603 map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
605 uint8_t **memory;
606 uint8_t *raw;
607 unsigned offset;
608 int segment = ((phys_addr >> 24) & 0xff);
610 switch (segment)
613 case 0x00: /* Unified memory */
615 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
616 last_segname = "umem";
617 break;
620 case 0x01: /* On-chip insn memory */
622 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
623 last_segname = "imem";
624 break;
627 case 0x02: /* On-chip data memory */
629 if ((phys_addr & 0xff00) == 0xff00)
631 phys_addr = (phys_addr & 0xffff);
632 if (phys_addr == DMAP2_SHADDOW)
634 phys_addr = DMAP2_OFFSET;
635 last_segname = "dmap";
637 else
638 last_segname = "reg";
640 else
641 last_segname = "dmem";
642 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
643 break;
646 default:
647 /* OOPS! */
648 last_segname = "scrap";
649 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
652 if (*memory == NULL)
653 *memory = xcalloc (1, SEGMENT_SIZE);
655 offset = (phys_addr % SEGMENT_SIZE);
656 raw = *memory + offset;
657 return raw;
660 /* Transfer data to/from simulated memory. Since a bug in either the
661 simulated program or in gdb or the simulator itself may cause a
662 bogus address to be passed in, we need to do some sanity checking
663 on addresses to make sure they are within bounds. When an address
664 fails the bounds check, treat it as a zero length read/write rather
665 than aborting the entire run. */
667 static int
668 xfer_mem (SIM_DESC sd,
669 address_word virt,
670 unsigned char *buffer,
671 uint64_t size,
672 int write_p)
674 uint8_t *memory;
675 unsigned long phys;
676 int phys_size;
677 phys_size = sim_d10v_translate_addr (sd, NULL, virt, size, &phys, NULL,
678 dmap_register, imap_register);
679 if (phys_size == 0)
680 return 0;
682 memory = map_memory (sd, NULL, phys);
684 #ifdef DEBUG
685 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
687 sim_io_printf
688 (sd,
689 "sim_%s %d bytes: 0x%08" PRIxTA " (%s) -> 0x%08lx (%s) -> %p (%s)\n",
690 write_p ? "write" : "read",
691 phys_size, virt, last_from,
692 phys, last_to,
693 memory, last_segname);
695 #endif
697 if (write_p)
699 memcpy (memory, buffer, phys_size);
701 else
703 memcpy (buffer, memory, phys_size);
706 return phys_size;
710 uint64_t
711 sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t size)
713 /* FIXME: this should be performing a virtual transfer */
714 /* FIXME: We cast the const away, but it's safe because xfer_mem only reads
715 when write_p==1. This is still ugly. */
716 return xfer_mem (sd, addr, (void *) buffer, size, 1);
719 uint64_t
720 sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t size)
722 /* FIXME: this should be performing a virtual transfer */
723 return xfer_mem (sd, addr, buffer, size, 0);
726 static sim_cia
727 d10v_pc_get (sim_cpu *cpu)
729 return PC;
732 static void
733 d10v_pc_set (sim_cpu *cpu, sim_cia pc)
735 SIM_DESC sd = CPU_STATE (cpu);
736 SET_PC (pc);
739 static void
740 free_state (SIM_DESC sd)
742 if (STATE_MODULES (sd) != NULL)
743 sim_module_uninstall (sd);
744 sim_cpu_free_all (sd);
745 sim_state_free (sd);
748 static int d10v_reg_fetch (SIM_CPU *, int, void *, int);
749 static int d10v_reg_store (SIM_CPU *, int, const void *, int);
751 SIM_DESC
752 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
753 struct bfd *abfd, char * const *argv)
755 struct simops *s;
756 struct hash_entry *h;
757 static int init_p = 0;
758 char * const *p;
759 int i;
760 SIM_DESC sd = sim_state_alloc (kind, cb);
761 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
763 /* Set default options before parsing user options. */
764 current_alignment = STRICT_ALIGNMENT;
765 cb->syscall_map = cb_d10v_syscall_map;
767 /* The cpu data is kept in a separately allocated chunk of memory. */
768 if (sim_cpu_alloc_all (sd, 0) != SIM_RC_OK)
770 free_state (sd);
771 return 0;
774 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
776 free_state (sd);
777 return 0;
780 /* The parser will print an error message for us, so we silently return. */
781 if (sim_parse_args (sd, argv) != SIM_RC_OK)
783 free_state (sd);
784 return 0;
787 /* Check for/establish the a reference program image. */
788 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
790 free_state (sd);
791 return 0;
794 /* Configure/verify the target byte order and other runtime
795 configuration options. */
796 if (sim_config (sd) != SIM_RC_OK)
798 sim_module_uninstall (sd);
799 return 0;
802 if (sim_post_argv_init (sd) != SIM_RC_OK)
804 /* Uninstall the modules to avoid memory leaks,
805 file descriptor leaks, etc. */
806 sim_module_uninstall (sd);
807 return 0;
810 /* CPU specific initialization. */
811 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
813 SIM_CPU *cpu = STATE_CPU (sd, i);
815 CPU_REG_FETCH (cpu) = d10v_reg_fetch;
816 CPU_REG_STORE (cpu) = d10v_reg_store;
817 CPU_PC_FETCH (cpu) = d10v_pc_get;
818 CPU_PC_STORE (cpu) = d10v_pc_set;
821 old_segment_mapping = 0;
823 /* NOTE: This argument parsing is only effective when this function
824 is called by GDB. Standalone argument parsing is handled by
825 sim/common/run.c. */
826 for (p = argv + 1; *p; ++p)
828 if (strcmp (*p, "-oldseg") == 0)
829 old_segment_mapping = 1;
830 #ifdef DEBUG
831 else if (strcmp (*p, "-t") == 0)
832 d10v_debug = DEBUG;
833 else if (strncmp (*p, "-t", 2) == 0)
834 d10v_debug = atoi (*p + 2);
835 #endif
838 /* put all the opcodes in the hash table */
839 if (!init_p++)
841 for (s = Simops; s->func; s++)
843 h = &hash_table[hash(s->opcode,s->format)];
845 /* go to the last entry in the chain */
846 while (h->next)
847 h = h->next;
849 if (h->ops)
851 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
852 if (!h->next)
853 perror ("malloc failure");
855 h = h->next;
857 h->ops = s;
858 h->mask = s->mask;
859 h->opcode = s->opcode;
860 h->size = s->is_long;
864 /* reset the processor state */
865 if (!State.mem.data[0])
866 sim_size (1);
868 return sd;
871 uint8_t *
872 dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16_t offset)
874 unsigned long phys;
875 uint8_t *mem;
876 int phys_size;
878 /* Note: DMEM address range is 0..0x10000. Calling code can compute
879 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
880 is uint16_t this is modulo'ed onto 0x0e5d. */
882 phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
883 dmap_register);
884 if (phys_size == 0)
885 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
886 mem = map_memory (sd, cpu, phys);
887 #ifdef DEBUG
888 if ((d10v_debug & DEBUG_MEMORY))
890 sim_io_printf
891 (sd,
892 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> %p (%s)\n",
893 offset, last_from,
894 phys, phys_size, last_to,
895 mem, last_segname);
897 #endif
898 return mem;
901 uint8_t *
902 imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32_t offset)
904 unsigned long phys;
905 uint8_t *mem;
906 int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
907 imap_register);
908 if (phys_size == 0)
909 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
910 mem = map_memory (sd, cpu, phys);
911 #ifdef DEBUG
912 if ((d10v_debug & DEBUG_MEMORY))
914 sim_io_printf
915 (sd,
916 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> %p (%s)\n",
917 offset, last_from,
918 phys, phys_size, last_to,
919 mem, last_segname);
921 #endif
922 return mem;
925 static void
926 step_once (SIM_DESC sd, SIM_CPU *cpu)
928 uint32_t inst;
929 uint8_t *iaddr;
931 /* TODO: Unindent this block. */
933 iaddr = imem_addr (sd, cpu, (uint32_t)PC << 2);
935 inst = get_longword( iaddr );
937 State.pc_changed = 0;
938 ins_type_counters[ (int)INS_CYCLES ]++;
940 switch (inst & 0xC0000000)
942 case 0xC0000000:
943 /* long instruction */
944 do_long (sd, cpu, inst & 0x3FFFFFFF);
945 break;
946 case 0x80000000:
947 /* R -> L */
948 do_2_short (sd, cpu, inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
949 break;
950 case 0x40000000:
951 /* L -> R */
952 do_2_short (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
953 break;
954 case 0:
955 do_parallel (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
956 break;
959 /* If the PC of the current instruction matches RPT_E then
960 schedule a branch to the loop start. If one of those
961 instructions happens to be a branch, than that instruction
962 will be ignored */
963 if (!State.pc_changed)
965 if (PSW_RP && PC == RPT_E)
967 /* Note: The behavior of a branch instruction at RPT_E
968 is implementation dependant, this simulator takes the
969 branch. Branching to RPT_E is valid, the instruction
970 must be executed before the loop is taken. */
971 if (RPT_C == 1)
973 SET_PSW_RP (0);
974 SET_RPT_C (0);
975 SET_PC (PC + 1);
977 else
979 SET_RPT_C (RPT_C - 1);
980 SET_PC (RPT_S);
983 else
984 SET_PC (PC + 1);
987 /* Check for a breakpoint trap on this instruction. This
988 overrides any pending branches or loops */
989 if (PSW_DB && PC == IBA)
991 SET_BPC (PC);
992 SET_BPSW (PSW);
993 SET_PSW (PSW & PSW_SM_BIT);
994 SET_PC (SDBT_VECTOR_START);
997 /* Writeback all the DATA / PC changes */
998 SLOT_FLUSH ();
1002 void
1003 sim_engine_run (SIM_DESC sd,
1004 int next_cpu_nr, /* ignore */
1005 int nr_cpus, /* ignore */
1006 int siggnal)
1008 sim_cpu *cpu;
1010 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1012 cpu = STATE_CPU (sd, 0);
1014 switch (siggnal)
1016 case 0:
1017 break;
1018 case GDB_SIGNAL_BUS:
1019 SET_BPC (PC);
1020 SET_BPSW (PSW);
1021 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1022 JMP (AE_VECTOR_START);
1023 SLOT_FLUSH ();
1024 break;
1025 case GDB_SIGNAL_ILL:
1026 SET_BPC (PC);
1027 SET_BPSW (PSW);
1028 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1029 JMP (RIE_VECTOR_START);
1030 SLOT_FLUSH ();
1031 break;
1032 default:
1033 /* just ignore it */
1034 break;
1037 while (1)
1039 step_once (sd, cpu);
1040 if (sim_events_tick (sd))
1041 sim_events_process (sd);
1045 void
1046 sim_info (SIM_DESC sd, bool verbose)
1048 char buf1[40];
1049 char buf2[40];
1050 char buf3[40];
1051 char buf4[40];
1052 char buf5[40];
1053 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1054 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1055 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1056 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1057 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1059 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1060 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1061 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1062 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1063 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1065 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1066 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1067 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1068 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1069 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1070 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1071 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1072 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1073 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1074 unsigned long total = (unknown + left_total + right_total + ins_long);
1076 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1077 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1078 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1079 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1080 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1081 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1083 sim_io_printf (sd,
1084 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1085 size, add_commas (buf1, sizeof (buf1), left_total),
1086 normal_size, add_commas (buf2, sizeof (buf2), left),
1087 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1088 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1089 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1091 sim_io_printf (sd,
1092 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1093 size, add_commas (buf1, sizeof (buf1), right_total),
1094 normal_size, add_commas (buf2, sizeof (buf2), right),
1095 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1096 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1097 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1099 if (ins_long)
1100 sim_io_printf (sd,
1101 "executed %*s long instruction(s)\n",
1102 size, add_commas (buf1, sizeof (buf1), ins_long));
1104 if (parallel)
1105 sim_io_printf (sd,
1106 "executed %*s parallel instruction(s)\n",
1107 size, add_commas (buf1, sizeof (buf1), parallel));
1109 if (leftright)
1110 sim_io_printf (sd,
1111 "executed %*s instruction(s) encoded L->R\n",
1112 size, add_commas (buf1, sizeof (buf1), leftright));
1114 if (rightleft)
1115 sim_io_printf (sd,
1116 "executed %*s instruction(s) encoded R->L\n",
1117 size, add_commas (buf1, sizeof (buf1), rightleft));
1119 if (unknown)
1120 sim_io_printf (sd,
1121 "executed %*s unknown instruction(s)\n",
1122 size, add_commas (buf1, sizeof (buf1), unknown));
1124 if (cond_true)
1125 sim_io_printf (sd,
1126 "executed %*s instruction(s) due to EXExxx condition being true\n",
1127 size, add_commas (buf1, sizeof (buf1), cond_true));
1129 if (cond_false)
1130 sim_io_printf (sd,
1131 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1132 size, add_commas (buf1, sizeof (buf1), cond_false));
1134 if (cond_jump)
1135 sim_io_printf (sd,
1136 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1137 size, add_commas (buf1, sizeof (buf1), cond_jump));
1139 sim_io_printf (sd,
1140 "executed %*s cycle(s)\n",
1141 size, add_commas (buf1, sizeof (buf1), cycles));
1143 sim_io_printf (sd,
1144 "executed %*s total instructions\n",
1145 size, add_commas (buf1, sizeof (buf1), total));
1148 SIM_RC
1149 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1150 char * const *argv, char * const *env)
1152 bfd_vma start_address;
1154 /* Make sure we have the right structure for the following memset. */
1155 static_assert (offsetof (struct _state, regs) == 0,
1156 "State.regs is not at offset 0");
1158 /* Reset state from the regs field until the mem field. */
1159 memset (&State, 0, (uintptr_t) &State.mem - (uintptr_t) &State.regs);
1161 /* There was a hack here to copy the values of argc and argv into r0
1162 and r1. The values were also saved into some high memory that
1163 won't be overwritten by the stack (0x7C00). The reason for doing
1164 this was to allow the 'run' program to accept arguments. Without
1165 the hack, this is not possible anymore. If the simulator is run
1166 from the debugger, arguments cannot be passed in, so this makes
1167 no difference. */
1169 /* set PC */
1170 if (abfd != NULL)
1171 start_address = bfd_get_start_address (abfd);
1172 else
1173 start_address = 0xffc0 << 2;
1174 #ifdef DEBUG
1175 if (d10v_debug)
1176 sim_io_printf (sd, "sim_create_inferior: PC=0x%" PRIx64 "\n",
1177 (uint64_t) start_address);
1178 #endif
1180 SIM_CPU *cpu = STATE_CPU (sd, 0);
1181 SET_CREG (PC_CR, start_address >> 2);
1184 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1185 initializes imap0 and imap1 to 0x1000 as part of its ROM
1186 initialization. */
1187 if (old_segment_mapping)
1189 /* External memory startup. This is the HARD reset state. */
1190 set_imap_register (sd, 0, 0x0000);
1191 set_imap_register (sd, 1, 0x007f);
1192 set_dmap_register (sd, 0, 0x2000);
1193 set_dmap_register (sd, 1, 0x2000);
1194 set_dmap_register (sd, 2, 0x0000); /* Old DMAP */
1195 set_dmap_register (sd, 3, 0x0000);
1197 else
1199 /* Internal memory startup. This is the ROM intialized state. */
1200 set_imap_register (sd, 0, 0x1000);
1201 set_imap_register (sd, 1, 0x1000);
1202 set_dmap_register (sd, 0, 0x2000);
1203 set_dmap_register (sd, 1, 0x2000);
1204 set_dmap_register (sd, 2, 0x2000); /* DMAP2 initial internal value is
1205 0x2000 on the new board. */
1206 set_dmap_register (sd, 3, 0x0000);
1209 SLOT_FLUSH ();
1210 return SIM_RC_OK;
1213 static int
1214 d10v_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
1216 SIM_DESC sd = CPU_STATE (cpu);
1217 int size;
1218 switch ((enum sim_d10v_regs) rn)
1220 case SIM_D10V_R0_REGNUM:
1221 case SIM_D10V_R1_REGNUM:
1222 case SIM_D10V_R2_REGNUM:
1223 case SIM_D10V_R3_REGNUM:
1224 case SIM_D10V_R4_REGNUM:
1225 case SIM_D10V_R5_REGNUM:
1226 case SIM_D10V_R6_REGNUM:
1227 case SIM_D10V_R7_REGNUM:
1228 case SIM_D10V_R8_REGNUM:
1229 case SIM_D10V_R9_REGNUM:
1230 case SIM_D10V_R10_REGNUM:
1231 case SIM_D10V_R11_REGNUM:
1232 case SIM_D10V_R12_REGNUM:
1233 case SIM_D10V_R13_REGNUM:
1234 case SIM_D10V_R14_REGNUM:
1235 case SIM_D10V_R15_REGNUM:
1236 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1237 size = 2;
1238 break;
1239 case SIM_D10V_CR0_REGNUM:
1240 case SIM_D10V_CR1_REGNUM:
1241 case SIM_D10V_CR2_REGNUM:
1242 case SIM_D10V_CR3_REGNUM:
1243 case SIM_D10V_CR4_REGNUM:
1244 case SIM_D10V_CR5_REGNUM:
1245 case SIM_D10V_CR6_REGNUM:
1246 case SIM_D10V_CR7_REGNUM:
1247 case SIM_D10V_CR8_REGNUM:
1248 case SIM_D10V_CR9_REGNUM:
1249 case SIM_D10V_CR10_REGNUM:
1250 case SIM_D10V_CR11_REGNUM:
1251 case SIM_D10V_CR12_REGNUM:
1252 case SIM_D10V_CR13_REGNUM:
1253 case SIM_D10V_CR14_REGNUM:
1254 case SIM_D10V_CR15_REGNUM:
1255 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1256 size = 2;
1257 break;
1258 case SIM_D10V_A0_REGNUM:
1259 case SIM_D10V_A1_REGNUM:
1260 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1261 size = 8;
1262 break;
1263 case SIM_D10V_SPI_REGNUM:
1264 /* PSW_SM indicates that the current SP is the USER
1265 stack-pointer. */
1266 WRITE_16 (memory, spi_register ());
1267 size = 2;
1268 break;
1269 case SIM_D10V_SPU_REGNUM:
1270 /* PSW_SM indicates that the current SP is the USER
1271 stack-pointer. */
1272 WRITE_16 (memory, spu_register ());
1273 size = 2;
1274 break;
1275 case SIM_D10V_IMAP0_REGNUM:
1276 case SIM_D10V_IMAP1_REGNUM:
1277 WRITE_16 (memory, imap_register (sd, cpu, NULL, rn - SIM_D10V_IMAP0_REGNUM));
1278 size = 2;
1279 break;
1280 case SIM_D10V_DMAP0_REGNUM:
1281 case SIM_D10V_DMAP1_REGNUM:
1282 case SIM_D10V_DMAP2_REGNUM:
1283 case SIM_D10V_DMAP3_REGNUM:
1284 WRITE_16 (memory, dmap_register (sd, cpu, NULL, rn - SIM_D10V_DMAP0_REGNUM));
1285 size = 2;
1286 break;
1287 case SIM_D10V_TS2_DMAP_REGNUM:
1288 size = 0;
1289 break;
1290 default:
1291 size = 0;
1292 break;
1294 return size;
1297 static int
1298 d10v_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
1300 SIM_DESC sd = CPU_STATE (cpu);
1301 int size;
1302 switch ((enum sim_d10v_regs) rn)
1304 case SIM_D10V_R0_REGNUM:
1305 case SIM_D10V_R1_REGNUM:
1306 case SIM_D10V_R2_REGNUM:
1307 case SIM_D10V_R3_REGNUM:
1308 case SIM_D10V_R4_REGNUM:
1309 case SIM_D10V_R5_REGNUM:
1310 case SIM_D10V_R6_REGNUM:
1311 case SIM_D10V_R7_REGNUM:
1312 case SIM_D10V_R8_REGNUM:
1313 case SIM_D10V_R9_REGNUM:
1314 case SIM_D10V_R10_REGNUM:
1315 case SIM_D10V_R11_REGNUM:
1316 case SIM_D10V_R12_REGNUM:
1317 case SIM_D10V_R13_REGNUM:
1318 case SIM_D10V_R14_REGNUM:
1319 case SIM_D10V_R15_REGNUM:
1320 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1321 size = 2;
1322 break;
1323 case SIM_D10V_CR0_REGNUM:
1324 case SIM_D10V_CR1_REGNUM:
1325 case SIM_D10V_CR2_REGNUM:
1326 case SIM_D10V_CR3_REGNUM:
1327 case SIM_D10V_CR4_REGNUM:
1328 case SIM_D10V_CR5_REGNUM:
1329 case SIM_D10V_CR6_REGNUM:
1330 case SIM_D10V_CR7_REGNUM:
1331 case SIM_D10V_CR8_REGNUM:
1332 case SIM_D10V_CR9_REGNUM:
1333 case SIM_D10V_CR10_REGNUM:
1334 case SIM_D10V_CR11_REGNUM:
1335 case SIM_D10V_CR12_REGNUM:
1336 case SIM_D10V_CR13_REGNUM:
1337 case SIM_D10V_CR14_REGNUM:
1338 case SIM_D10V_CR15_REGNUM:
1339 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1340 size = 2;
1341 break;
1342 case SIM_D10V_A0_REGNUM:
1343 case SIM_D10V_A1_REGNUM:
1344 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1345 size = 8;
1346 break;
1347 case SIM_D10V_SPI_REGNUM:
1348 /* PSW_SM indicates that the current SP is the USER
1349 stack-pointer. */
1350 set_spi_register (READ_16 (memory));
1351 size = 2;
1352 break;
1353 case SIM_D10V_SPU_REGNUM:
1354 set_spu_register (READ_16 (memory));
1355 size = 2;
1356 break;
1357 case SIM_D10V_IMAP0_REGNUM:
1358 case SIM_D10V_IMAP1_REGNUM:
1359 set_imap_register (sd, rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
1360 size = 2;
1361 break;
1362 case SIM_D10V_DMAP0_REGNUM:
1363 case SIM_D10V_DMAP1_REGNUM:
1364 case SIM_D10V_DMAP2_REGNUM:
1365 case SIM_D10V_DMAP3_REGNUM:
1366 set_dmap_register (sd, rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
1367 size = 2;
1368 break;
1369 case SIM_D10V_TS2_DMAP_REGNUM:
1370 size = 0;
1371 break;
1372 default:
1373 size = 0;
1374 break;
1376 SLOT_FLUSH ();
1377 return size;