5 #include "sim-options.h"
7 #include "mn10300_sim.h"
12 #include "sim-assert.h"
38 host_callback *mn10300_callback;
43 static void dispatch PARAMS ((uint32, uint32, int));
44 static long hash PARAMS ((long));
45 static void init_system PARAMS ((void));
47 static SIM_OPEN_KIND sim_kind;
53 struct hash_entry *next;
62 static int max_mem = 0;
63 struct hash_entry hash_table[MAX_HASH+1];
66 /* This probably doesn't do a very good job at bucket filling, but
72 /* These are one byte insns, we special case these since, in theory,
73 they should be the most heavily used. */
74 if ((insn & 0xffffff00) == 0)
119 /* These are two byte insns */
120 if ((insn & 0xffff0000) == 0)
122 if ((insn & 0xf000) == 0x2000
123 || (insn & 0xf000) == 0x5000)
124 return ((insn & 0xfc00) >> 8) & 0x7f;
126 if ((insn & 0xf000) == 0x4000)
127 return ((insn & 0xf300) >> 8) & 0x7f;
129 if ((insn & 0xf000) == 0x8000
130 || (insn & 0xf000) == 0x9000
131 || (insn & 0xf000) == 0xa000
132 || (insn & 0xf000) == 0xb000)
133 return ((insn & 0xf000) >> 8) & 0x7f;
135 if ((insn & 0xff00) == 0xf000
136 || (insn & 0xff00) == 0xf100
137 || (insn & 0xff00) == 0xf200
138 || (insn & 0xff00) == 0xf500
139 || (insn & 0xff00) == 0xf600)
140 return ((insn & 0xfff0) >> 4) & 0x7f;
142 if ((insn & 0xf000) == 0xc000)
143 return ((insn & 0xff00) >> 8) & 0x7f;
145 return ((insn & 0xffc0) >> 6) & 0x7f;
148 /* These are three byte insns. */
149 if ((insn & 0xff000000) == 0)
151 if ((insn & 0xf00000) == 0x000000)
152 return ((insn & 0xf30000) >> 16) & 0x7f;
154 if ((insn & 0xf00000) == 0x200000
155 || (insn & 0xf00000) == 0x300000)
156 return ((insn & 0xfc0000) >> 16) & 0x7f;
158 if ((insn & 0xff0000) == 0xf80000)
159 return ((insn & 0xfff000) >> 12) & 0x7f;
161 if ((insn & 0xff0000) == 0xf90000)
162 return ((insn & 0xfffc00) >> 10) & 0x7f;
164 return ((insn & 0xff0000) >> 16) & 0x7f;
167 /* These are four byte or larger insns. */
168 if ((insn & 0xf0000000) == 0xf0000000)
169 return ((insn & 0xfff00000) >> 20) & 0x7f;
171 return ((insn & 0xff000000) >> 24) & 0x7f;
175 dispatch (insn, extension, length)
180 struct hash_entry *h;
182 h = &hash_table[hash(insn)];
184 while ((insn & h->mask) != h->opcode
185 || (length != h->ops->length))
189 (*mn10300_callback->printf_filtered) (mn10300_callback,
190 "ERROR looking up hash for 0x%x, PC=0x%x\n", insn, PC);
201 /* Now call the right function. */
202 (h->ops->func)(insn, extension);
214 max_mem = 1 << power;
215 State.mem = (uint8 *) calloc (1, 1 << power);
218 (*mn10300_callback->printf_filtered) (mn10300_callback, "Allocation of main memory failed.\n");
231 sim_write (sd, addr, buffer, size)
234 unsigned char *buffer;
241 for (i = 0; i < size; i++)
242 store_byte (addr + i, buffer[i]);
247 /* Compare two opcode table entries for qsort. */
249 compare_simops (arg1, arg2)
253 unsigned long code1 = ((struct simops *)arg1)->opcode;
254 unsigned long code2 = ((struct simops *)arg2)->opcode;
265 sim_open (kind, cb, abfd, argv)
272 struct hash_entry *h;
276 mn10300_callback = cb;
278 /* Sort the opcode array from smallest opcode to largest.
279 This will generally improve simulator performance as the smaller
280 opcodes are generally preferred to the larger opcodes. */
281 for (i = 0, s = Simops; s->func; s++, i++)
283 qsort (Simops, i, sizeof (Simops[0]), compare_simops);
288 for (p = argv + 1; *p; ++p)
290 if (strcmp (*p, "-E") == 0)
291 ++p; /* ignore endian spec */
294 if (strcmp (*p, "-t") == 0)
295 mn10300_debug = DEBUG;
298 (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR: unsupported option(s): %s\n",*p);
301 /* put all the opcodes in the hash table */
302 for (s = Simops; s->func; s++)
304 h = &hash_table[hash(s->opcode)];
306 /* go to the last entry in the chain */
309 /* Don't insert the same opcode more than once. */
310 if (h->opcode == s->opcode
311 && h->mask == s->mask
318 /* Don't insert the same opcode more than once. */
319 if (h->opcode == s->opcode
320 && h->mask == s->mask
326 h->next = calloc(1,sizeof(struct hash_entry));
331 h->opcode = s->opcode;
338 /* fudge our descriptor for now */
344 sim_close (sd, quitting)
355 (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile %d\n", n);
359 sim_set_profile_size (n)
362 (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile_size %d\n", n);
373 sim_resume (sd, step, siggnal)
379 struct hash_entry *h;
382 State.exception = SIGTRAP;
390 unsigned long insn, extension;
392 /* Fetch the current instruction. */
393 inst = load_mem_big (PC, 2);
396 /* Using a giant case statement may seem like a waste because of the
397 code/rodata size the table itself will consume. However, using
398 a giant case statement speeds up the simulator by 10-15% by avoiding
399 cascading if/else statements or cascading case statements. */
401 switch ((inst >> 8) & 0xff)
403 /* All the single byte insns except 0x80, 0x90, 0xa0, 0xb0
404 which must be handled specially. */
507 insn = (inst >> 8) & 0xff;
509 dispatch (insn, extension, 1);
512 /* Special cases where dm == dn is used to encode a different
532 dispatch (insn, extension, 2);
583 insn = (inst >> 8) & 0xff;
585 dispatch (insn, extension, 1);
588 /* The two byte instructions. */
635 dispatch (insn, extension, 2);
638 /* The three byte insns with a 16bit operand in little endian
673 insn = load_byte (PC);
675 insn |= load_half (PC + 1);
677 dispatch (insn, extension, 3);
680 /* The three byte insns without 16bit operand. */
685 insn = load_mem_big (PC, 3);
687 dispatch (insn, extension, 3);
690 /* Four byte insns. */
693 if ((inst & 0xfffc) == 0xfaf0
694 || (inst & 0xfffc) == 0xfaf4
695 || (inst & 0xfffc) == 0xfaf8)
696 insn = load_mem_big (PC, 4);
701 insn |= load_half (PC + 2);
704 dispatch (insn, extension, 4);
707 /* Five byte insns. */
709 insn = load_byte (PC);
711 insn |= (load_half (PC + 1) << 8);
712 insn |= load_byte (PC + 3);
713 extension = load_byte (PC + 4);
714 dispatch (insn, extension, 5);
718 insn = load_byte (PC);
720 extension = load_word (PC + 1);
721 insn |= (extension & 0xffffff00) >> 8;
723 dispatch (insn, extension, 5);
726 /* Six byte insns. */
730 extension = load_word (PC + 2);
731 insn |= ((extension & 0xffff0000) >> 16);
733 dispatch (insn, extension, 6);
737 insn = load_byte (PC) << 24;
738 extension = load_word (PC + 1);
739 insn |= ((extension >> 8) & 0xffffff);
740 extension = (extension & 0xff) << 16;
741 extension |= load_byte (PC + 5) << 8;
742 extension |= load_byte (PC + 6);
743 dispatch (insn, extension, 7);
748 extension = load_word (PC + 2);
749 insn |= ((extension >> 16) & 0xffff);
751 extension &= 0xffff00;
752 extension |= load_byte (PC + 6);
753 dispatch (insn, extension, 7);
760 while (!State.exception);
765 for (i = 0; i < MAX_HASH; i++)
767 struct hash_entry *h;
770 printf("hash 0x%x:\n", i);
774 printf("h->opcode = 0x%x, count = 0x%x\n", h->opcode, h->count);
791 mn10300_debug = DEBUG;
793 sim_resume (sd, 0, 0);
798 sim_info (sd, verbose)
802 (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_info\n");
806 sim_create_inferior (sd, abfd, argv, env)
813 PC = bfd_get_start_address (abfd);
820 sim_set_callbacks (p)
823 mn10300_callback = p;
826 /* All the code for exiting, signals, etc needs to be revamped.
828 This is enough to get c-torture limping though. */
831 sim_stop_reason (sd, reason, sigrc)
833 enum sim_stop *reason;
837 *reason = sim_exited;
839 *reason = sim_stopped;
840 if (State.exception == SIGQUIT)
843 *sigrc = State.exception;
847 sim_read (sd, addr, buffer, size)
850 unsigned char *buffer;
854 for (i = 0; i < size; i++)
855 buffer[i] = load_byte (addr + i);
861 sim_do_command (sd, cmd)
865 (*mn10300_callback->printf_filtered) (mn10300_callback, "\"%s\" is not a valid mn10300 simulator command.\n", cmd);
869 sim_load (sd, prog, abfd, from_tty)
875 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
878 prog_bfd = sim_load_file (sd, myname, mn10300_callback, prog, abfd,
879 sim_kind == SIM_OPEN_DEBUG,
881 if (prog_bfd == NULL)
884 bfd_close (prog_bfd);
887 #endif /* not WITH_COMMON */
892 /* For compatibility */
895 /* mn10300 interrupt model */
910 char *interrupt_names[] = {
924 do_interrupt (sd, data)
929 char **interrupt_name = (char**)data;
930 enum interrupt_type inttype;
931 inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
933 /* For a hardware reset, drop everything and jump to the start
935 if (inttype == int_reset)
940 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
943 /* Deliver an NMI when allowed */
944 if (inttype == int_nmi)
948 /* We're already working on an NMI, so this one must wait
949 around until the previous one is done. The processor
950 ignores subsequent NMIs, so we don't need to count them.
951 Just keep re-scheduling a single NMI until it manages to
953 if (STATE_CPU (sd, 0)->pending_nmi != NULL)
954 sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
955 STATE_CPU (sd, 0)->pending_nmi =
956 sim_events_schedule (sd, 1, do_interrupt, data);
961 /* NMI can be delivered. Do not deschedule pending_nmi as
962 that, if still in the event queue, is a second NMI that
963 needs to be delivered later. */
966 /* Set the FECC part of the ECR. */
973 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
977 /* deliver maskable interrupt when allowed */
978 if (inttype > int_nmi && inttype < num_int_types)
980 if ((PSW & PSW_NP) || (PSW & PSW_ID))
982 /* Can't deliver this interrupt, reschedule it for later */
983 sim_events_schedule (sd, 1, do_interrupt, data);
991 /* Disable further interrupts. */
993 /* Indicate that we're doing interrupt not exception processing. */
995 /* Clear the EICC part of the ECR, will set below. */
1024 /* Should never be possible. */
1025 sim_engine_abort (sd, NULL, NULL_CIA,
1026 "do_interrupt - internal error - bad switch");
1030 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1033 /* some other interrupt? */
1034 sim_engine_abort (sd, NULL, NULL_CIA,
1035 "do_interrupt - internal error - interrupt %d unknown",
1040 /* These default values correspond to expected usage for the chip. */
1043 sim_open (kind, cb, abfd, argv)
1049 SIM_DESC sd = sim_state_alloc (kind, cb);
1050 mn10300_callback = cb;
1052 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1054 /* for compatibility */
1057 /* FIXME: should be better way of setting up interrupts */
1058 STATE_WATCHPOINTS (sd)->pc = &(PC);
1059 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
1060 STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
1061 STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
1063 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1066 /* Allocate core managed memory */
1068 /* "Mirror" the ROM addresses below 1MB. */
1069 sim_do_command (sd, "memory region 0,0x100000");
1071 /* getopt will print the error message so we just have to exit if this fails.
1072 FIXME: Hmmm... in the case of gdb we need getopt to call
1074 if (sim_parse_args (sd, argv) != SIM_RC_OK)
1076 /* Uninstall the modules to avoid memory leaks,
1077 file descriptor leaks, etc. */
1078 sim_module_uninstall (sd);
1082 /* check for/establish the a reference program image */
1083 if (sim_analyze_program (sd,
1084 (STATE_PROG_ARGV (sd) != NULL
1085 ? *STATE_PROG_ARGV (sd)
1089 sim_module_uninstall (sd);
1093 /* establish any remaining configuration options */
1094 if (sim_config (sd) != SIM_RC_OK)
1096 sim_module_uninstall (sd);
1100 if (sim_post_argv_init (sd) != SIM_RC_OK)
1102 /* Uninstall the modules to avoid memory leaks,
1103 file descriptor leaks, etc. */
1104 sim_module_uninstall (sd);
1109 /* set machine specific configuration */
1110 /* STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
1111 /* | PSW_CY | PSW_OV | PSW_S | PSW_Z); */
1118 sim_close (sd, quitting)
1122 sim_module_uninstall (sd);
1127 sim_create_inferior (sd, prog_bfd, argv, env)
1129 struct _bfd *prog_bfd;
1133 memset (&State, 0, sizeof (State));
1134 if (prog_bfd != NULL) {
1135 PC = bfd_get_start_address (prog_bfd);
1139 CIA_SET (STATE_CPU (sd, 0), (unsigned64) PC);
1145 sim_do_command (sd, cmd)
1149 char *mm_cmd = "memory-map";
1150 char *int_cmd = "interrupt";
1152 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1154 if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
1155 sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
1156 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
1157 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
1159 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
1162 #endif /* WITH_COMMON */
1164 /* FIXME These would more efficient to use than load_mem/store_mem,
1165 but need to be changed to use the memory map. */
1179 return (a[1] << 8) + (a[0]);
1187 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
1191 put_byte (addr, data)
1200 put_half (addr, data)
1206 a[1] = (data >> 8) & 0xff;
1210 put_word (addr, data)
1216 a[1] = (data >> 8) & 0xff;
1217 a[2] = (data >> 16) & 0xff;
1218 a[3] = (data >> 24) & 0xff;
1222 sim_fetch_register (sd, rn, memory, length)
1225 unsigned char *memory;
1228 put_word (memory, State.regs[rn]);
1233 sim_store_register (sd, rn, memory, length)
1236 unsigned char *memory;
1239 State.regs[rn] = get_word (memory);