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