* v850_sim.h: The V850 doesn't have split I&D spaces. Change
[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   printf("format 4 0x%x\n", insn);
158 }
159
160 static void
161 do_format_5 (insn)
162      uint32 insn;
163 {
164   struct hash_entry *h;
165   printf("format 5 0x%x\n", insn);
166
167   h = lookup_hash (insn);
168   OP[0] = ((insn & 0x3f) | (((insn >> 17) & 0x7fff) << 6)) << 1;
169   OP[1] = (insn >> 11) & 0x1f;
170   (h->ops->func) ();
171 }
172
173 static void
174 do_format_6 (insn)
175      uint32 insn;
176 {
177   struct hash_entry *h;
178   printf("format 6 0x%x\n", insn);
179
180   h = lookup_hash (insn);
181   OP[0] = (insn >> 16) & 0xffff;
182   OP[1] = insn & 0x1f;
183   OP[2] = (insn >> 11) & 0x1f;
184   (h->ops->func) ();
185 }
186
187 static void
188 do_format_7 (insn)
189      uint32 insn;
190 {
191   struct hash_entry *h;
192   printf("format 7 0x%x\n", insn);
193
194   h = lookup_hash (insn);
195   OP[0] = insn & 0x1f;
196   OP[1] = (insn >> 11) & 0x1f;
197   OP[2] = (insn >> 16) & 0xffff;
198   (h->ops->func) ();
199 }
200
201 static void
202 do_format_8 (insn)
203      uint32 insn;
204 {
205   printf("format 8 0x%x\n", insn);
206 }
207
208 static void
209 do_formats_9_10 (insn)
210      uint32 insn;
211 {
212   struct hash_entry *h;
213   printf("formats 9 and 10 0x%x\n", insn);
214
215   h = lookup_hash (insn);
216   OP[0] = insn & 0x1f;
217   OP[1] = (insn >> 11) & 0x1f;
218   (h->ops->func) ();
219 }
220
221 void
222 sim_size (power)
223      int power;
224
225 {
226   if (State.mem)
227     {
228       free (State.mem);
229     }
230
231   State.mem = (uint8 *)calloc(1,1<<MEM_SIZE);
232   if (!State.mem)
233     {
234       fprintf (stderr,"Memory allocation failed.\n");
235       exit(1);
236     }
237   printf ("Allocated %d bytes memory and\n",1<<MEM_SIZE);
238 }
239
240 static void
241 init_system ()
242 {
243   if (!State.mem)
244     sim_size(1);
245 }
246
247 int
248 sim_write (addr, buffer, size)
249      SIM_ADDR addr;
250      unsigned char *buffer;
251      int size;
252 {
253   int i;
254   init_system ();
255
256   /* printf ("sim_write %d bytes to 0x%x\n",size,addr); */
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 /*   printf ("sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */
324
325  if (step)
326    State.exception = SIGTRAP;
327  else
328    State.exception = 0;
329  
330  do
331    {
332      inst = RLW (PC);
333      oldpc = PC;
334      opcode = (inst & 0x07e0) >> 5;
335      if ((opcode & 0x30) == 0
336          || (opcode & 0x38) == 0x10)
337        {
338          do_format_1_2 (inst & 0xffff);
339          PC += 2;
340        }
341      else if ((opcode & 0x3C) == 0x18
342               || (opcode & 0x3C) == 0x1C
343               || (opcode & 0x3C) == 0x20
344               || (opcode & 0x3C) == 0x24
345               || (opcode & 0x3C) == 0x28)
346        {
347          do_format_4 (inst & 0xffff);
348          PC += 2;
349        }
350      else if ((opcode & 0x3C) == 0x23)
351        {
352          do_format_3 (inst & 0xffff);
353          /* No PC update, it's done in the instruction.  */
354        }
355      else if ((opcode & 0x38) == 0x30)
356        {
357          do_format_6 (inst);
358          PC += 4;
359        }
360      else if ((opcode & 0x3C) == 0x38)
361        {
362          do_format_7 (inst);
363          PC += 4;
364        }
365      else if ((opcode & 0x3E) == 0x3C)
366        {
367          do_format_5 (inst);
368          /* No PC update, it's done in the instruction.  */
369        }
370      else if ((opcode & 0x3F) == 0x3E)
371        {
372          do_format_8 (inst);
373          PC += 4;
374        }
375      else
376        {
377          do_formats_9_10 (inst);
378          PC += 4;
379        }
380    } 
381  while (!State.exception);
382 }
383
384 int
385 sim_trace ()
386 {
387   printf ("sim_trace\n");
388   return 0;
389 }
390
391 void
392 sim_info (verbose)
393      int verbose;
394 {
395   printf ("sim_info\n");
396 }
397
398 void
399 sim_create_inferior (start_address, argv, env)
400      SIM_ADDR start_address;
401      char **argv;
402      char **env;
403 {
404   printf ("sim_create_inferior:  PC=0x%x\n",start_address);
405   PC = start_address;
406 }
407
408
409 void
410 sim_kill ()
411 {
412   /* nothing to do */
413 }
414
415 void
416 sim_set_callbacks(p)
417      host_callback *p;
418 {
419   printf ("sim_set_callbacks\n");
420   /* callback = p; */
421 }
422
423 void
424 sim_stop_reason (reason, sigrc)
425      enum sim_stop *reason;
426      int *sigrc;
427 {
428 /*   printf ("sim_stop_reason:  PC=0x%x\n",PC); */
429
430   if (State.exception == SIGQUIT)
431     {
432       *reason = sim_exited;
433       *sigrc = State.exception;
434     }
435   else
436     {
437       *reason = sim_stopped;
438       *sigrc = State.exception;
439     } 
440 }
441
442 void
443 sim_fetch_register (rn, memory)
444      int rn;
445      unsigned char *memory;
446 {
447   *(uint32 *)memory = State.regs[rn];
448   /* printf ("sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
449 }
450  
451 void
452 sim_store_register (rn, memory)
453      int rn;
454      unsigned char *memory;
455 {
456   State.regs[rn]= *(uint32 *)memory;
457   /* printf ("store: r%d=0x%x\n",rn,State.regs[rn]); */
458 }
459
460 sim_read (addr, buffer, size)
461      SIM_ADDR addr;
462      unsigned char *buffer;
463      int size;
464 {
465   int i;
466   for (i = 0; i < size; i++)
467     {
468       buffer[i] = State.mem[addr + i];
469     }
470   return size;
471
472
473 void
474 sim_do_command (cmd)
475      char *cmd;
476
477   printf("sim_do_command: %s\n",cmd);
478 }
479
480 int
481 sim_load (prog, from_tty)
482      char *prog;
483      int from_tty;
484 {
485   /* Return nonzero so GDB will handle it.  */
486   return 1;
487