* interp.c: OP should be an array of 32bit operands!
[external/binutils.git] / sim / v850 / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4 #include "remote-sim.h"
5 #include "callback.h"
6
7 #include "v850_sim.h"
8
9 #define MEM_SIZE 18     /* V850 memory size is 18 bits XXX */
10
11 host_callback *v850_callback;
12
13
14 uint32 OP[4];
15
16 static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
17
18 #define MAX_HASH  63
19 struct hash_entry
20 {
21   struct hash_entry *next;
22   long opcode;
23   long mask;
24   struct simops *ops;
25 };
26
27 struct hash_entry hash_table[MAX_HASH+1];
28
29 static long 
30 hash(insn)
31      long insn;
32 {
33   if ((insn & 0x0600) == 0
34       || (insn & 0x0700) == 0x0200)
35     return (insn & 0x07e0) >> 5;
36   if ((insn & 0x0700) == 0x0300
37       || (insn & 0x0700) == 0x0400
38       || (insn & 0x0700) == 0x0500)
39     return (insn & 0x0780) >> 7;
40   if ((insn & 0x0700) == 0x0600)
41     return (insn & 0x07e0) >> 5;
42   if ((insn & 0x0780) == 0x0700)
43     return (insn & 0x07e0) >> 5;
44   if ((insn & 0x07c0) == 0x0780)
45     return (insn & 0x07c0) >> 6;
46   if ((insn & 0x07E0) == 0x07C0)
47     return (insn & 0x07e0) >> 5;
48   return (insn & 0x07e0) >> 5;
49 }
50
51 static struct hash_entry *
52 lookup_hash (ins)
53      uint32 ins;
54 {
55   struct hash_entry *h;
56
57   h = &hash_table[hash(ins)];
58
59   while ( (ins & h->mask) != h->opcode)
60     {
61       if (h->next == NULL)
62         {
63           printf ("ERROR looking up hash for %x\n",ins);
64           exit(1);
65         }
66       h = h->next;
67     }
68   return (h);
69 }
70
71 uint8
72 get_byte (x)
73      uint8 *x;
74 {
75   return *x;
76 }
77
78 uint16
79 get_half (x)
80      uint8 *x;
81 {
82   uint8 *a = x;
83   return (a[1] << 8) + (a[0]);
84 }
85
86 uint32
87 get_word (x)
88       uint8 *x;
89 {
90   uint8 *a = x;
91   return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
92 }
93
94 void
95 put_byte (addr, data)
96      uint8 *addr;
97      uint8 data;
98 {
99   uint8 *a = addr;
100   a[0] = data;
101 }
102
103 void
104 put_half (addr, data)
105      uint8 *addr;
106      uint16 data;
107 {
108   uint8 *a = addr;
109   a[0] = data & 0xff;
110   a[1] = (data >> 8) & 0xff;
111 }
112
113 void
114 put_word (addr, data)
115      uint8 *addr;
116      uint32 data;
117 {
118   uint8 *a = addr;
119   a[0] = data & 0xff;
120   a[1] = (data >> 8) & 0xff;
121   a[2] = (data >> 16) & 0xff;
122   a[3] = (data >> 24) & 0xff;
123 }
124
125 static void
126 do_format_1_2 (insn)
127      uint32 insn;
128 {
129   struct hash_entry *h;
130
131   h = lookup_hash (insn);
132   OP[0] = insn & 0x1f;
133   OP[1] = (insn >> 11) & 0x1f;
134   (h->ops->func) ();
135 }
136
137 static void
138 do_format_3 (insn)
139      uint32 insn;
140 {
141   struct hash_entry *h;
142
143   h = lookup_hash (insn);
144   OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1;
145   (h->ops->func) ();
146 }
147
148 static void
149 do_format_4 (insn)
150      uint32 insn;
151 {
152   struct hash_entry *h;
153
154   h = lookup_hash (insn);
155   OP[0] = (insn >> 11) & 0x1f;
156   OP[1] = (insn & 0x7f);
157   (h->ops->func) ();
158 }
159
160 static void
161 do_format_5 (insn)
162      uint32 insn;
163 {
164   struct hash_entry *h;
165
166   h = lookup_hash (insn);
167   OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
168   OP[1] = (insn >> 11) & 0x1f;
169   (h->ops->func) ();
170 }
171
172 static void
173 do_format_6 (insn)
174      uint32 insn;
175 {
176   struct hash_entry *h;
177
178   h = lookup_hash (insn);
179   OP[0] = (insn >> 16) & 0xffff;
180   OP[1] = insn & 0x1f;
181   OP[2] = (insn >> 11) & 0x1f;
182   (h->ops->func) ();
183 }
184
185 static void
186 do_format_7 (insn)
187      uint32 insn;
188 {
189   struct hash_entry *h;
190
191   h = lookup_hash (insn);
192   OP[0] = insn & 0x1f;
193   OP[1] = (insn >> 11) & 0x1f;
194   OP[2] = (insn >> 16) & 0xffff;
195   (h->ops->func) ();
196 }
197
198 static void
199 do_format_8 (insn)
200      uint32 insn;
201 {
202   struct hash_entry *h;
203
204   h = lookup_hash (insn);
205   OP[0] = insn & 0x1f;
206   OP[1] = (insn >> 11) & 0x7;
207   OP[2] = (insn >> 16) & 0xffff;
208   (h->ops->func) ();
209 }
210
211 static void
212 do_formats_9_10 (insn)
213      uint32 insn;
214 {
215   struct hash_entry *h;
216
217   h = lookup_hash (insn);
218   OP[0] = insn & 0x1f;
219   OP[1] = (insn >> 11) & 0x1f;
220   (h->ops->func) ();
221 }
222
223 void
224 sim_size (power)
225      int power;
226
227 {
228   if (State.mem)
229     {
230       free (State.mem);
231     }
232
233   State.mem = (uint8 *)calloc(1,1<<MEM_SIZE);
234   if (!State.mem)
235     {
236       fprintf (stderr,"Memory allocation failed.\n");
237       exit(1);
238     }
239 }
240
241 static void
242 init_system ()
243 {
244   if (!State.mem)
245     sim_size(1);
246 }
247
248 int
249 sim_write (addr, buffer, size)
250      SIM_ADDR addr;
251      unsigned char *buffer;
252      int size;
253 {
254   int i;
255   init_system ();
256
257   for (i = 0; i < size; i++)
258     {
259       State.mem[i+addr] = buffer[i]; 
260     }
261   return size;
262 }
263
264 void
265 sim_open (args)
266      char *args;
267 {
268   struct simops *s;
269   struct hash_entry *h, *prev;
270   if (args != NULL)
271       printf ("sim_open %s\n",args);
272
273   /* put all the opcodes in the hash table */
274   for (s = Simops; s->func; s++)
275     {
276       h = &hash_table[hash(s->opcode)];
277       
278       /* go to the last entry in the chain */
279       while (h->next)
280           h = h->next;
281
282       if (h->ops)
283         {
284           h->next = calloc(1,sizeof(struct hash_entry));
285           h = h->next;
286         }
287       h->ops = s;
288       h->mask = s->mask;
289       h->opcode = s->opcode;
290     }
291 }
292
293
294 void
295 sim_close (quitting)
296      int quitting;
297 {
298   /* nothing to do */
299 }
300
301 void
302 sim_set_profile (n)
303      int n;
304 {
305   printf ("sim_set_profile %d\n",n);
306 }
307
308 void
309 sim_set_profile_size (n)
310      int n;
311 {
312   printf ("sim_set_profile_size %d\n",n);
313 }
314
315 void
316 sim_resume (step, siggnal)
317      int step, siggnal;
318 {
319   uint32 inst, opcode;
320   int i;
321   reg_t oldpc;
322
323
324  if (step)
325    State.exception = SIGTRAP;
326  else
327    State.exception = 0;
328  
329  do
330    {
331      inst = RLW (PC);
332      oldpc = PC;
333      opcode = (inst & 0x07e0) >> 5;
334      if ((opcode & 0x30) == 0
335          || (opcode & 0x38) == 0x10)
336        {
337          do_format_1_2 (inst & 0xffff);
338          PC += 2;
339        }
340      else if ((opcode & 0x3C) == 0x18
341               || (opcode & 0x3C) == 0x1C
342               || (opcode & 0x3C) == 0x20
343               || (opcode & 0x3C) == 0x24
344               || (opcode & 0x3C) == 0x28)
345        {
346          do_format_4 (inst & 0xffff);
347          PC += 2;
348        }
349      else if ((opcode & 0x3C) == 0x2C)
350        {
351          do_format_3 (inst & 0xffff);
352          /* No PC update, it's done in the instruction.  */
353        }
354      else if ((opcode & 0x38) == 0x30)
355        {
356          do_format_6 (inst);
357          PC += 4;
358        }
359      else if ((opcode & 0x3C) == 0x38)
360        {
361          do_format_7 (inst);
362          PC += 4;
363        }
364      else if ((opcode & 0x3E) == 0x3C)
365        {
366          do_format_5 (inst);
367          /* No PC update, it's done in the instruction.  */
368        }
369      else if ((opcode & 0x3F) == 0x3E)
370        {
371          do_format_8 (inst);
372          PC += 4;
373        }
374      else
375        {
376          do_formats_9_10 (inst);
377          PC += 4;
378        }
379    } 
380  while (!State.exception);
381 }
382
383 int
384 sim_trace ()
385 {
386   printf ("sim_trace\n");
387   return 0;
388 }
389
390 void
391 sim_info (verbose)
392      int verbose;
393 {
394   printf ("sim_info\n");
395 }
396
397 void
398 sim_create_inferior (start_address, argv, env)
399      SIM_ADDR start_address;
400      char **argv;
401      char **env;
402 {
403   PC = start_address;
404 }
405
406
407 void
408 sim_kill ()
409 {
410   /* nothing to do */
411 }
412
413 void
414 sim_set_callbacks(p)
415      host_callback *p;
416 {
417   v850_callback = p;
418 }
419
420 /* All the code for exiting, signals, etc needs to be revamped.  */
421
422    This is enough to get c-torture limping though.  */
423 void
424 sim_stop_reason (reason, sigrc)
425      enum sim_stop *reason;
426      int *sigrc;
427 {
428
429   *reason = sim_stopped;
430   if (State.exception == SIGQUIT)
431     *sigrc = 0;
432   else
433     *sigrc = State.exception;
434 }
435
436 void
437 sim_fetch_register (rn, memory)
438      int rn;
439      unsigned char *memory;
440 {
441   *(uint32 *)memory = State.regs[rn];
442 }
443  
444 void
445 sim_store_register (rn, memory)
446      int rn;
447      unsigned char *memory;
448 {
449   State.regs[rn]= *(uint32 *)memory;
450 }
451
452 sim_read (addr, buffer, size)
453      SIM_ADDR addr;
454      unsigned char *buffer;
455      int size;
456 {
457   int i;
458   for (i = 0; i < size; i++)
459     {
460       buffer[i] = State.mem[addr + i];
461     }
462   return size;
463
464
465 void
466 sim_do_command (cmd)
467      char *cmd;
468
469   printf("sim_do_command: %s\n",cmd);
470 }
471
472 int
473 sim_load (prog, from_tty)
474      char *prog;
475      int from_tty;
476 {
477   /* Return nonzero so GDB will handle it.  */
478   return 1;
479