039bd177a6644405a03a8f85885a38ba586c00fd
6 #include "mn10300_sim.h"
11 #include "sim-assert.h"
37 host_callback
*mn10300_callback
;
39 static SIM_OPEN_KIND sim_kind
;
44 static void dispatch
PARAMS ((uint32
, uint32
, int));
45 static long hash
PARAMS ((long));
46 static void init_system
PARAMS ((void));
51 struct hash_entry
*next
;
60 static int max_mem
= 0;
61 struct hash_entry hash_table
[MAX_HASH
+1];
64 /* This probably doesn't do a very good job at bucket filling, but
70 /* These are one byte insns, we special case these since, in theory,
71 they should be the most heavily used. */
72 if ((insn
& 0xffffff00) == 0)
117 /* These are two byte insns */
118 if ((insn
& 0xffff0000) == 0)
120 if ((insn
& 0xf000) == 0x2000
121 || (insn
& 0xf000) == 0x5000)
122 return ((insn
& 0xfc00) >> 8) & 0x7f;
124 if ((insn
& 0xf000) == 0x4000)
125 return ((insn
& 0xf300) >> 8) & 0x7f;
127 if ((insn
& 0xf000) == 0x8000
128 || (insn
& 0xf000) == 0x9000
129 || (insn
& 0xf000) == 0xa000
130 || (insn
& 0xf000) == 0xb000)
131 return ((insn
& 0xf000) >> 8) & 0x7f;
133 if ((insn
& 0xff00) == 0xf000
134 || (insn
& 0xff00) == 0xf100
135 || (insn
& 0xff00) == 0xf200
136 || (insn
& 0xff00) == 0xf500
137 || (insn
& 0xff00) == 0xf600)
138 return ((insn
& 0xfff0) >> 4) & 0x7f;
140 if ((insn
& 0xf000) == 0xc000)
141 return ((insn
& 0xff00) >> 8) & 0x7f;
143 return ((insn
& 0xffc0) >> 6) & 0x7f;
146 /* These are three byte insns. */
147 if ((insn
& 0xff000000) == 0)
149 if ((insn
& 0xf00000) == 0x000000)
150 return ((insn
& 0xf30000) >> 16) & 0x7f;
152 if ((insn
& 0xf00000) == 0x200000
153 || (insn
& 0xf00000) == 0x300000)
154 return ((insn
& 0xfc0000) >> 16) & 0x7f;
156 if ((insn
& 0xff0000) == 0xf80000)
157 return ((insn
& 0xfff000) >> 12) & 0x7f;
159 if ((insn
& 0xff0000) == 0xf90000)
160 return ((insn
& 0xfffc00) >> 10) & 0x7f;
162 return ((insn
& 0xff0000) >> 16) & 0x7f;
165 /* These are four byte or larger insns. */
166 if ((insn
& 0xf0000000) == 0xf0000000)
167 return ((insn
& 0xfff00000) >> 20) & 0x7f;
169 return ((insn
& 0xff000000) >> 24) & 0x7f;
173 dispatch (insn
, extension
, length
)
178 struct hash_entry
*h
;
180 h
= &hash_table
[hash(insn
)];
182 while ((insn
& h
->mask
) != h
->opcode
183 || (length
!= h
->ops
->length
))
187 (*mn10300_callback
->printf_filtered
) (mn10300_callback
,
188 "ERROR looking up hash for 0x%x, PC=0x%x\n", insn
, PC
);
199 /* Now call the right function. */
200 (h
->ops
->func
)(insn
, extension
);
212 max_mem
= 1 << power
;
213 State
.mem
= (uint8
*) calloc (1, 1 << power
);
216 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "Allocation of main memory failed.\n");
229 sim_write (sd
, addr
, buffer
, size
)
232 unsigned char *buffer
;
239 for (i
= 0; i
< size
; i
++)
240 store_byte (addr
+ i
, buffer
[i
]);
245 /* Compare two opcode table entries for qsort. */
247 compare_simops (arg1
, arg2
)
251 unsigned long code1
= ((struct simops
*)arg1
)->opcode
;
252 unsigned long code2
= ((struct simops
*)arg2
)->opcode
;
263 sim_open (kind
, cb
, abfd
, argv
)
270 struct hash_entry
*h
;
274 mn10300_callback
= cb
;
276 /* Sort the opcode array from smallest opcode to largest.
277 This will generally improve simulator performance as the smaller
278 opcodes are generally preferred to the larger opcodes. */
279 for (i
= 0, s
= Simops
; s
->func
; s
++, i
++)
281 qsort (Simops
, i
, sizeof (Simops
[0]), compare_simops
);
286 for (p
= argv
+ 1; *p
; ++p
)
288 if (strcmp (*p
, "-E") == 0)
289 ++p
; /* ignore endian spec */
292 if (strcmp (*p
, "-t") == 0)
293 mn10300_debug
= DEBUG
;
296 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "ERROR: unsupported option(s): %s\n",*p
);
299 /* put all the opcodes in the hash table */
300 for (s
= Simops
; s
->func
; s
++)
302 h
= &hash_table
[hash(s
->opcode
)];
304 /* go to the last entry in the chain */
307 /* Don't insert the same opcode more than once. */
308 if (h
->opcode
== s
->opcode
309 && h
->mask
== s
->mask
316 /* Don't insert the same opcode more than once. */
317 if (h
->opcode
== s
->opcode
318 && h
->mask
== s
->mask
324 h
->next
= calloc(1,sizeof(struct hash_entry
));
329 h
->opcode
= s
->opcode
;
336 /* fudge our descriptor for now */
342 sim_close (sd
, quitting
)
353 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "sim_set_profile %d\n", n
);
357 sim_set_profile_size (n
)
360 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "sim_set_profile_size %d\n", n
);
371 sim_resume (sd
, step
, siggnal
)
377 struct hash_entry
*h
;
380 State
.exception
= SIGTRAP
;
388 unsigned long insn
, extension
;
390 /* Fetch the current instruction. */
391 inst
= load_mem_big (PC
, 2);
394 /* Using a giant case statement may seem like a waste because of the
395 code/rodata size the table itself will consume. However, using
396 a giant case statement speeds up the simulator by 10-15% by avoiding
397 cascading if/else statements or cascading case statements. */
399 switch ((inst
>> 8) & 0xff)
401 /* All the single byte insns except 0x80, 0x90, 0xa0, 0xb0
402 which must be handled specially. */
505 insn
= (inst
>> 8) & 0xff;
507 dispatch (insn
, extension
, 1);
510 /* Special cases where dm == dn is used to encode a different
530 dispatch (insn
, extension
, 2);
581 insn
= (inst
>> 8) & 0xff;
583 dispatch (insn
, extension
, 1);
586 /* The two byte instructions. */
633 dispatch (insn
, extension
, 2);
636 /* The three byte insns with a 16bit operand in little endian
671 insn
= load_byte (PC
);
673 insn
|= load_half (PC
+ 1);
675 dispatch (insn
, extension
, 3);
678 /* The three byte insns without 16bit operand. */
683 insn
= load_mem_big (PC
, 3);
685 dispatch (insn
, extension
, 3);
688 /* Four byte insns. */
691 if ((inst
& 0xfffc) == 0xfaf0
692 || (inst
& 0xfffc) == 0xfaf4
693 || (inst
& 0xfffc) == 0xfaf8)
694 insn
= load_mem_big (PC
, 4);
699 insn
|= load_half (PC
+ 2);
702 dispatch (insn
, extension
, 4);
705 /* Five byte insns. */
707 insn
= load_byte (PC
);
709 insn
|= (load_half (PC
+ 1) << 8);
710 insn
|= load_byte (PC
+ 3);
711 extension
= load_byte (PC
+ 4);
712 dispatch (insn
, extension
, 5);
716 insn
= load_byte (PC
);
718 extension
= load_word (PC
+ 1);
719 insn
|= (extension
& 0xffffff00) >> 8;
721 dispatch (insn
, extension
, 5);
724 /* Six byte insns. */
728 extension
= load_word (PC
+ 2);
729 insn
|= ((extension
& 0xffff0000) >> 16);
731 dispatch (insn
, extension
, 6);
735 insn
= load_byte (PC
) << 24;
736 extension
= load_word (PC
+ 1);
737 insn
|= ((extension
>> 8) & 0xffffff);
738 extension
= (extension
& 0xff) << 16;
739 extension
|= load_byte (PC
+ 5) << 8;
740 extension
|= load_byte (PC
+ 6);
741 dispatch (insn
, extension
, 7);
746 extension
= load_word (PC
+ 2);
747 insn
|= ((extension
>> 16) & 0xffff);
749 extension
&= 0xffff00;
750 extension
|= load_byte (PC
+ 6);
751 dispatch (insn
, extension
, 7);
758 while (!State
.exception
);
763 for (i
= 0; i
< MAX_HASH
; i
++)
765 struct hash_entry
*h
;
768 printf("hash 0x%x:\n", i
);
772 printf("h->opcode = 0x%x, count = 0x%x\n", h
->opcode
, h
->count
);
789 mn10300_debug
= DEBUG
;
791 sim_resume (sd
, 0, 0);
796 sim_info (sd
, verbose
)
800 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "sim_info\n");
804 sim_create_inferior (sd
, abfd
, argv
, env
)
811 PC
= bfd_get_start_address (abfd
);
818 sim_set_callbacks (p
)
821 mn10300_callback
= p
;
824 /* All the code for exiting, signals, etc needs to be revamped.
826 This is enough to get c-torture limping though. */
829 sim_stop_reason (sd
, reason
, sigrc
)
831 enum sim_stop
*reason
;
835 *reason
= sim_exited
;
837 *reason
= sim_stopped
;
838 if (State
.exception
== SIGQUIT
)
841 *sigrc
= State
.exception
;
845 sim_read (sd
, addr
, buffer
, size
)
848 unsigned char *buffer
;
852 for (i
= 0; i
< size
; i
++)
853 buffer
[i
] = load_byte (addr
+ i
);
859 sim_do_command (sd
, cmd
)
863 (*mn10300_callback
->printf_filtered
) (mn10300_callback
, "\"%s\" is not a valid mn10300 simulator command.\n", cmd
);
867 sim_load (sd
, prog
, abfd
, from_tty
)
873 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
876 prog_bfd
= sim_load_file (sd
, myname
, mn10300_callback
, prog
, abfd
,
877 sim_kind
== SIM_OPEN_DEBUG
,
879 if (prog_bfd
== NULL
)
882 bfd_close (prog_bfd
);
885 #endif /* not WITH_COMMON */
890 /* For compatibility */
893 /* mn10300 interrupt model */
908 char *interrupt_names
[] = {
922 do_interrupt (sd
, data
)
927 char **interrupt_name
= (char**)data
;
928 enum interrupt_type inttype
;
929 inttype
= (interrupt_name
- STATE_WATCHPOINTS (sd
)->interrupt_names
);
931 /* For a hardware reset, drop everything and jump to the start
933 if (inttype
== int_reset
)
938 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
941 /* Deliver an NMI when allowed */
942 if (inttype
== int_nmi
)
946 /* We're already working on an NMI, so this one must wait
947 around until the previous one is done. The processor
948 ignores subsequent NMIs, so we don't need to count them.
949 Just keep re-scheduling a single NMI until it manages to
951 if (STATE_CPU (sd
, 0)->pending_nmi
!= NULL
)
952 sim_events_deschedule (sd
, STATE_CPU (sd
, 0)->pending_nmi
);
953 STATE_CPU (sd
, 0)->pending_nmi
=
954 sim_events_schedule (sd
, 1, do_interrupt
, data
);
959 /* NMI can be delivered. Do not deschedule pending_nmi as
960 that, if still in the event queue, is a second NMI that
961 needs to be delivered later. */
964 /* Set the FECC part of the ECR. */
971 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
975 /* deliver maskable interrupt when allowed */
976 if (inttype
> int_nmi
&& inttype
< num_int_types
)
978 if ((PSW
& PSW_NP
) || (PSW
& PSW_ID
))
980 /* Can't deliver this interrupt, reschedule it for later */
981 sim_events_schedule (sd
, 1, do_interrupt
, data
);
989 /* Disable further interrupts. */
991 /* Indicate that we're doing interrupt not exception processing. */
993 /* Clear the EICC part of the ECR, will set below. */
1022 /* Should never be possible. */
1023 sim_engine_abort (sd
, NULL
, NULL_CIA
,
1024 "do_interrupt - internal error - bad switch");
1028 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1031 /* some other interrupt? */
1032 sim_engine_abort (sd
, NULL
, NULL_CIA
,
1033 "do_interrupt - internal error - interrupt %d unknown",
1038 /* These default values correspond to expected usage for the chip. */
1041 sim_open (kind
, cb
, abfd
, argv
)
1047 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
1049 mn10300_callback
= cb
;
1051 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
1053 /* for compatibility */
1056 /* FIXME: should be better way of setting up interrupts */
1057 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
1058 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
1059 STATE_WATCHPOINTS (sd
)->interrupt_handler
= do_interrupt
;
1060 STATE_WATCHPOINTS (sd
)->interrupt_names
= interrupt_names
;
1062 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
1065 /* Allocate core managed memory */
1067 /* "Mirror" the ROM addresses below 1MB. */
1068 sim_do_command (sd
, "memory region 0,0x100000");
1070 /* getopt will print the error message so we just have to exit if this fails.
1071 FIXME: Hmmm... in the case of gdb we need getopt to call
1073 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1075 /* Uninstall the modules to avoid memory leaks,
1076 file descriptor leaks, etc. */
1077 sim_module_uninstall (sd
);
1081 /* check for/establish the a reference program image */
1082 if (sim_analyze_program (sd
,
1083 (STATE_PROG_ARGV (sd
) != NULL
1084 ? *STATE_PROG_ARGV (sd
)
1088 sim_module_uninstall (sd
);
1092 /* establish any remaining configuration options */
1093 if (sim_config (sd
) != SIM_RC_OK
)
1095 sim_module_uninstall (sd
);
1099 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
1101 /* Uninstall the modules to avoid memory leaks,
1102 file descriptor leaks, etc. */
1103 sim_module_uninstall (sd
);
1108 /* set machine specific configuration */
1109 /* STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
1110 /* | PSW_CY | PSW_OV | PSW_S | PSW_Z); */
1117 sim_close (sd
, quitting
)
1121 sim_module_uninstall (sd
);
1126 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1128 struct _bfd
*prog_bfd
;
1132 memset (&State
, 0, sizeof (State
));
1133 if (prog_bfd
!= NULL
) {
1134 PC
= bfd_get_start_address (prog_bfd
);
1138 CIA_SET (STATE_CPU (sd
, 0), (unsigned64
) PC
);
1144 sim_do_command (sd
, cmd
)
1148 char *mm_cmd
= "memory-map";
1149 char *int_cmd
= "interrupt";
1151 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1153 if (strncmp (cmd
, mm_cmd
, strlen (mm_cmd
) == 0))
1154 sim_io_eprintf (sd
, "`memory-map' command replaced by `sim memory'\n");
1155 else if (strncmp (cmd
, int_cmd
, strlen (int_cmd
)) == 0)
1156 sim_io_eprintf (sd
, "`interrupt' command replaced by `sim watch'\n");
1158 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);
1161 #endif /* WITH_COMMON */
1163 /* FIXME These would more efficient to use than load_mem/store_mem,
1164 but need to be changed to use the memory map. */
1178 return (a
[1] << 8) + (a
[0]);
1186 return (a
[3]<<24) + (a
[2]<<16) + (a
[1]<<8) + (a
[0]);
1190 put_byte (addr
, data
)
1199 put_half (addr
, data
)
1205 a
[1] = (data
>> 8) & 0xff;
1209 put_word (addr
, data
)
1215 a
[1] = (data
>> 8) & 0xff;
1216 a
[2] = (data
>> 16) & 0xff;
1217 a
[3] = (data
>> 24) & 0xff;
1221 sim_fetch_register (sd
, rn
, memory
, length
)
1224 unsigned char *memory
;
1227 put_word (memory
, State
.regs
[rn
]);
1232 sim_store_register (sd
, rn
, memory
, length
)
1235 unsigned char *memory
;
1238 State
.regs
[rn
] = get_word (memory
);
This page took 0.05744 seconds and 4 git commands to generate.