5 #include "remote-sim.h"
10 enum _leftright
{ LEFT_FIRST
, RIGHT_FIRST
};
13 static SIM_OPEN_KIND sim_kind
;
16 /* Set this to true to get the previous segment layout. */
18 int old_segment_mapping
;
20 host_callback
*d10v_callback
;
21 unsigned long ins_type_counters
[ (int)INS_MAX
];
25 static int init_text_p
= 0;
26 /* non-zero if we opened prog_bfd */
27 static int prog_bfd_was_opened_p
;
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
);
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
48 /* Counter for the ui_loop_hook update */
49 static long ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
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 */
56 #if defined(__GNUC__) && defined(__OPTIMIZE__)
57 #define INLINE __inline__
66 struct hash_entry
*next
;
73 struct hash_entry hash_table
[MAX_HASH
+1];
80 if (format
& LONG_OPCODE
)
81 return ((insn
& 0x3F000000) >> 24);
83 return((insn
& 0x7E00) >> 9);
86 INLINE
static struct hash_entry
*
87 lookup_hash (ins
, size
)
94 h
= &hash_table
[(ins
& 0x3F000000) >> 24];
96 h
= &hash_table
[(ins
& 0x7E00) >> 9];
98 while ((ins
& h
->mask
) != h
->opcode
|| h
->size
!= size
)
102 (*d10v_callback
->printf_filtered
)
103 (d10v_callback
, "ERROR: Illegal instruction %x at PC %x\n", ins
, PC
);
104 State
.exception
= SIGILL
;
113 get_operands (struct simops
*s
, uint32 ins
)
115 int i
, shift
, bits
, flags
;
117 for (i
=0; i
< s
->numops
; i
++)
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
;
125 /* FIXME: for tracing, update values that need to be updated each
126 instruction decode cycle */
127 State
.trace
.psw
= PSW
;
134 if (!init_text_p
&& prog_bfd
!= NULL
)
137 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
138 if (strcmp (bfd_get_section_name (prog_bfd
, s
), ".text") == 0)
141 text_start
= bfd_get_section_vma (prog_bfd
, s
);
142 text_end
= text_start
+ bfd_section_size (prog_bfd
, s
);
147 return (PC
<< 2) + text_start
;
154 struct hash_entry
*h
;
156 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
157 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_long 0x%x\n", ins
);
159 h
= lookup_hash (ins
, 1);
162 get_operands (h
->ops
, ins
);
163 State
.ins_type
= INS_LONG
;
164 ins_type_counters
[ (int)State
.ins_type
]++;
169 do_2_short (ins1
, ins2
, leftright
)
171 enum _leftright leftright
;
173 struct hash_entry
*h
;
174 enum _ins_type first
, second
;
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
);
182 if (leftright
== LEFT_FIRST
)
186 ins_type_counters
[ (int)INS_LEFTRIGHT
]++;
192 ins_type_counters
[ (int)INS_RIGHTLEFT
]++;
195 /* Issue the first instruction */
196 h
= lookup_hash (ins1
, 0);
199 get_operands (h
->ops
, ins1
);
200 State
.ins_type
= first
;
201 ins_type_counters
[ (int)State
.ins_type
]++;
204 /* Issue the second instruction (if the PC hasn't changed) */
205 if (!State
.pc_changed
&& !State
.exception
)
207 /* finish any existing instructions */
209 h
= lookup_hash (ins2
, 0);
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
]++;
218 else if (!State
.exception
)
219 ins_type_counters
[ (int)INS_COND_JUMP
]++;
223 do_parallel (ins1
, ins2
)
226 struct hash_entry
*h1
, *h2
;
228 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
229 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_parallel 0x%x || 0x%x\n", ins1
, ins2
);
231 ins_type_counters
[ (int)INS_PARALLEL
]++;
232 h1
= lookup_hash (ins1
, 0);
235 h2
= lookup_hash (ins2
, 0);
239 if (h1
->ops
->exec_type
== PARONLY
)
241 get_operands (h1
->ops
, ins1
);
242 State
.ins_type
= INS_LEFT_COND_TEST
;
243 ins_type_counters
[ (int)State
.ins_type
]++;
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
]++;
254 ins_type_counters
[ (int)INS_COND_FALSE
]++;
256 else if (h2
->ops
->exec_type
== PARONLY
)
258 get_operands (h2
->ops
, ins2
);
259 State
.ins_type
= INS_RIGHT_COND_TEST
;
260 ins_type_counters
[ (int)State
.ins_type
]++;
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
]++;
271 ins_type_counters
[ (int)INS_COND_FALSE
]++;
275 get_operands (h1
->ops
, ins1
);
276 State
.ins_type
= INS_LEFT_PARALLEL
;
277 ins_type_counters
[ (int)State
.ins_type
]++;
279 if (!State
.exception
)
281 get_operands (h2
->ops
, ins2
);
282 State
.ins_type
= INS_RIGHT_PARALLEL
;
283 ins_type_counters
[ (int)State
.ins_type
]++;
290 add_commas(buf
, sizeof_buf
, value
)
296 char *endbuf
= buf
+ sizeof_buf
- 1;
306 *--endbuf
= (value
% 10) + '0';
307 } while ((value
/= 10) != 0);
318 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
320 if (State
.mem
.insn
[i
])
321 free (State
.mem
.insn
[i
]);
323 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
325 if (State
.mem
.data
[i
])
326 free (State
.mem
.data
[i
]);
328 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
330 if (State
.mem
.unif
[i
])
331 free (State
.mem
.unif
[i
]);
333 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
335 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
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";
345 IMAP0_OFFSET
= 0xff00,
346 DMAP0_OFFSET
= 0xff08,
347 DMAP2_SHADDOW
= 0xff04,
348 DMAP2_OFFSET
= 0xff0c
352 set_dmap_register (int reg_nr
, unsigned long value
)
354 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
355 + DMAP0_OFFSET
+ 2 * reg_nr
);
356 WRITE_16 (raw
, value
);
358 if ((d10v_debug
& DEBUG_MEMORY
))
360 (*d10v_callback
->printf_filtered
)
361 (d10v_callback
, "mem: dmap%d=0x%04lx\n", reg_nr
, value
);
367 dmap_register (int reg_nr
)
369 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
370 + DMAP0_OFFSET
+ 2 * reg_nr
);
371 return READ_16 (raw
);
375 set_imap_register (int reg_nr
, unsigned long value
)
377 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
378 + IMAP0_OFFSET
+ 2 * reg_nr
);
379 WRITE_16 (raw
, value
);
381 if ((d10v_debug
& DEBUG_MEMORY
))
383 (*d10v_callback
->printf_filtered
)
384 (d10v_callback
, "mem: imap%d=0x%04lx\n", reg_nr
, value
);
390 imap_register (int reg_nr
)
392 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
393 + IMAP0_OFFSET
+ 2 * reg_nr
);
394 return READ_16 (raw
);
409 return HELD_SP (HELD_SPU_IDX
);
418 return HELD_SP (HELD_SPI_IDX
);
422 set_spi_register (unsigned long value
)
425 SET_GPR (SP_IDX
, value
);
426 SET_HELD_SP (HELD_SPI_IDX
, value
);
430 set_spu_register (unsigned long value
)
433 SET_GPR (SP_IDX
, value
);
434 SET_HELD_SP (HELD_SPU_IDX
, value
);
437 /* Given a virtual address in the DMAP address space, translate it
438 into a physical address. */
441 sim_d10v_translate_dmap_addr (unsigned long offset
,
444 unsigned long (*dmap_register
) (int reg_nr
))
448 last_from
= "logical-data";
449 if (offset
>= DMAP_BLOCK_SIZE
* SIM_D10V_NR_DMAP_REGS
)
451 /* Logical address out side of data segments, not supported */
454 regno
= (offset
/ DMAP_BLOCK_SIZE
);
455 offset
= (offset
% DMAP_BLOCK_SIZE
);
456 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
458 /* Don't cross a BLOCK boundary */
459 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
461 map
= dmap_register (regno
);
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
);
472 int sp
= ((map
& 0x3000) >> 12);
473 int segno
= (map
& 0x3ff);
476 case 0: /* 00: Unified memory */
477 *phys
= SIM_D10V_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
480 case 1: /* 01: Instruction Memory */
481 *phys
= SIM_D10V_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
482 last_to
= "chip-insn";
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";
488 case 3: /* 11: Reserved */
495 /* Given a virtual address in the IMAP address space, translate it
496 into a physical address. */
499 sim_d10v_translate_imap_addr (unsigned long offset
,
502 unsigned long (*imap_register
) (int reg_nr
))
508 last_from
= "logical-insn";
509 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_D10V_NR_IMAP_REGS
))
511 /* Logical address outside of IMAP segments, not supported */
514 regno
= (offset
/ IMAP_BLOCK_SIZE
);
515 offset
= (offset
% IMAP_BLOCK_SIZE
);
516 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
518 /* Don't cross a BLOCK boundary */
519 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
521 map
= imap_register (regno
);
522 sp
= (map
& 0x3000) >> 12;
523 segno
= (map
& 0x007f);
526 case 0: /* 00: unified memory */
527 *phys
= SIM_D10V_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
530 case 1: /* 01: instruction memory */
531 *phys
= SIM_D10V_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
532 last_to
= "chip-insn";
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";
550 sim_d10v_translate_addr (unsigned long memaddr
,
552 unsigned long *targ_addr
,
553 unsigned long (*dmap_register
) (int reg_nr
),
554 unsigned long (*imap_register
) (int reg_nr
))
560 last_from
= "unknown";
563 seg
= (memaddr
>> 24);
564 off
= (memaddr
& 0xffffffL
);
566 /* However, if we've asked to use the previous generation of segment
567 mapping, rearrange the segments as follows. */
569 if (old_segment_mapping
)
573 case 0x00: /* DMAP translated memory */
576 case 0x01: /* IMAP translated memory */
579 case 0x10: /* On-chip data memory */
582 case 0x11: /* On-chip insn memory */
585 case 0x12: /* Unified memory */
593 case 0x00: /* Physical unified memory */
594 last_from
= "phys-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
);
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
);
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
);
617 case 0x10: /* in logical data address segment */
618 nr_bytes
= sim_d10v_translate_dmap_addr (off
, nr_bytes
, &phys
,
622 case 0x11: /* in logical instruction address segment */
623 nr_bytes
= sim_d10v_translate_imap_addr (off
, nr_bytes
, &phys
,
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. */
640 map_memory (unsigned phys_addr
)
645 int segment
= ((phys_addr
>> 24) & 0xff);
650 case 0x00: /* Unified memory */
652 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
653 last_segname
= "umem";
657 case 0x01: /* On-chip insn memory */
659 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
660 last_segname
= "imem";
664 case 0x02: /* On-chip data memory */
666 if ((phys_addr
& 0xff00) == 0xff00)
668 phys_addr
= (phys_addr
& 0xffff);
669 if (phys_addr
== DMAP2_SHADDOW
)
671 phys_addr
= DMAP2_OFFSET
;
672 last_segname
= "dmap";
675 last_segname
= "reg";
678 last_segname
= "dmem";
679 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
685 last_segname
= "scrap";
686 return State
.mem
.fault
;
691 *memory
= calloc (1, SEGMENT_SIZE
);
694 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Malloc failed.\n");
695 return State
.mem
.fault
;
699 offset
= (phys_addr
% SEGMENT_SIZE
);
700 raw
= *memory
+ offset
;
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. */
712 xfer_mem (SIM_ADDR virt
,
713 unsigned char *buffer
,
719 while (xfered
< size
)
724 phys_size
= sim_d10v_translate_addr (virt
, size
,
731 memory
= map_memory (phys
);
734 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
736 (*d10v_callback
->printf_filtered
)
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
,
742 (long) memory
, last_segname
);
748 memcpy (memory
, buffer
, phys_size
);
752 memcpy (buffer
, memory
, phys_size
);
765 sim_write (sd
, addr
, buffer
, size
)
768 unsigned char *buffer
;
771 /* FIXME: this should be performing a virtual transfer */
772 return xfer_mem( addr
, buffer
, size
, 1);
776 sim_read (sd
, addr
, buffer
, size
)
779 unsigned char *buffer
;
782 /* FIXME: this should be performing a virtual transfer */
783 return xfer_mem( addr
, buffer
, size
, 0);
788 sim_open (kind
, callback
, abfd
, argv
)
790 host_callback
*callback
;
795 struct hash_entry
*h
;
796 static int init_p
= 0;
800 d10v_callback
= callback
;
802 old_segment_mapping
= 0;
804 /* NOTE: This argument parsing is only effective when this function
805 is called by GDB. Standalone argument parsing is handled by
807 for (p
= argv
+ 1; *p
; ++p
)
809 if (strcmp (*p
, "-oldseg") == 0)
810 old_segment_mapping
= 1;
812 else if (strcmp (*p
, "-t") == 0)
814 else if (strncmp (*p
, "-t", 2) == 0)
815 d10v_debug
= atoi (*p
+ 2);
818 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unsupported option(s): %s\n",*p
);
821 /* put all the opcodes in the hash table */
824 for (s
= Simops
; s
->func
; s
++)
826 h
= &hash_table
[hash(s
->opcode
,s
->format
)];
828 /* go to the last entry in the chain */
834 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
836 perror ("malloc failure");
842 h
->opcode
= s
->opcode
;
843 h
->size
= s
->is_long
;
847 /* reset the processor state */
848 if (!State
.mem
.data
[0])
850 sim_create_inferior ((SIM_DESC
) 1, NULL
, NULL
, NULL
);
852 /* Fudge our descriptor. */
858 sim_close (sd
, quitting
)
862 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
864 bfd_close (prog_bfd
);
866 prog_bfd_was_opened_p
= 0;
874 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile %d\n",n
);
878 sim_set_profile_size (n
)
881 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile_size %d\n",n
);
885 dmem_addr (uint16 offset
)
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. */
895 phys_size
= sim_d10v_translate_dmap_addr (offset
, 1, &phys
,
899 mem
= State
.mem
.fault
;
902 mem
= map_memory (phys
);
904 if ((d10v_debug
& DEBUG_MEMORY
))
906 (*d10v_callback
->printf_filtered
)
908 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
910 phys
, phys_size
, last_to
,
911 (long) mem
, last_segname
);
918 imem_addr (uint32 offset
)
922 int phys_size
= sim_d10v_translate_imap_addr (offset
, 1, &phys
, imap_register
);
925 return State
.mem
.fault
;
927 mem
= map_memory (phys
);
929 if ((d10v_debug
& DEBUG_MEMORY
))
931 (*d10v_callback
->printf_filtered
)
933 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
935 phys
, phys_size
, last_to
,
936 (long) mem
, last_segname
);
942 static int stop_simulator
= 0;
953 /* Run (or resume) the program. */
955 sim_resume (sd
, step
, siggnal
)
962 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
969 iaddr
= imem_addr ((uint32
)PC
<< 2);
970 if (iaddr
== State
.mem
.fault
)
972 State
.exception
= SIGBUS
;
976 inst
= get_longword( iaddr
);
978 State
.pc_changed
= 0;
979 ins_type_counters
[ (int)INS_CYCLES
]++;
981 switch (inst
& 0xC0000000)
984 /* long instruction */
985 do_long (inst
& 0x3FFFFFFF);
989 do_2_short ( inst
& 0x7FFF, (inst
& 0x3FFF8000) >> 15, RIGHT_FIRST
);
993 do_2_short ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF, LEFT_FIRST
);
996 do_parallel ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF);
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
1004 if (!State
.pc_changed
)
1006 if (PSW_RP
&& PC
== RPT_E
)
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. */
1020 SET_RPT_C (RPT_C
- 1);
1028 /* Check for a breakpoint trap on this instruction. This
1029 overrides any pending branches or loops */
1030 if (PSW_DB
&& PC
== IBA
)
1034 SET_PSW (PSW
& PSW_SM_BIT
);
1035 SET_PC (SDBT_VECTOR_START
);
1038 /* Writeback all the DATA / PC changes */
1041 #ifdef NEED_UI_LOOP_HOOK
1042 if (ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1044 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1047 #endif /* NEED_UI_LOOP_HOOK */
1049 while ( !State
.exception
&& !stop_simulator
);
1051 if (step
&& !State
.exception
)
1052 State
.exception
= SIGTRAP
;
1062 sim_resume (sd
, 0, 0);
1067 sim_info (sd
, verbose
)
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
;
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
;
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
);
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
));
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
));
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
));
1123 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1124 "executed %*s long instruction(s)\n",
1125 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1128 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1129 "executed %*s parallel instruction(s)\n",
1130 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1133 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1134 "executed %*s instruction(s) encoded L->R\n",
1135 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1138 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1139 "executed %*s instruction(s) encoded R->L\n",
1140 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1143 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1144 "executed %*s unknown instruction(s)\n",
1145 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
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
));
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
));
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
));
1162 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1163 "executed %*s cycle(s)\n",
1164 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1166 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1167 "executed %*s total instructions\n",
1168 size
, add_commas (buf1
, sizeof (buf1
), total
));
1172 sim_create_inferior (sd
, abfd
, argv
, env
)
1178 bfd_vma start_address
;
1180 /* reset all state information */
1181 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
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;
1192 int size
= strlen (argv
[i
]) + 1;
1193 SW (addr
+ 2*i
, addr
+ p
);
1194 sim_write (sd
, addr
+ 0, argv
[i
], size
);
1204 start_address
= bfd_get_start_address (abfd
);
1206 start_address
= 0xffc0 << 2;
1209 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1211 SET_CREG (PC_CR
, start_address
>> 2);
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
1216 if (old_segment_mapping
)
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);
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);
1243 sim_set_callbacks (p
)
1250 sim_stop_reason (sd
, reason
, sigrc
)
1252 enum sim_stop
*reason
;
1255 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1257 switch (State
.exception
)
1259 case SIG_D10V_STOP
: /* stop instruction */
1260 *reason
= sim_exited
;
1264 case SIG_D10V_EXIT
: /* exit trap */
1265 *reason
= sim_exited
;
1269 default: /* some signal */
1270 *reason
= sim_stopped
;
1271 if (stop_simulator
&& !State
.exception
)
1274 *sigrc
= State
.exception
;
1282 sim_fetch_register (sd
, rn
, memory
, length
)
1285 unsigned char *memory
;
1291 else if (rn
>= SIM_D10V_R0_REGNUM
1292 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1294 WRITE_16 (memory
, GPR (rn
- SIM_D10V_R0_REGNUM
));
1297 else if (rn
>= SIM_D10V_CR0_REGNUM
1298 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1300 WRITE_16 (memory
, CREG (rn
- SIM_D10V_CR0_REGNUM
));
1303 else if (rn
>= SIM_D10V_A0_REGNUM
1304 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1306 WRITE_64 (memory
, ACC (rn
- SIM_D10V_A0_REGNUM
));
1309 else if (rn
== SIM_D10V_SPI_REGNUM
)
1311 /* PSW_SM indicates that the current SP is the USER
1313 WRITE_16 (memory
, spi_register ());
1316 else if (rn
== SIM_D10V_SPU_REGNUM
)
1318 /* PSW_SM indicates that the current SP is the USER
1320 WRITE_16 (memory
, spu_register ());
1323 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1324 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1326 WRITE_16 (memory
, imap_register (rn
- SIM_D10V_IMAP0_REGNUM
));
1329 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1330 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1332 WRITE_16 (memory
, dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
));
1341 sim_store_register (sd
, rn
, memory
, length
)
1344 unsigned char *memory
;
1350 else if (rn
>= SIM_D10V_R0_REGNUM
1351 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1353 SET_GPR (rn
- SIM_D10V_R0_REGNUM
, READ_16 (memory
));
1356 else if (rn
>= SIM_D10V_CR0_REGNUM
1357 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1359 SET_CREG (rn
- SIM_D10V_CR0_REGNUM
, READ_16 (memory
));
1362 else if (rn
>= SIM_D10V_A0_REGNUM
1363 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1365 SET_ACC (rn
- SIM_D10V_A0_REGNUM
, READ_64 (memory
) & MASK40
);
1368 else if (rn
== SIM_D10V_SPI_REGNUM
)
1370 /* PSW_SM indicates that the current SP is the USER
1372 set_spi_register (READ_16 (memory
));
1375 else if (rn
== SIM_D10V_SPU_REGNUM
)
1377 set_spu_register (READ_16 (memory
));
1380 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1381 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1383 set_imap_register (rn
- SIM_D10V_IMAP0_REGNUM
, READ_16(memory
));
1386 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1387 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1389 set_dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
, READ_16(memory
));
1400 sim_do_command (sd
, cmd
)
1404 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_do_command: %s\n",cmd
);
1408 sim_load (sd
, prog
, abfd
, from_tty
)
1414 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1416 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1418 bfd_close (prog_bfd
);
1419 prog_bfd_was_opened_p
= 0;
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
)
1426 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.057489 seconds and 4 git commands to generate.