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
;
105 State
.pc_changed
= 1; /* Don't increment the PC. */
114 get_operands (struct simops
*s
, uint32 ins
)
116 int i
, shift
, bits
, flags
;
118 for (i
=0; i
< s
->numops
; i
++)
120 shift
= s
->operands
[3*i
];
121 bits
= s
->operands
[3*i
+1];
122 flags
= s
->operands
[3*i
+2];
123 mask
= 0x7FFFFFFF >> (31 - bits
);
124 OP
[i
] = (ins
>> shift
) & mask
;
126 /* FIXME: for tracing, update values that need to be updated each
127 instruction decode cycle */
128 State
.trace
.psw
= PSW
;
135 if (!init_text_p
&& prog_bfd
!= NULL
)
138 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
139 if (strcmp (bfd_get_section_name (prog_bfd
, s
), ".text") == 0)
142 text_start
= bfd_get_section_vma (prog_bfd
, s
);
143 text_end
= text_start
+ bfd_section_size (prog_bfd
, s
);
148 return (PC
<< 2) + text_start
;
155 struct hash_entry
*h
;
157 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
158 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_long 0x%x\n", ins
);
160 h
= lookup_hash (ins
, 1);
163 get_operands (h
->ops
, ins
);
164 State
.ins_type
= INS_LONG
;
165 ins_type_counters
[ (int)State
.ins_type
]++;
170 do_2_short (ins1
, ins2
, leftright
)
172 enum _leftright leftright
;
174 struct hash_entry
*h
;
175 enum _ins_type first
, second
;
178 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
179 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_2_short 0x%x (%s) -> 0x%x\n",
180 ins1
, (leftright
) ? "left" : "right", ins2
);
183 if (leftright
== LEFT_FIRST
)
187 ins_type_counters
[ (int)INS_LEFTRIGHT
]++;
193 ins_type_counters
[ (int)INS_RIGHTLEFT
]++;
196 /* Issue the first instruction */
197 h
= lookup_hash (ins1
, 0);
200 get_operands (h
->ops
, ins1
);
201 State
.ins_type
= first
;
202 ins_type_counters
[ (int)State
.ins_type
]++;
205 /* Issue the second instruction (if the PC hasn't changed) */
206 if (!State
.pc_changed
&& !State
.exception
)
208 /* finish any existing instructions */
210 h
= lookup_hash (ins2
, 0);
213 get_operands (h
->ops
, ins2
);
214 State
.ins_type
= second
;
215 ins_type_counters
[ (int)State
.ins_type
]++;
216 ins_type_counters
[ (int)INS_CYCLES
]++;
219 else if (!State
.exception
)
220 ins_type_counters
[ (int)INS_COND_JUMP
]++;
224 do_parallel (ins1
, ins2
)
227 struct hash_entry
*h1
, *h2
;
229 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
230 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_parallel 0x%x || 0x%x\n", ins1
, ins2
);
232 ins_type_counters
[ (int)INS_PARALLEL
]++;
233 h1
= lookup_hash (ins1
, 0);
236 h2
= lookup_hash (ins2
, 0);
240 if (h1
->ops
->exec_type
== PARONLY
)
242 get_operands (h1
->ops
, ins1
);
243 State
.ins_type
= INS_LEFT_COND_TEST
;
244 ins_type_counters
[ (int)State
.ins_type
]++;
248 ins_type_counters
[ (int)INS_COND_TRUE
]++;
249 get_operands (h2
->ops
, ins2
);
250 State
.ins_type
= INS_RIGHT_COND_EXE
;
251 ins_type_counters
[ (int)State
.ins_type
]++;
255 ins_type_counters
[ (int)INS_COND_FALSE
]++;
257 else if (h2
->ops
->exec_type
== PARONLY
)
259 get_operands (h2
->ops
, ins2
);
260 State
.ins_type
= INS_RIGHT_COND_TEST
;
261 ins_type_counters
[ (int)State
.ins_type
]++;
265 ins_type_counters
[ (int)INS_COND_TRUE
]++;
266 get_operands (h1
->ops
, ins1
);
267 State
.ins_type
= INS_LEFT_COND_EXE
;
268 ins_type_counters
[ (int)State
.ins_type
]++;
272 ins_type_counters
[ (int)INS_COND_FALSE
]++;
276 get_operands (h1
->ops
, ins1
);
277 State
.ins_type
= INS_LEFT_PARALLEL
;
278 ins_type_counters
[ (int)State
.ins_type
]++;
280 if (!State
.exception
)
282 get_operands (h2
->ops
, ins2
);
283 State
.ins_type
= INS_RIGHT_PARALLEL
;
284 ins_type_counters
[ (int)State
.ins_type
]++;
291 add_commas(buf
, sizeof_buf
, value
)
297 char *endbuf
= buf
+ sizeof_buf
- 1;
307 *--endbuf
= (value
% 10) + '0';
308 } while ((value
/= 10) != 0);
319 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
321 if (State
.mem
.insn
[i
])
322 free (State
.mem
.insn
[i
]);
324 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
326 if (State
.mem
.data
[i
])
327 free (State
.mem
.data
[i
]);
329 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
331 if (State
.mem
.unif
[i
])
332 free (State
.mem
.unif
[i
]);
334 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
336 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
339 /* For tracing - leave info on last access around. */
340 static char *last_segname
= "invalid";
341 static char *last_from
= "invalid";
342 static char *last_to
= "invalid";
346 IMAP0_OFFSET
= 0xff00,
347 DMAP0_OFFSET
= 0xff08,
348 DMAP2_SHADDOW
= 0xff04,
349 DMAP2_OFFSET
= 0xff0c
353 set_dmap_register (int reg_nr
, unsigned long value
)
355 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
356 + DMAP0_OFFSET
+ 2 * reg_nr
);
357 WRITE_16 (raw
, value
);
359 if ((d10v_debug
& DEBUG_MEMORY
))
361 (*d10v_callback
->printf_filtered
)
362 (d10v_callback
, "mem: dmap%d=0x%04lx\n", reg_nr
, value
);
368 dmap_register (int reg_nr
)
370 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
371 + DMAP0_OFFSET
+ 2 * reg_nr
);
372 return READ_16 (raw
);
376 set_imap_register (int reg_nr
, unsigned long value
)
378 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
379 + IMAP0_OFFSET
+ 2 * reg_nr
);
380 WRITE_16 (raw
, value
);
382 if ((d10v_debug
& DEBUG_MEMORY
))
384 (*d10v_callback
->printf_filtered
)
385 (d10v_callback
, "mem: imap%d=0x%04lx\n", reg_nr
, value
);
391 imap_register (int reg_nr
)
393 uint8
*raw
= map_memory (SIM_D10V_MEMORY_DATA
394 + IMAP0_OFFSET
+ 2 * reg_nr
);
395 return READ_16 (raw
);
410 return HELD_SP (HELD_SPU_IDX
);
419 return HELD_SP (HELD_SPI_IDX
);
423 set_spi_register (unsigned long value
)
426 SET_GPR (SP_IDX
, value
);
427 SET_HELD_SP (HELD_SPI_IDX
, value
);
431 set_spu_register (unsigned long value
)
434 SET_GPR (SP_IDX
, value
);
435 SET_HELD_SP (HELD_SPU_IDX
, value
);
438 /* Given a virtual address in the DMAP address space, translate it
439 into a physical address. */
442 sim_d10v_translate_dmap_addr (unsigned long offset
,
445 unsigned long (*dmap_register
) (int reg_nr
))
449 last_from
= "logical-data";
450 if (offset
>= DMAP_BLOCK_SIZE
* SIM_D10V_NR_DMAP_REGS
)
452 /* Logical address out side of data segments, not supported */
455 regno
= (offset
/ DMAP_BLOCK_SIZE
);
456 offset
= (offset
% DMAP_BLOCK_SIZE
);
457 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
459 /* Don't cross a BLOCK boundary */
460 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
462 map
= dmap_register (regno
);
465 /* Always maps to data memory */
466 int iospi
= (offset
/ 0x1000) % 4;
467 int iosp
= (map
>> (4 * (3 - iospi
))) % 0x10;
468 last_to
= "io-space";
469 *phys
= (SIM_D10V_MEMORY_DATA
+ (iosp
* 0x10000) + 0xc000 + offset
);
473 int sp
= ((map
& 0x3000) >> 12);
474 int segno
= (map
& 0x3ff);
477 case 0: /* 00: Unified memory */
478 *phys
= SIM_D10V_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
481 case 1: /* 01: Instruction Memory */
482 *phys
= SIM_D10V_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
483 last_to
= "chip-insn";
485 case 2: /* 10: Internal data memory */
486 *phys
= SIM_D10V_MEMORY_DATA
+ (segno
<< 16) + (regno
* DMAP_BLOCK_SIZE
) + offset
;
487 last_to
= "chip-data";
489 case 3: /* 11: Reserved */
496 /* Given a virtual address in the IMAP address space, translate it
497 into a physical address. */
500 sim_d10v_translate_imap_addr (unsigned long offset
,
503 unsigned long (*imap_register
) (int reg_nr
))
509 last_from
= "logical-insn";
510 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_D10V_NR_IMAP_REGS
))
512 /* Logical address outside of IMAP segments, not supported */
515 regno
= (offset
/ IMAP_BLOCK_SIZE
);
516 offset
= (offset
% IMAP_BLOCK_SIZE
);
517 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
519 /* Don't cross a BLOCK boundary */
520 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
522 map
= imap_register (regno
);
523 sp
= (map
& 0x3000) >> 12;
524 segno
= (map
& 0x007f);
527 case 0: /* 00: unified memory */
528 *phys
= SIM_D10V_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
531 case 1: /* 01: instruction memory */
532 *phys
= SIM_D10V_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
533 last_to
= "chip-insn";
538 case 3: /* 11: for testing - instruction memory */
539 offset
= (offset
% 0x800);
540 *phys
= SIM_D10V_MEMORY_INSN
+ offset
;
541 if (offset
+ nr_bytes
> 0x800)
542 /* don't cross VM boundary */
543 nr_bytes
= 0x800 - offset
;
544 last_to
= "test-insn";
551 sim_d10v_translate_addr (unsigned long memaddr
,
553 unsigned long *targ_addr
,
554 unsigned long (*dmap_register
) (int reg_nr
),
555 unsigned long (*imap_register
) (int reg_nr
))
561 last_from
= "unknown";
564 seg
= (memaddr
>> 24);
565 off
= (memaddr
& 0xffffffL
);
567 /* However, if we've asked to use the previous generation of segment
568 mapping, rearrange the segments as follows. */
570 if (old_segment_mapping
)
574 case 0x00: /* DMAP translated memory */
577 case 0x01: /* IMAP translated memory */
580 case 0x10: /* On-chip data memory */
583 case 0x11: /* On-chip insn memory */
586 case 0x12: /* Unified memory */
594 case 0x00: /* Physical unified memory */
595 last_from
= "phys-unified";
597 phys
= SIM_D10V_MEMORY_UNIFIED
+ off
;
598 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
599 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
602 case 0x01: /* Physical instruction memory */
603 last_from
= "phys-insn";
604 last_to
= "chip-insn";
605 phys
= SIM_D10V_MEMORY_INSN
+ off
;
606 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
607 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
610 case 0x02: /* Physical data memory segment */
611 last_from
= "phys-data";
612 last_to
= "chip-data";
613 phys
= SIM_D10V_MEMORY_DATA
+ off
;
614 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
615 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
618 case 0x10: /* in logical data address segment */
619 nr_bytes
= sim_d10v_translate_dmap_addr (off
, nr_bytes
, &phys
,
623 case 0x11: /* in logical instruction address segment */
624 nr_bytes
= sim_d10v_translate_imap_addr (off
, nr_bytes
, &phys
,
636 /* Return a pointer into the raw buffer designated by phys_addr. It
637 is assumed that the client has already ensured that the access
638 isn't going to cross a segment boundary. */
641 map_memory (unsigned phys_addr
)
646 int segment
= ((phys_addr
>> 24) & 0xff);
651 case 0x00: /* Unified memory */
653 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
654 last_segname
= "umem";
658 case 0x01: /* On-chip insn memory */
660 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
661 last_segname
= "imem";
665 case 0x02: /* On-chip data memory */
667 if ((phys_addr
& 0xff00) == 0xff00)
669 phys_addr
= (phys_addr
& 0xffff);
670 if (phys_addr
== DMAP2_SHADDOW
)
672 phys_addr
= DMAP2_OFFSET
;
673 last_segname
= "dmap";
676 last_segname
= "reg";
679 last_segname
= "dmem";
680 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
686 last_segname
= "scrap";
687 return State
.mem
.fault
;
692 *memory
= calloc (1, SEGMENT_SIZE
);
695 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Malloc failed.\n");
696 return State
.mem
.fault
;
700 offset
= (phys_addr
% SEGMENT_SIZE
);
701 raw
= *memory
+ offset
;
705 /* Transfer data to/from simulated memory. Since a bug in either the
706 simulated program or in gdb or the simulator itself may cause a
707 bogus address to be passed in, we need to do some sanity checking
708 on addresses to make sure they are within bounds. When an address
709 fails the bounds check, treat it as a zero length read/write rather
710 than aborting the entire run. */
713 xfer_mem (SIM_ADDR virt
,
714 unsigned char *buffer
,
720 while (xfered
< size
)
725 phys_size
= sim_d10v_translate_addr (virt
, size
,
732 memory
= map_memory (phys
);
735 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
737 (*d10v_callback
->printf_filtered
)
739 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
740 (write_p
? "write" : "read"),
741 phys_size
, virt
, last_from
,
743 (long) memory
, last_segname
);
749 memcpy (memory
, buffer
, phys_size
);
753 memcpy (buffer
, memory
, phys_size
);
766 sim_write (sd
, addr
, buffer
, size
)
769 unsigned char *buffer
;
772 /* FIXME: this should be performing a virtual transfer */
773 return xfer_mem( addr
, buffer
, size
, 1);
777 sim_read (sd
, addr
, buffer
, size
)
780 unsigned char *buffer
;
783 /* FIXME: this should be performing a virtual transfer */
784 return xfer_mem( addr
, buffer
, size
, 0);
789 sim_open (kind
, callback
, abfd
, argv
)
791 host_callback
*callback
;
796 struct hash_entry
*h
;
797 static int init_p
= 0;
801 d10v_callback
= callback
;
803 old_segment_mapping
= 0;
805 /* NOTE: This argument parsing is only effective when this function
806 is called by GDB. Standalone argument parsing is handled by
808 for (p
= argv
+ 1; *p
; ++p
)
810 if (strcmp (*p
, "-oldseg") == 0)
811 old_segment_mapping
= 1;
813 else if (strcmp (*p
, "-t") == 0)
815 else if (strncmp (*p
, "-t", 2) == 0)
816 d10v_debug
= atoi (*p
+ 2);
819 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unsupported option(s): %s\n",*p
);
822 /* put all the opcodes in the hash table */
825 for (s
= Simops
; s
->func
; s
++)
827 h
= &hash_table
[hash(s
->opcode
,s
->format
)];
829 /* go to the last entry in the chain */
835 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
837 perror ("malloc failure");
843 h
->opcode
= s
->opcode
;
844 h
->size
= s
->is_long
;
848 /* reset the processor state */
849 if (!State
.mem
.data
[0])
851 sim_create_inferior ((SIM_DESC
) 1, NULL
, NULL
, NULL
);
853 /* Fudge our descriptor. */
859 sim_close (sd
, quitting
)
863 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
865 bfd_close (prog_bfd
);
867 prog_bfd_was_opened_p
= 0;
875 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile %d\n",n
);
879 sim_set_profile_size (n
)
882 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile_size %d\n",n
);
886 dmem_addr (uint16 offset
)
892 /* Note: DMEM address range is 0..0x10000. Calling code can compute
893 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
894 is uint16 this is modulo'ed onto 0x0e5d. */
896 phys_size
= sim_d10v_translate_dmap_addr (offset
, 1, &phys
,
900 mem
= State
.mem
.fault
;
903 mem
= map_memory (phys
);
905 if ((d10v_debug
& DEBUG_MEMORY
))
907 (*d10v_callback
->printf_filtered
)
909 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
911 phys
, phys_size
, last_to
,
912 (long) mem
, last_segname
);
919 imem_addr (uint32 offset
)
923 int phys_size
= sim_d10v_translate_imap_addr (offset
, 1, &phys
, imap_register
);
926 return State
.mem
.fault
;
928 mem
= map_memory (phys
);
930 if ((d10v_debug
& DEBUG_MEMORY
))
932 (*d10v_callback
->printf_filtered
)
934 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
936 phys
, phys_size
, last_to
,
937 (long) mem
, last_segname
);
943 static int stop_simulator
= 0;
954 /* Run (or resume) the program. */
956 sim_resume (sd
, step
, siggnal
)
963 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
970 iaddr
= imem_addr ((uint32
)PC
<< 2);
971 if (iaddr
== State
.mem
.fault
)
973 State
.exception
= SIGBUS
;
977 inst
= get_longword( iaddr
);
979 State
.pc_changed
= 0;
980 ins_type_counters
[ (int)INS_CYCLES
]++;
982 switch (inst
& 0xC0000000)
985 /* long instruction */
986 do_long (inst
& 0x3FFFFFFF);
990 do_2_short ( inst
& 0x7FFF, (inst
& 0x3FFF8000) >> 15, RIGHT_FIRST
);
994 do_2_short ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF, LEFT_FIRST
);
997 do_parallel ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF);
1001 /* If the PC of the current instruction matches RPT_E then
1002 schedule a branch to the loop start. If one of those
1003 instructions happens to be a branch, than that instruction
1005 if (!State
.pc_changed
)
1007 if (PSW_RP
&& PC
== RPT_E
)
1009 /* Note: The behavour of a branch instruction at RPT_E
1010 is implementation dependant, this simulator takes the
1011 branch. Branching to RPT_E is valid, the instruction
1012 must be executed before the loop is taken. */
1021 SET_RPT_C (RPT_C
- 1);
1029 /* Check for a breakpoint trap on this instruction. This
1030 overrides any pending branches or loops */
1031 if (PSW_DB
&& PC
== IBA
)
1035 SET_PSW (PSW
& PSW_SM_BIT
);
1036 SET_PC (SDBT_VECTOR_START
);
1039 /* Writeback all the DATA / PC changes */
1042 #ifdef NEED_UI_LOOP_HOOK
1043 if (ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1045 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1048 #endif /* NEED_UI_LOOP_HOOK */
1050 while ( !State
.exception
&& !stop_simulator
);
1052 if (step
&& !State
.exception
)
1053 State
.exception
= SIGTRAP
;
1063 sim_resume (sd
, 0, 0);
1068 sim_info (sd
, verbose
)
1077 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
1078 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
1079 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
1080 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
1081 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
1083 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
1084 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
1085 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
1086 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
1087 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
1089 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
1090 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
1091 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
1092 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
1093 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
1094 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
1095 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
1096 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
1097 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
1098 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
1100 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
1101 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
1102 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
1103 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
1104 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
1105 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
1107 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1108 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1109 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
1110 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
1111 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
1112 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
1113 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
1115 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1116 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1117 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
1118 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
1119 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
1120 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
1121 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
1124 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1125 "executed %*s long instruction(s)\n",
1126 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1129 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1130 "executed %*s parallel instruction(s)\n",
1131 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1134 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1135 "executed %*s instruction(s) encoded L->R\n",
1136 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1139 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1140 "executed %*s instruction(s) encoded R->L\n",
1141 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1144 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1145 "executed %*s unknown instruction(s)\n",
1146 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
1149 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1150 "executed %*s instruction(s) due to EXExxx condition being true\n",
1151 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
1154 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1155 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1156 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
1159 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1160 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1161 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
1163 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1164 "executed %*s cycle(s)\n",
1165 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1167 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1168 "executed %*s total instructions\n",
1169 size
, add_commas (buf1
, sizeof (buf1
), total
));
1173 sim_create_inferior (sd
, abfd
, argv
, env
)
1179 bfd_vma start_address
;
1181 /* reset all state information */
1182 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
1186 /* a hack to set r0/r1 with argc/argv */
1187 /* some high memory that won't be overwritten by the stack soon */
1188 bfd_vma addr
= 0x7C00;
1193 int size
= strlen (argv
[i
]) + 1;
1194 SW (addr
+ 2*i
, addr
+ p
);
1195 sim_write (sd
, addr
+ 0, argv
[i
], size
);
1205 start_address
= bfd_get_start_address (abfd
);
1207 start_address
= 0xffc0 << 2;
1210 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1212 SET_CREG (PC_CR
, start_address
>> 2);
1214 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1215 initializes imap0 and imap1 to 0x1000 as part of its ROM
1217 if (old_segment_mapping
)
1219 /* External memory startup. This is the HARD reset state. */
1220 set_imap_register (0, 0x0000);
1221 set_imap_register (1, 0x007f);
1222 set_dmap_register (0, 0x2000);
1223 set_dmap_register (1, 0x2000);
1224 set_dmap_register (2, 0x0000); /* Old DMAP */
1225 set_dmap_register (3, 0x0000);
1229 /* Internal memory startup. This is the ROM intialized state. */
1230 set_imap_register (0, 0x1000);
1231 set_imap_register (1, 0x1000);
1232 set_dmap_register (0, 0x2000);
1233 set_dmap_register (1, 0x2000);
1234 set_dmap_register (2, 0x0000); /* Old DMAP, Value is not 0x2000 */
1235 set_dmap_register (3, 0x0000);
1244 sim_set_callbacks (p
)
1251 sim_stop_reason (sd
, reason
, sigrc
)
1253 enum sim_stop
*reason
;
1256 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1258 switch (State
.exception
)
1260 case SIG_D10V_STOP
: /* stop instruction */
1261 *reason
= sim_exited
;
1265 case SIG_D10V_EXIT
: /* exit trap */
1266 *reason
= sim_exited
;
1270 default: /* some signal */
1271 *reason
= sim_stopped
;
1272 if (stop_simulator
&& !State
.exception
)
1275 *sigrc
= State
.exception
;
1283 sim_fetch_register (sd
, rn
, memory
, length
)
1286 unsigned char *memory
;
1292 else if (rn
>= SIM_D10V_R0_REGNUM
1293 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1295 WRITE_16 (memory
, GPR (rn
- SIM_D10V_R0_REGNUM
));
1298 else if (rn
>= SIM_D10V_CR0_REGNUM
1299 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1301 WRITE_16 (memory
, CREG (rn
- SIM_D10V_CR0_REGNUM
));
1304 else if (rn
>= SIM_D10V_A0_REGNUM
1305 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1307 WRITE_64 (memory
, ACC (rn
- SIM_D10V_A0_REGNUM
));
1310 else if (rn
== SIM_D10V_SPI_REGNUM
)
1312 /* PSW_SM indicates that the current SP is the USER
1314 WRITE_16 (memory
, spi_register ());
1317 else if (rn
== SIM_D10V_SPU_REGNUM
)
1319 /* PSW_SM indicates that the current SP is the USER
1321 WRITE_16 (memory
, spu_register ());
1324 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1325 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1327 WRITE_16 (memory
, imap_register (rn
- SIM_D10V_IMAP0_REGNUM
));
1330 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1331 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1333 WRITE_16 (memory
, dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
));
1342 sim_store_register (sd
, rn
, memory
, length
)
1345 unsigned char *memory
;
1351 else if (rn
>= SIM_D10V_R0_REGNUM
1352 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1354 SET_GPR (rn
- SIM_D10V_R0_REGNUM
, READ_16 (memory
));
1357 else if (rn
>= SIM_D10V_CR0_REGNUM
1358 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1360 SET_CREG (rn
- SIM_D10V_CR0_REGNUM
, READ_16 (memory
));
1363 else if (rn
>= SIM_D10V_A0_REGNUM
1364 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1366 SET_ACC (rn
- SIM_D10V_A0_REGNUM
, READ_64 (memory
) & MASK40
);
1369 else if (rn
== SIM_D10V_SPI_REGNUM
)
1371 /* PSW_SM indicates that the current SP is the USER
1373 set_spi_register (READ_16 (memory
));
1376 else if (rn
== SIM_D10V_SPU_REGNUM
)
1378 set_spu_register (READ_16 (memory
));
1381 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1382 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1384 set_imap_register (rn
- SIM_D10V_IMAP0_REGNUM
, READ_16(memory
));
1387 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1388 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1390 set_dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
, READ_16(memory
));
1401 sim_do_command (sd
, cmd
)
1405 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_do_command: %s\n",cmd
);
1409 sim_load (sd
, prog
, abfd
, from_tty
)
1415 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1417 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1419 bfd_close (prog_bfd
);
1420 prog_bfd_was_opened_p
= 0;
1422 prog_bfd
= sim_load_file (sd
, myname
, d10v_callback
, prog
, abfd
,
1423 sim_kind
== SIM_OPEN_DEBUG
,
1424 1/*LMA*/, sim_write
);
1425 if (prog_bfd
== NULL
)
1427 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.058083 seconds and 4 git commands to generate.