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); */
978 SET_HW_PSW ((PSW
& (PSW_F0_BIT
| PSW_F1_BIT
| PSW_C_BIT
)));
979 JMP (AE_VECTOR_START
);
989 iaddr
= imem_addr ((uint32
)PC
<< 2);
990 if (iaddr
== State
.mem
.fault
)
992 State
.exception
= SIGBUS
;
996 inst
= get_longword( iaddr
);
998 State
.pc_changed
= 0;
999 ins_type_counters
[ (int)INS_CYCLES
]++;
1001 switch (inst
& 0xC0000000)
1004 /* long instruction */
1005 do_long (inst
& 0x3FFFFFFF);
1009 do_2_short ( inst
& 0x7FFF, (inst
& 0x3FFF8000) >> 15, RIGHT_FIRST
);
1013 do_2_short ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF, LEFT_FIRST
);
1016 do_parallel ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF);
1020 /* If the PC of the current instruction matches RPT_E then
1021 schedule a branch to the loop start. If one of those
1022 instructions happens to be a branch, than that instruction
1024 if (!State
.pc_changed
)
1026 if (PSW_RP
&& PC
== RPT_E
)
1028 /* Note: The behavour of a branch instruction at RPT_E
1029 is implementation dependant, this simulator takes the
1030 branch. Branching to RPT_E is valid, the instruction
1031 must be executed before the loop is taken. */
1040 SET_RPT_C (RPT_C
- 1);
1048 /* Check for a breakpoint trap on this instruction. This
1049 overrides any pending branches or loops */
1050 if (PSW_DB
&& PC
== IBA
)
1054 SET_PSW (PSW
& PSW_SM_BIT
);
1055 SET_PC (SDBT_VECTOR_START
);
1058 /* Writeback all the DATA / PC changes */
1061 #ifdef NEED_UI_LOOP_HOOK
1062 if (ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1064 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1067 #endif /* NEED_UI_LOOP_HOOK */
1069 while ( !State
.exception
&& !stop_simulator
);
1071 if (step
&& !State
.exception
)
1072 State
.exception
= SIGTRAP
;
1076 sim_set_trace (void)
1084 sim_info (sd
, verbose
)
1093 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
1094 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
1095 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
1096 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
1097 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
1099 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
1100 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
1101 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
1102 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
1103 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
1105 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
1106 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
1107 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
1108 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
1109 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
1110 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
1111 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
1112 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
1113 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
1114 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
1116 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
1117 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
1118 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
1119 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
1120 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
1121 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
1123 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1124 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1125 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
1126 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
1127 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
1128 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
1129 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
1131 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1132 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1133 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
1134 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
1135 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
1136 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
1137 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
1140 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1141 "executed %*s long instruction(s)\n",
1142 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1145 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1146 "executed %*s parallel instruction(s)\n",
1147 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1150 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1151 "executed %*s instruction(s) encoded L->R\n",
1152 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1155 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1156 "executed %*s instruction(s) encoded R->L\n",
1157 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1160 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1161 "executed %*s unknown instruction(s)\n",
1162 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
1165 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1166 "executed %*s instruction(s) due to EXExxx condition being true\n",
1167 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
1170 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1171 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1172 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
1175 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1176 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1177 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
1179 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1180 "executed %*s cycle(s)\n",
1181 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1183 (*d10v_callback
->printf_filtered
) (d10v_callback
,
1184 "executed %*s total instructions\n",
1185 size
, add_commas (buf1
, sizeof (buf1
), total
));
1189 sim_create_inferior (sd
, abfd
, argv
, env
)
1195 bfd_vma start_address
;
1197 /* reset all state information */
1198 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
1202 /* a hack to set r0/r1 with argc/argv */
1203 /* some high memory that won't be overwritten by the stack soon */
1204 bfd_vma addr
= 0x7C00;
1209 int size
= strlen (argv
[i
]) + 1;
1210 SW (addr
+ 2*i
, addr
+ p
);
1211 sim_write (sd
, addr
+ 0, argv
[i
], size
);
1221 start_address
= bfd_get_start_address (abfd
);
1223 start_address
= 0xffc0 << 2;
1226 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1228 SET_CREG (PC_CR
, start_address
>> 2);
1230 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1231 initializes imap0 and imap1 to 0x1000 as part of its ROM
1233 if (old_segment_mapping
)
1235 /* External memory startup. This is the HARD reset state. */
1236 set_imap_register (0, 0x0000);
1237 set_imap_register (1, 0x007f);
1238 set_dmap_register (0, 0x2000);
1239 set_dmap_register (1, 0x2000);
1240 set_dmap_register (2, 0x0000); /* Old DMAP */
1241 set_dmap_register (3, 0x0000);
1245 /* Internal memory startup. This is the ROM intialized state. */
1246 set_imap_register (0, 0x1000);
1247 set_imap_register (1, 0x1000);
1248 set_dmap_register (0, 0x2000);
1249 set_dmap_register (1, 0x2000);
1250 set_dmap_register (2, 0x0000); /* Old DMAP, Value is not 0x2000 */
1251 set_dmap_register (3, 0x0000);
1260 sim_set_callbacks (p
)
1267 sim_stop_reason (sd
, reason
, sigrc
)
1269 enum sim_stop
*reason
;
1272 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1274 switch (State
.exception
)
1276 case SIG_D10V_STOP
: /* stop instruction */
1277 *reason
= sim_exited
;
1281 case SIG_D10V_EXIT
: /* exit trap */
1282 *reason
= sim_exited
;
1287 *reason
= sim_stopped
;
1295 default: /* some signal */
1296 *reason
= sim_stopped
;
1297 if (stop_simulator
&& !State
.exception
)
1300 *sigrc
= State
.exception
;
1308 sim_fetch_register (sd
, rn
, memory
, length
)
1311 unsigned char *memory
;
1317 else if (rn
>= SIM_D10V_R0_REGNUM
1318 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1320 WRITE_16 (memory
, GPR (rn
- SIM_D10V_R0_REGNUM
));
1323 else if (rn
>= SIM_D10V_CR0_REGNUM
1324 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1326 WRITE_16 (memory
, CREG (rn
- SIM_D10V_CR0_REGNUM
));
1329 else if (rn
>= SIM_D10V_A0_REGNUM
1330 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1332 WRITE_64 (memory
, ACC (rn
- SIM_D10V_A0_REGNUM
));
1335 else if (rn
== SIM_D10V_SPI_REGNUM
)
1337 /* PSW_SM indicates that the current SP is the USER
1339 WRITE_16 (memory
, spi_register ());
1342 else if (rn
== SIM_D10V_SPU_REGNUM
)
1344 /* PSW_SM indicates that the current SP is the USER
1346 WRITE_16 (memory
, spu_register ());
1349 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1350 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1352 WRITE_16 (memory
, imap_register (rn
- SIM_D10V_IMAP0_REGNUM
));
1355 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1356 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1358 WRITE_16 (memory
, dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
));
1367 sim_store_register (sd
, rn
, memory
, length
)
1370 unsigned char *memory
;
1376 else if (rn
>= SIM_D10V_R0_REGNUM
1377 && rn
< SIM_D10V_R0_REGNUM
+ SIM_D10V_NR_R_REGS
)
1379 SET_GPR (rn
- SIM_D10V_R0_REGNUM
, READ_16 (memory
));
1382 else if (rn
>= SIM_D10V_CR0_REGNUM
1383 && rn
< SIM_D10V_CR0_REGNUM
+ SIM_D10V_NR_CR_REGS
)
1385 SET_CREG (rn
- SIM_D10V_CR0_REGNUM
, READ_16 (memory
));
1388 else if (rn
>= SIM_D10V_A0_REGNUM
1389 && rn
< SIM_D10V_A0_REGNUM
+ SIM_D10V_NR_A_REGS
)
1391 SET_ACC (rn
- SIM_D10V_A0_REGNUM
, READ_64 (memory
) & MASK40
);
1394 else if (rn
== SIM_D10V_SPI_REGNUM
)
1396 /* PSW_SM indicates that the current SP is the USER
1398 set_spi_register (READ_16 (memory
));
1401 else if (rn
== SIM_D10V_SPU_REGNUM
)
1403 set_spu_register (READ_16 (memory
));
1406 else if (rn
>= SIM_D10V_IMAP0_REGNUM
1407 && rn
< SIM_D10V_IMAP0_REGNUM
+ SIM_D10V_NR_IMAP_REGS
)
1409 set_imap_register (rn
- SIM_D10V_IMAP0_REGNUM
, READ_16(memory
));
1412 else if (rn
>= SIM_D10V_DMAP0_REGNUM
1413 && rn
< SIM_D10V_DMAP0_REGNUM
+ SIM_D10V_NR_DMAP_REGS
)
1415 set_dmap_register (rn
- SIM_D10V_DMAP0_REGNUM
, READ_16(memory
));
1426 sim_do_command (sd
, cmd
)
1430 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_do_command: %s\n",cmd
);
1434 sim_load (sd
, prog
, abfd
, from_tty
)
1440 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1442 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1444 bfd_close (prog_bfd
);
1445 prog_bfd_was_opened_p
= 0;
1447 prog_bfd
= sim_load_file (sd
, myname
, d10v_callback
, prog
, abfd
,
1448 sim_kind
== SIM_OPEN_DEBUG
,
1449 1/*LMA*/, sim_write
);
1450 if (prog_bfd
== NULL
)
1452 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.057986 seconds and 4 git commands to generate.