o Wordwrap usage messages from sim-options
[binutils-gdb.git] / sim / v850 / interp.c
1 #include <signal.h>
2 #include "sim-main.h"
3 #include "sim-options.h"
4 #include "v850_sim.h"
5
6 #ifdef HAVE_STDLIB_H
7 #include <stdlib.h>
8 #endif
9
10 #ifdef HAVE_STRING_H
11 #include <string.h>
12 #else
13 #ifdef HAVE_STRINGS_H
14 #include <strings.h>
15 #endif
16 #endif
17
18 #include "bfd.h"
19
20 #ifndef INLINE
21 #ifdef __GNUC__
22 #define INLINE inline
23 #else
24 #define INLINE
25 #endif
26 #endif
27
28
29 /* For compatibility */
30 SIM_DESC simulator;
31
32
33
34 /* v850 interrupt model */
35
36 enum interrupt_type
37 {
38 int_reset,
39 int_nmi,
40 int_intov1,
41 int_intp10,
42 int_intp11,
43 int_intp12,
44 int_intp13,
45 int_intcm4,
46 num_int_types
47 };
48
49 char *interrupt_names[] = {
50 "reset",
51 "nmi",
52 "intov1",
53 "intp10",
54 "intp11",
55 "intp12",
56 "intp13",
57 "intcm4",
58 NULL
59 };
60
61 static void
62 do_interrupt (sd, data)
63 SIM_DESC sd;
64 void *data;
65 {
66 char **interrupt_name = (char**)data;
67 enum interrupt_type inttype;
68 inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
69 /* Disable further interrupts. */
70 PSW |= PSW_ID;
71 /* Indicate that we're doing interrupt not exception processing. */
72 PSW &= ~PSW_EP;
73 if (inttype == int_reset)
74 {
75 PC = 0;
76 PSW = 0x20;
77 ECR = 0;
78 /* (Might be useful to init other regs with random values.) */
79 }
80 else if (inttype == int_nmi)
81 {
82 if (PSW & PSW_NP)
83 {
84 /* We're already working on an NMI, so this one must wait
85 around until the previous one is done. The processor
86 ignores subsequent NMIs, so we don't need to count them. */
87 State.pending_nmi = 1;
88 }
89 else
90 {
91 FEPC = PC;
92 FEPSW = PSW;
93 /* Set the FECC part of the ECR. */
94 ECR &= 0x0000ffff;
95 ECR |= 0x10;
96 PSW |= PSW_NP;
97 PC = 0x10;
98 }
99 }
100 else
101 {
102 EIPC = PC;
103 EIPSW = PSW;
104 /* Clear the EICC part of the ECR, will set below. */
105 ECR &= 0xffff0000;
106 switch (inttype)
107 {
108 case int_intov1:
109 PC = 0x80;
110 ECR |= 0x80;
111 break;
112 case int_intp10:
113 PC = 0x90;
114 ECR |= 0x90;
115 break;
116 case int_intp11:
117 PC = 0xa0;
118 ECR |= 0xa0;
119 break;
120 case int_intp12:
121 PC = 0xb0;
122 ECR |= 0xb0;
123 break;
124 case int_intp13:
125 PC = 0xc0;
126 ECR |= 0xc0;
127 break;
128 case int_intcm4:
129 PC = 0xd0;
130 ECR |= 0xd0;
131 break;
132 default:
133 /* Should never be possible. */
134 abort ();
135 break;
136 }
137 }
138 }
139
140 /* These default values correspond to expected usage for the chip. */
141
142 int v850_debug;
143
144 uint32 OP[4];
145
146 static long hash PARAMS ((long));
147 #if 0
148 static void do_format_1_2 PARAMS ((uint32));
149 static void do_format_3 PARAMS ((uint32));
150 static void do_format_4 PARAMS ((uint32));
151 static void do_format_5 PARAMS ((uint32));
152 static void do_format_6 PARAMS ((uint32));
153 static void do_format_7 PARAMS ((uint32));
154 static void do_format_8 PARAMS ((uint32));
155 static void do_format_9_10 PARAMS ((uint32));
156 #endif
157
158 #define MAX_HASH 63
159
160 struct hash_entry
161 {
162 struct hash_entry *next;
163 unsigned long opcode;
164 unsigned long mask;
165 struct simops *ops;
166 };
167
168 struct hash_entry hash_table[MAX_HASH+1];
169
170
171 static INLINE long
172 hash(insn)
173 long insn;
174 {
175 if ( (insn & 0x0600) == 0
176 || (insn & 0x0700) == 0x0200
177 || (insn & 0x0700) == 0x0600
178 || (insn & 0x0780) == 0x0700)
179 return (insn & 0x07e0) >> 5;
180
181 if ((insn & 0x0700) == 0x0300
182 || (insn & 0x0700) == 0x0400
183 || (insn & 0x0700) == 0x0500)
184 return (insn & 0x0780) >> 7;
185
186 if ((insn & 0x07c0) == 0x0780)
187 return (insn & 0x07c0) >> 6;
188
189 return (insn & 0x07e0) >> 5;
190 }
191
192 #if 0
193 static struct hash_entry *
194 lookup_hash (sd, ins)
195 SIM_DESC sd;
196 uint32 ins;
197 {
198 struct hash_entry *h;
199
200 h = &hash_table[hash(ins)];
201
202 while ((ins & h->mask) != h->opcode)
203 {
204 if (h->next == NULL)
205 {
206 sim_io_error (sd, "ERROR looking up hash for 0x%lx, PC=0x%lx",
207 (long) ins, (long) PC);
208 }
209 h = h->next;
210 }
211 return (h);
212 }
213 #endif
214
215 SIM_DESC
216 sim_open (kind, cb, abfd, argv)
217 SIM_OPEN_KIND kind;
218 host_callback *cb;
219 struct _bfd *abfd;
220 char **argv;
221 {
222 char *buf;
223 SIM_DESC sd = sim_state_alloc (kind, cb);
224 #if 0
225 struct simops *s;
226 struct hash_entry *h;
227 #endif
228
229 /* for compatibility */
230 simulator = sd;
231
232 /* FIXME: should be better way of setting up interrupts */
233 STATE_WATCHPOINTS (sd)->pc = &(PC);
234 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
235 STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
236 STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
237
238 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
239 return 0;
240
241 /* Allocate core managed memory */
242 /* "Mirror" the ROM addresses below 1MB. */
243 asprintf (&buf, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
244 sim_do_command (sd, buf);
245 free (buf);
246 /* Chunk of ram adjacent to rom */
247 asprintf (&buf, "memory region 0x100000,0x%lx", V850_LOW_END - 0x100000);
248 sim_do_command (sd, buf);
249 free (buf);
250 /* peripheral I/O region - mirror 1K across 4k (0x1000) */
251 sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
252 /* similarly if in the internal RAM region */
253 sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
254
255 /* getopt will print the error message so we just have to exit if this fails.
256 FIXME: Hmmm... in the case of gdb we need getopt to call
257 print_filtered. */
258 if (sim_parse_args (sd, argv) != SIM_RC_OK)
259 {
260 /* Uninstall the modules to avoid memory leaks,
261 file descriptor leaks, etc. */
262 sim_module_uninstall (sd);
263 return 0;
264 }
265
266 /* check for/establish the a reference program image */
267 if (sim_analyze_program (sd,
268 (STATE_PROG_ARGV (sd) != NULL
269 ? *STATE_PROG_ARGV (sd)
270 : NULL),
271 abfd) != SIM_RC_OK)
272 {
273 sim_module_uninstall (sd);
274 return 0;
275 }
276
277 /* establish any remaining configuration options */
278 if (sim_config (sd) != SIM_RC_OK)
279 {
280 sim_module_uninstall (sd);
281 return 0;
282 }
283
284 if (sim_post_argv_init (sd) != SIM_RC_OK)
285 {
286 /* Uninstall the modules to avoid memory leaks,
287 file descriptor leaks, etc. */
288 sim_module_uninstall (sd);
289 return 0;
290 }
291
292 #if 0
293 /* put all the opcodes in the hash table */
294 for (s = Simops; s->func; s++)
295 {
296 h = &hash_table[hash(s->opcode)];
297
298 /* go to the last entry in the chain */
299 while (h->next)
300 h = h->next;
301
302 if (h->ops)
303 {
304 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
305 h = h->next;
306 }
307 h->ops = s;
308 h->mask = s->mask;
309 h->opcode = s->opcode;
310 }
311 #endif
312
313 return sd;
314 }
315
316
317 void
318 sim_close (sd, quitting)
319 SIM_DESC sd;
320 int quitting;
321 {
322 sim_module_uninstall (sd);
323 }
324
325 int
326 sim_stop (sd)
327 SIM_DESC sd;
328 {
329 return 0;
330 }
331
332 #if 0
333 void
334 sim_engine_run (sd, next_cpu_nr, siggnal)
335 SIM_DESC sd;
336 int next_cpu_nr;
337 int siggnal;
338 {
339 uint32 inst;
340 SIM_ADDR oldpc;
341
342 while (1)
343 {
344 struct hash_entry * h;
345 /* Fetch the current instruction. */
346 inst = RLW (PC);
347 oldpc = PC;
348
349 h = lookup_hash (sd, inst);
350 OP[0] = inst & 0x1f;
351 OP[1] = (inst >> 11) & 0x1f;
352 OP[2] = (inst >> 16) & 0xffff;
353 OP[3] = inst;
354
355 /* fprintf (stderr, "PC = %x, SP = %x\n", PC, SP ); */
356
357 if (inst == 0)
358 {
359 fprintf (stderr, "NOP encountered!\n");
360 break;
361 }
362
363 PC += h->ops->func ();
364
365 if (oldpc == PC)
366 {
367 sim_io_eprintf (sd, "simulator loop at %lx\n", (long) PC );
368 break;
369 }
370
371 if (sim_events_tick (sd))
372 {
373 sim_events_process (sd);
374 }
375 }
376 }
377 #endif
378
379 #if 0
380 int
381 sim_trace (sd)
382 SIM_DESC sd;
383 {
384 #ifdef DEBUG
385 v850_debug = DEBUG;
386 #endif
387 sim_resume (sd, 0, 0);
388 return 1;
389 }
390 #endif
391
392 void
393 sim_info (sd, verbose)
394 SIM_DESC sd;
395 int verbose;
396 {
397 /* do nothing */
398 }
399
400 SIM_RC
401 sim_create_inferior (sd, prog_bfd, argv, env)
402 SIM_DESC sd;
403 struct _bfd *prog_bfd;
404 char **argv;
405 char **env;
406 {
407 memset (&State, 0, sizeof (State));
408 if (prog_bfd != NULL)
409 PC = bfd_get_start_address (prog_bfd);
410 return SIM_RC_OK;
411 }
412
413 void
414 sim_fetch_register (sd, rn, memory)
415 SIM_DESC sd;
416 int rn;
417 unsigned char *memory;
418 {
419 *(unsigned32*)memory = H2T_4 (State.regs[rn]);
420 }
421
422 void
423 sim_store_register (sd, rn, memory)
424 SIM_DESC sd;
425 int rn;
426 unsigned char *memory;
427 {
428 State.regs[rn] = T2H_4 (*(unsigned32*)memory);
429 }
430
431 void
432 sim_do_command (sd, cmd)
433 SIM_DESC sd;
434 char *cmd;
435 {
436 char *mm_cmd = "memory-map";
437 char *int_cmd = "interrupt";
438
439 if (sim_args_command (sd, cmd) != SIM_RC_OK)
440 {
441 if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
442 sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
443 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
444 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
445 else
446 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
447 }
448 }