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