* interp.c: OP should be an array of 32bit operands!
[binutils-gdb.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 }