* interp.c: Delete unused global variable "OP".
[external/binutils.git] / sim / mn10300 / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4
5 #include "mn10300_sim.h"
6
7 #ifndef INLINE
8 #ifdef __GNUC__
9 #define INLINE inline
10 #else
11 #define INLINE
12 #endif
13 #endif
14
15 host_callback *mn10300_callback;
16 int mn10300_debug;
17
18 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int));
19 static long hash PARAMS ((long));
20 static void init_system PARAMS ((void));
21 #define MAX_HASH  63
22
23 struct hash_entry
24 {
25   struct hash_entry *next;
26   long opcode;
27   long mask;
28   struct simops *ops;
29 };
30
31 struct hash_entry hash_table[MAX_HASH+1];
32
33
34 /* This probably doesn't do a very good job at bucket filling, but
35    it's simple... */
36 static INLINE long 
37 hash(insn)
38      long insn;
39 {
40   /* These are one byte insns.  */
41   if ((insn & 0xffffff00) == 0)
42     {
43       if ((insn & 0xf0) == 0x00
44           || (insn & 0xf0) == 0x40)
45         return (insn & 0xf3) & 0x3f;
46
47       if ((insn & 0xf0) == 0x10
48           || (insn & 0xf0) == 0x30
49           || (insn & 0xf0) == 0x50)
50         return (insn & 0xfc) & 0x3f;
51
52       if ((insn & 0xf0) == 0x60
53           || (insn & 0xf0) == 0x70
54           || (insn & 0xf0) == 0x80
55           || (insn & 0xf0) == 0x90
56           || (insn & 0xf0) == 0xa0
57           || (insn & 0xf0) == 0xb0
58           || (insn & 0xf0) == 0xe0)
59         return (insn & 0xf0) & 0x3f;
60
61       return (insn & 0xff) & 0x3f;
62     }
63
64   /* These are two byte insns */
65   if ((insn & 0xffff0000) == 0)
66     {
67       if ((insn & 0xf000) == 0x2000
68           || (insn & 0xf000) == 0x5000)
69         return ((insn & 0xfc00) >> 8) & 0x3f;
70
71       if ((insn & 0xf000) == 0x4000)
72         return ((insn & 0xf300) >> 8) & 0x3f;
73
74       if ((insn & 0xf000) == 0x8000
75           || (insn & 0xf000) == 0x9000
76           || (insn & 0xf000) == 0xa000
77           || (insn & 0xf000) == 0xb000)
78         return ((insn & 0xf000) >> 8) & 0x3f;
79
80       return ((insn & 0xff00) >> 8) & 0x3f;
81     }
82
83   /* These are three byte insns.  */
84   if ((insn & 0xff000000) == 0)
85     {
86       if ((insn & 0xf00000) == 0x000000)
87         return ((insn & 0xf30000) >> 16) & 0x3f;
88
89       if ((insn & 0xf00000) == 0x200000
90           || (insn & 0xf00000) == 0x300000)
91         return ((insn & 0xfc0000) >> 16) & 0x3f;
92
93         return ((insn & 0xff0000) >> 16) & 0x3f;
94     }
95
96   /* These are four byte or larger insns.  */
97   return ((insn & 0xff000000) >> 24) & 0x3f;
98 }
99
100 static struct hash_entry *
101 lookup_hash (ins, length)
102      uint32 ins;
103      int length;
104 {
105   struct hash_entry *h;
106
107   h = &hash_table[hash(ins)];
108
109   while ((ins & h->mask) != h->opcode
110          || (length != h->ops->length))
111     {
112       if (h->next == NULL)
113         {
114           (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC);
115           exit(1);
116         }
117       h = h->next;
118     }
119   return (h);
120 }
121
122 /* FIXME These would more efficient to use than load_mem/store_mem,
123    but need to be changed to use the memory map.  */
124
125 uint8
126 get_byte (x)
127      uint8 *x;
128 {
129   return *x;
130 }
131
132 uint16
133 get_half (x)
134      uint8 *x;
135 {
136   uint8 *a = x;
137   return (a[1] << 8) + (a[0]);
138 }
139
140 uint32
141 get_word (x)
142       uint8 *x;
143 {
144   uint8 *a = x;
145   return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
146 }
147
148 void
149 put_byte (addr, data)
150      uint8 *addr;
151      uint8 data;
152 {
153   uint8 *a = addr;
154   a[0] = data;
155 }
156
157 void
158 put_half (addr, data)
159      uint8 *addr;
160      uint16 data;
161 {
162   uint8 *a = addr;
163   a[0] = data & 0xff;
164   a[1] = (data >> 8) & 0xff;
165 }
166
167 void
168 put_word (addr, data)
169      uint8 *addr;
170      uint32 data;
171 {
172   uint8 *a = addr;
173   a[0] = data & 0xff;
174   a[1] = (data >> 8) & 0xff;
175   a[2] = (data >> 16) & 0xff;
176   a[3] = (data >> 24) & 0xff;
177 }
178
179
180 uint32
181 load_mem_big (addr, len)
182      SIM_ADDR addr;
183      int len;
184 {
185   uint8 *p = addr + State.mem;
186
187   switch (len)
188     {
189     case 1:
190       return p[0];
191     case 2:
192       return p[0] << 8 | p[1];
193     case 3:
194       return p[0] << 16 | p[1] << 8 | p[2];
195     case 4:
196       return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
197     default:
198       abort ();
199     }
200 }
201
202 uint32
203 load_mem (addr, len)
204      SIM_ADDR addr;
205      int len;
206 {
207   uint8 *p = addr + State.mem;
208
209   switch (len)
210     {
211     case 1:
212       return p[0];
213     case 2:
214       return p[1] << 8 | p[0];
215     case 3:
216       return p[2] << 16 | p[1] << 8 | p[0];
217     case 4:
218       return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
219     default:
220       abort ();
221     }
222 }
223
224 void
225 store_mem (addr, len, data)
226      SIM_ADDR addr;
227      int len;
228      uint32 data;
229 {
230   uint8 *p = addr + State.mem;
231
232   switch (len)
233     {
234     case 1:
235       p[0] = data;
236       return;
237     case 2:
238       p[0] = data;
239       p[1] = data >> 8;
240       return;
241     case 4:
242       p[0] = data;
243       p[1] = data >> 8;
244       p[2] = data >> 16;
245       p[3] = data >> 24;
246       return;
247     default:
248       abort ();
249     }
250 }
251
252 void
253 sim_size (power)
254      int power;
255
256 {
257   if (State.mem)
258     free (State.mem);
259
260   State.mem = (uint8 *) calloc (1,  1 << power);
261   if (!State.mem)
262     {
263       (*mn10300_callback->printf_filtered) (mn10300_callback, "Allocation of main memory failed.\n");
264       exit (1);
265     }
266 }
267
268 static void
269 init_system ()
270 {
271   if (!State.mem)
272     sim_size(18);
273 }
274
275 int
276 sim_write (addr, buffer, size)
277      SIM_ADDR addr;
278      unsigned char *buffer;
279      int size;
280 {
281   int i;
282
283   init_system ();
284
285   for (i = 0; i < size; i++)
286     store_mem (addr + i, 1, buffer[i]);
287
288   return size;
289 }
290
291 void
292 sim_open (args)
293      char *args;
294 {
295   struct simops *s;
296   struct hash_entry *h;
297   if (args != NULL)
298     {
299 #ifdef DEBUG
300       if (strcmp (args, "-t") == 0)
301         mn10300_debug = DEBUG;
302       else
303 #endif
304         (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR: unsupported option(s): %s\n",args);
305     }
306
307   /* put all the opcodes in the hash table */
308   for (s = Simops; s->func; s++)
309     {
310       h = &hash_table[hash(s->opcode)];
311       
312       /* go to the last entry in the chain */
313       while (h->next)
314           h = h->next;
315
316       if (h->ops)
317         {
318           h->next = calloc(1,sizeof(struct hash_entry));
319           h = h->next;
320         }
321       h->ops = s;
322       h->mask = s->mask;
323       h->opcode = s->opcode;
324     }
325 }
326
327
328 void
329 sim_close (quitting)
330      int quitting;
331 {
332   /* nothing to do */
333 }
334
335 void
336 sim_set_profile (n)
337      int n;
338 {
339   (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile %d\n", n);
340 }
341
342 void
343 sim_set_profile_size (n)
344      int n;
345 {
346   (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_set_profile_size %d\n", n);
347 }
348
349 void
350 sim_resume (step, siggnal)
351      int step, siggnal;
352 {
353   uint32 inst;
354   reg_t oldpc;
355   struct hash_entry *h;
356
357   if (step)
358     State.exception = SIGTRAP;
359   else
360     State.exception = 0;
361
362   do
363     {
364       unsigned long insn, extension;
365
366       /* Fetch the current instruction.  */
367       inst = load_mem_big (PC, 1);
368       oldpc = PC;
369
370       /* These are one byte insns.  */
371       if ((inst & 0xf3) == 0x00
372           || (inst & 0xf0) == 0x10
373           || (inst & 0xfc) == 0x3c
374           || (inst & 0xf3) == 0x41
375           || (inst & 0xf3) == 0x40
376           || (inst & 0xfc) == 0x50
377           || (inst & 0xfc) == 0x54
378           || (inst & 0xf0) == 0x60
379           || (inst & 0xf0) == 0x70
380           || ((inst & 0xf0) == 0x80
381               && (inst & 0x0c) >> 2 != (inst & 0x03))
382           || ((inst & 0xf0) == 0x90
383               && (inst & 0x0c) >> 2 != (inst & 0x03))
384           || ((inst & 0xf0) == 0xa0
385               && (inst & 0x0c) >> 2 != (inst & 0x03))
386           || ((inst & 0xf0) == 0xb0
387               && (inst & 0x0c) >> 2 != (inst & 0x03))
388           || (inst & 0xff) == 0xcb
389           || (inst & 0xfc) == 0xd0
390           || (inst & 0xfc) == 0xd4
391           || (inst & 0xfc) == 0xd8
392           || (inst & 0xf0) == 0xe0)
393         {
394           insn = inst;
395           h = lookup_hash (insn, 1);
396           extension = 0;
397           (h->ops->func)(insn, extension);
398           PC += 1;
399         }
400
401       /* These are two byte insns.  */
402       else if ((inst & 0xf0) == 0x80
403                || (inst & 0xf0) == 0x90
404                || (inst & 0xf0) == 0xa0
405                || (inst & 0xf0) == 0xb0
406                || (inst & 0xfc) == 0x20
407                || (inst & 0xfc) == 0x28
408                || (inst & 0xf3) == 0x43
409                || (inst & 0xf3) == 0x42
410                || (inst & 0xfc) == 0x58
411                || (inst & 0xfc) == 0x5c
412                || ((inst & 0xf0) == 0xc0
413                    && (inst & 0xff) != 0xcb
414                    && (inst & 0xff) != 0xcc
415                    && (inst & 0xff) != 0xcd)
416                || (inst & 0xff) == 0xf0
417                || (inst & 0xff) == 0xf1
418                || (inst & 0xff) == 0xf2
419                || (inst & 0xff) == 0xf3
420                || (inst & 0xff) == 0xf4
421                || (inst & 0xff) == 0xf5
422                || (inst & 0xff) == 0xf6)
423         {
424           insn = load_mem_big (PC, 2);
425           h = lookup_hash (insn, 2);
426           extension = 0;
427           (h->ops->func)(insn, extension);
428           PC += 2;
429         }
430
431       /* These are three byte insns.  */
432       else if ((inst & 0xff) == 0xf8
433                || (inst & 0xff) == 0xcc 
434                || (inst & 0xff) == 0xf9
435                || (inst & 0xf3) == 0x01
436                || (inst & 0xf3) == 0x02
437                || (inst & 0xf3) == 0x03
438                || (inst & 0xfc) == 0x24
439                || (inst & 0xfc) == 0x2c
440                || (inst & 0xfc) == 0x30
441                || (inst & 0xfc) == 0x34
442                || (inst & 0xfc) == 0x38
443                || (inst & 0xff) == 0xde
444                || (inst & 0xff) == 0xdf
445                || (inst & 0xff) == 0xcc)
446         {
447           insn = load_mem_big (PC, 3);
448           h = lookup_hash (insn, 3);
449           extension = 0;
450           (h->ops->func)(insn, extension);
451           PC += 3;
452         }
453
454       /* These are four byte insns.  */
455       else if ((inst & 0xff) == 0xfa
456                || (inst & 0xff) == 0xfb)
457         {
458           insn = load_mem_big (PC, 4);
459           h = lookup_hash (insn, 4);
460           extension = 0;
461           (h->ops->func)();
462           PC += 4;
463         }
464
465       /* These are five byte insns.  */
466       else if ((inst & 0xff) == 0xcd
467                || (inst & 0xff) == 0xdc)
468         {
469           insn = load_mem_big (PC, 4);
470           h = lookup_hash (insn, 5);
471           extension = load_mem_big (PC + 4, 1);
472           (h->ops->func)(insn, extension);
473           PC += 5;
474         }
475
476       /* These are six byte insns.  */
477       else if ((inst & 0xff) == 0xfd
478                || (inst & 0xff) == 0xfc)
479         {
480           insn = load_mem_big (PC, 4);
481           h = lookup_hash (insn, 6);
482           extension = load_mem_big (PC + 4, 2);
483           (h->ops->func)(insn, extension);
484           PC += 6;
485         }
486
487       /* Else its a seven byte insns (in theory).  */
488       else
489         {
490           insn = load_mem_big (PC, 4);
491           h = lookup_hash (insn, 7);
492           extension = load_mem_big (PC + 4, 3);
493           (h->ops->func)(insn, extension);
494           PC += 7;
495         }
496     }
497   while (!State.exception);
498 }
499
500 int
501 sim_trace ()
502 {
503 #ifdef DEBUG
504   mn10300_debug = DEBUG;
505 #endif
506   sim_resume (0, 0);
507   return 1;
508 }
509
510 void
511 sim_info (verbose)
512      int verbose;
513 {
514   (*mn10300_callback->printf_filtered) (mn10300_callback, "sim_info\n");
515 }
516
517 void
518 sim_create_inferior (start_address, argv, env)
519      SIM_ADDR start_address;
520      char **argv;
521      char **env;
522 {
523   PC = start_address;
524 }
525
526 void
527 sim_kill ()
528 {
529   /* nothing to do */
530 }
531
532 void
533 sim_set_callbacks (p)
534      host_callback *p;
535 {
536   mn10300_callback = p;
537 }
538
539 /* All the code for exiting, signals, etc needs to be revamped.
540
541    This is enough to get c-torture limping though.  */
542
543 void
544 sim_stop_reason (reason, sigrc)
545      enum sim_stop *reason;
546      int *sigrc;
547 {
548   *reason = sim_stopped;
549   if (State.exception == SIGQUIT)
550     *sigrc = 0;
551   else
552     *sigrc = State.exception;
553 }
554
555 void
556 sim_fetch_register (rn, memory)
557      int rn;
558      unsigned char *memory;
559 {
560   put_word (memory, State.regs[rn]);
561 }
562  
563 void
564 sim_store_register (rn, memory)
565      int rn;
566      unsigned char *memory;
567 {
568   State.regs[rn] = get_word (memory);
569 }
570
571 int
572 sim_read (addr, buffer, size)
573      SIM_ADDR addr;
574      unsigned char *buffer;
575      int size;
576 {
577   int i;
578   for (i = 0; i < size; i++)
579     buffer[i] = load_mem (addr + i, 1);
580
581   return size;
582
583
584 void
585 sim_do_command (cmd)
586      char *cmd;
587 {
588   (*mn10300_callback->printf_filtered) (mn10300_callback, "\"%s\" is not a valid mn10300 simulator command.\n", cmd);
589 }
590
591 int
592 sim_load (prog, from_tty)
593      char *prog;
594      int from_tty;
595 {
596   /* Return nonzero so GDB will handle it.  */
597   return 1;
598