bcbb98239d17ad3aaef7462ba91f971c41615949
[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 printf("format 3 0x%x\n", insn);
171 }
172
173 static void
174 do_format_4 (insn)
175 uint32 insn;
176 {
177 printf("format 4 0x%x\n", insn);
178 }
179
180 static void
181 do_format_5 (insn)
182 uint32 insn;
183 {
184 printf("format 5 0x%x\n", insn);
185 }
186
187 static void
188 do_format_6 (insn)
189 uint32 insn;
190 {
191 struct hash_entry *h;
192 printf("format 6 0x%x\n", insn);
193
194 h = lookup_hash (insn);
195 OP[0] = (insn >> 16) & 0xffff;
196 OP[1] = insn & 0x1f;
197 OP[2] = (insn >> 11) & 0x1f;
198 (h->ops->func) ();
199 }
200
201 static void
202 do_format_7 (insn)
203 uint32 insn;
204 {
205 printf("format 7 0x%x\n", insn);
206 }
207
208 static void
209 do_format_8 (insn)
210 uint32 insn;
211 {
212 printf("format 8 0x%x\n", insn);
213 }
214
215 static void
216 do_formats_9_10 (insn)
217 uint32 insn;
218 {
219 struct hash_entry *h;
220 printf("formats 9 and 10 0x%x\n", insn);
221
222 h = lookup_hash (insn);
223 OP[0] = insn & 0x1f;
224 OP[1] = (insn >> 11) & 0x1f;
225 (h->ops->func) ();
226 }
227
228 void
229 sim_size (power)
230 int power;
231
232 {
233 if (State.imem)
234 {
235 free (State.imem);
236 free (State.dmem);
237 }
238
239 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
240 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
241 if (!State.imem || !State.dmem )
242 {
243 fprintf (stderr,"Memory allocation failed.\n");
244 exit(1);
245 }
246 printf ("Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
247 printf (" %d bytes data memory.\n",1<<DMEM_SIZE);
248 }
249
250 static void
251 init_system ()
252 {
253 if (!State.imem)
254 sim_size(1);
255 }
256
257 int
258 sim_write (addr, buffer, size)
259 SIM_ADDR addr;
260 unsigned char *buffer;
261 int size;
262 {
263 int i;
264 init_system ();
265
266 /* printf ("sim_write %d bytes to 0x%x\n",size,addr); */
267 for (i = 0; i < size; i++)
268 {
269 State.imem[i+addr] = buffer[i];
270 }
271 return size;
272 }
273
274 void
275 sim_open (args)
276 char *args;
277 {
278 struct simops *s;
279 struct hash_entry *h, *prev;
280 if (args != NULL)
281 printf ("sim_open %s\n",args);
282
283 /* put all the opcodes in the hash table */
284 for (s = Simops; s->func; s++)
285 {
286 h = &hash_table[hash(s->opcode)];
287
288 /* go to the last entry in the chain */
289 while (h->next)
290 h = h->next;
291
292 if (h->ops)
293 {
294 h->next = calloc(1,sizeof(struct hash_entry));
295 h = h->next;
296 }
297 h->ops = s;
298 h->mask = s->mask;
299 h->opcode = s->opcode;
300 }
301 }
302
303
304 void
305 sim_close (quitting)
306 int quitting;
307 {
308 /* nothing to do */
309 }
310
311 void
312 sim_set_profile (n)
313 int n;
314 {
315 printf ("sim_set_profile %d\n",n);
316 }
317
318 void
319 sim_set_profile_size (n)
320 int n;
321 {
322 printf ("sim_set_profile_size %d\n",n);
323 }
324
325 void
326 sim_resume (step, siggnal)
327 int step, siggnal;
328 {
329 uint32 inst, opcode;
330 int i;
331 reg_t oldpc;
332
333 /* printf ("sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
334
335 if (step)
336 State.exception = SIGTRAP;
337 else
338 State.exception = 0;
339
340 do
341 {
342 inst = RLW (PC);
343 oldpc = PC;
344 opcode = (inst & 0x07e0) >> 5;
345 if ((opcode & 0x30) == 0
346 || (opcode & 0x38) == 0x10)
347 {
348 do_format_1_2 (inst & 0xffff);
349 PC += 2;
350 }
351 else if ((opcode & 0x3C) == 0x18
352 || (opcode & 0x3C) == 0x1C
353 || (opcode & 0x3C) == 0x20
354 || (opcode & 0x3C) == 0x24
355 || (opcode & 0x3C) == 0x28)
356 {
357 do_format_4 (inst & 0xffff);
358 PC += 2;
359 }
360 else if ((opcode & 0x3C) == 0x23)
361 {
362 do_format_3 (inst & 0xffff);
363 /* No PC update, it's done in the instruction. */
364 }
365 else if ((opcode & 0x38) == 0x30)
366 {
367 do_format_6 (inst);
368 PC += 4;
369 }
370 else if ((opcode & 0x3C) == 0x38)
371 {
372 do_format_7 (inst);
373 PC += 4;
374 }
375 else if ((opcode & 0x3E) == 0x3C)
376 {
377 do_format_5 (inst);
378 PC += 4;
379 }
380 else if ((opcode & 0x3F) == 0x3E)
381 {
382 do_format_8 (inst);
383 PC += 4;
384 }
385 else
386 {
387 do_formats_9_10 (inst);
388 PC += 4;
389 }
390 }
391 while (!State.exception);
392 }
393
394 int
395 sim_trace ()
396 {
397 printf ("sim_trace\n");
398 return 0;
399 }
400
401 void
402 sim_info (verbose)
403 int verbose;
404 {
405 printf ("sim_info\n");
406 }
407
408 void
409 sim_create_inferior (start_address, argv, env)
410 SIM_ADDR start_address;
411 char **argv;
412 char **env;
413 {
414 printf ("sim_create_inferior: PC=0x%x\n",start_address);
415 PC = start_address;
416 }
417
418
419 void
420 sim_kill ()
421 {
422 /* nothing to do */
423 }
424
425 void
426 sim_set_callbacks(p)
427 host_callback *p;
428 {
429 printf ("sim_set_callbacks\n");
430 /* callback = p; */
431 }
432
433 void
434 sim_stop_reason (reason, sigrc)
435 enum sim_stop *reason;
436 int *sigrc;
437 {
438 /* printf ("sim_stop_reason: PC=0x%x\n",PC); */
439
440 if (State.exception == SIGQUIT)
441 {
442 *reason = sim_exited;
443 *sigrc = State.exception;
444 }
445 else
446 {
447 *reason = sim_stopped;
448 *sigrc = State.exception;
449 }
450 }
451
452 void
453 sim_fetch_register (rn, memory)
454 int rn;
455 unsigned char *memory;
456 {
457 *(uint32 *)memory = State.regs[rn];
458 /* printf ("sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
459 }
460
461 void
462 sim_store_register (rn, memory)
463 int rn;
464 unsigned char *memory;
465 {
466 State.regs[rn]= *(uint32 *)memory;
467 /* printf ("store: r%d=0x%x\n",rn,State.regs[rn]); */
468 }
469
470 sim_read (addr, buffer, size)
471 SIM_ADDR addr;
472 unsigned char *buffer;
473 int size;
474 {
475 int i;
476 for (i = 0; i < size; i++)
477 {
478 buffer[i] = State.imem[addr + i];
479 }
480 return size;
481 }
482
483 void
484 sim_do_command (cmd)
485 char *cmd;
486 {
487 printf("sim_do_command: %s\n",cmd);
488 }
489
490 int
491 sim_load (prog, from_tty)
492 char *prog;
493 int from_tty;
494 {
495 /* Return nonzero so GDB will handle it. */
496 return 1;
497 }