* interp.c (do_format_4): Get operands correctly and
[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 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 }