* v850-tdep.c: Cleanup lots of things. Add many comments.
[deliverable/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
d70b4d42 1#include <signal.h>
2934d1c9
MH
2#include "sysdep.h"
3#include "bfd.h"
4#include "remote-sim.h"
2934d1c9
MH
5
6#include "d10v_sim.h"
7
8#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
9#define DMEM_SIZE 16 /* Data memory */
10
87178dbd
MM
11enum _leftright { LEFT_FIRST, RIGHT_FIRST };
12
7eebfc62 13int d10v_debug;
87178dbd 14host_callback *d10v_callback;
7eebfc62
MM
15long ins_type_counters[ (int)INS_MAX ];
16long left_nops, right_nops;
87178dbd 17
2934d1c9
MH
18uint16 OP[4];
19
20static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
21
22#define MAX_HASH 63
23struct hash_entry
24{
25 struct hash_entry *next;
26 long opcode;
27 long mask;
28 struct simops *ops;
29};
30
31struct hash_entry hash_table[MAX_HASH+1];
32
33static long
34hash(insn, format)
35 long insn;
36 int format;
37{
38 if (format & LONG_OPCODE)
39 return ((insn & 0x3F000000) >> 24);
40 else
41 return((insn & 0x7E00) >> 9);
42}
43
44static struct hash_entry *
45lookup_hash (ins, size)
46 uint32 ins;
47 int size;
48{
49 struct hash_entry *h;
50
51 if (size)
52 h = &hash_table[(ins & 0x3F000000) >> 24];
53 else
54 h = &hash_table[(ins & 0x7E00) >> 9];
55
56 while ( (ins & h->mask) != h->opcode)
57 {
58 if (h->next == NULL)
59 {
7eebfc62 60 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
2934d1c9
MH
61 exit(1);
62 }
63 h = h->next;
64 }
65 return (h);
66}
67
2934d1c9
MH
68static void
69get_operands (struct simops *s, uint32 ins)
70{
71 int i, shift, bits, flags;
72 uint32 mask;
73 for (i=0; i < s->numops; i++)
74 {
75 shift = s->operands[3*i];
76 bits = s->operands[3*i+1];
77 flags = s->operands[3*i+2];
78 mask = 0x7FFFFFFF >> (31 - bits);
79 OP[i] = (ins >> shift) & mask;
80 }
81}
82
83static void
84do_long (ins)
85 uint32 ins;
86{
87 struct hash_entry *h;
7eebfc62
MM
88#ifdef DEBUG
89 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
90 (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
91#endif
2934d1c9
MH
92 h = lookup_hash (ins, 1);
93 get_operands (h->ops, ins);
87178dbd 94 State.ins_type = INS_LONG;
7eebfc62 95 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
96 (h->ops->func)();
97}
215ac953 98
2934d1c9 99static void
87178dbd 100do_2_short (ins1, ins2, leftright)
2934d1c9 101 uint16 ins1, ins2;
87178dbd 102 enum _leftright leftright;
2934d1c9
MH
103{
104 struct hash_entry *h;
215ac953
MM
105 reg_t orig_pc = PC;
106
7eebfc62
MM
107#ifdef DEBUG
108 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
109 (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
110 ins1, (leftright) ? "left" : "right", ins2);
111#endif
2934d1c9
MH
112 /* printf ("do_2_short %x -> %x\n",ins1,ins2); */
113 h = lookup_hash (ins1, 0);
114 get_operands (h->ops, ins1);
87178dbd 115 State.ins_type = (leftright == LEFT_FIRST) ? INS_LEFT : INS_RIGHT;
7eebfc62 116 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9 117 (h->ops->func)();
215ac953
MM
118
119 /* If the PC has changed (ie, a jump), don't do the second instruction */
57bc1a72 120 if (orig_pc == PC && !State.exception)
215ac953
MM
121 {
122 h = lookup_hash (ins2, 0);
123 get_operands (h->ops, ins2);
124 State.ins_type = (leftright == LEFT_FIRST) ? INS_RIGHT : INS_LEFT;
125 ins_type_counters[ (int)State.ins_type ]++;
126 (h->ops->func)();
127 }
2934d1c9 128}
215ac953 129
2934d1c9
MH
130static void
131do_parallel (ins1, ins2)
132 uint16 ins1, ins2;
133{
134 struct hash_entry *h1, *h2;
7eebfc62
MM
135#ifdef DEBUG
136 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
137 (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
138#endif
2934d1c9 139 h1 = lookup_hash (ins1, 0);
2934d1c9 140 h2 = lookup_hash (ins2, 0);
d70b4d42 141
2934d1c9
MH
142 if (h1->ops->exec_type == PARONLY)
143 {
d70b4d42 144 get_operands (h1->ops, ins1);
87178dbd 145 State.ins_type = INS_LEFT;
7eebfc62 146 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
147 (h1->ops->func)();
148 if (State.exe)
d70b4d42
MH
149 {
150 get_operands (h2->ops, ins2);
87178dbd 151 State.ins_type = INS_RIGHT;
d70b4d42
MH
152 (h2->ops->func)();
153 }
2934d1c9
MH
154 }
155 else if (h2->ops->exec_type == PARONLY)
156 {
d70b4d42 157 get_operands (h2->ops, ins2);
87178dbd 158 State.ins_type = INS_RIGHT;
7eebfc62 159 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
160 (h2->ops->func)();
161 if (State.exe)
d70b4d42
MH
162 {
163 get_operands (h1->ops, ins1);
87178dbd 164 State.ins_type = INS_LEFT;
d70b4d42
MH
165 (h1->ops->func)();
166 }
2934d1c9
MH
167 }
168 else
169 {
d70b4d42 170 get_operands (h1->ops, ins1);
87178dbd 171 State.ins_type = INS_LEFT_PARALLEL;
7eebfc62 172 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9 173 (h1->ops->func)();
57bc1a72
MM
174 if (!State.exception)
175 {
176 get_operands (h2->ops, ins2);
177 State.ins_type = INS_RIGHT_PARALLEL;
178 ins_type_counters[ (int)State.ins_type ]++;
179 (h2->ops->func)();
180 }
2934d1c9
MH
181 }
182}
183
184
185void
186sim_size (power)
187 int power;
188
189{
190 if (State.imem)
191 {
192 free (State.imem);
193 free (State.dmem);
194 }
195
196 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
197 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
198 if (!State.imem || !State.dmem )
199 {
7eebfc62 200 (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
2934d1c9
MH
201 exit(1);
202 }
7eebfc62 203
57bc1a72
MM
204 State.mem_min = 1<<IMEM_SIZE;
205 State.mem_max = 0;
206
7eebfc62
MM
207#ifdef DEBUG
208 if ((d10v_debug & DEBUG_MEMSIZE) != 0)
209 {
210 (*d10v_callback->printf_filtered) (d10v_callback, "Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
211 (*d10v_callback->printf_filtered) (d10v_callback, " %d bytes data memory.\n", 1<<DMEM_SIZE);
212 }
87178dbd 213#endif
2934d1c9
MH
214}
215
216static void
217init_system ()
218{
219 if (!State.imem)
220 sim_size(1);
221}
222
223int
224sim_write (addr, buffer, size)
225 SIM_ADDR addr;
226 unsigned char *buffer;
227 int size;
228{
2934d1c9
MH
229 init_system ();
230
57bc1a72
MM
231#ifdef DEBUG
232 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
233 (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x, min = 0x%x, max = 0x%x\n",
234 size, addr, State.mem_min, State.mem_max);
235#endif
236
237 if (State.mem_min > addr)
238 State.mem_min = addr;
239
240 if (State.mem_max < addr+size-1)
241 State.mem_max = addr+size-1;
242
243 memcpy (State.imem+addr, buffer, size);
2934d1c9
MH
244 return size;
245}
246
247void
248sim_open (args)
249 char *args;
250{
251 struct simops *s;
252 struct hash_entry *h, *prev;
1eaaf305
MM
253 static int init_p = 0;
254
2934d1c9 255 if (args != NULL)
1eaaf305
MM
256 {
257#ifdef DEBUG
258 if (strcmp (args, "-t") == 0)
259 d10v_debug = DEBUG;
260 else
261#endif
262 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",args);
263 }
2934d1c9
MH
264
265 /* put all the opcodes in the hash table */
1eaaf305 266 if (!init_p++)
2934d1c9 267 {
1eaaf305 268 for (s = Simops; s->func; s++)
2934d1c9 269 {
1eaaf305
MM
270 h = &hash_table[hash(s->opcode,s->format)];
271
272 /* go to the last entry in the chain */
273 while (h->next)
274 h = h->next;
275
276 if (h->ops)
277 {
278 h->next = calloc(1,sizeof(struct hash_entry));
279 h = h->next;
280 }
281 h->ops = s;
282 h->mask = s->mask;
283 h->opcode = s->opcode;
2934d1c9 284 }
2934d1c9
MH
285 }
286}
287
288
289void
290sim_close (quitting)
291 int quitting;
292{
293 /* nothing to do */
294}
295
296void
297sim_set_profile (n)
298 int n;
299{
7eebfc62 300 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
2934d1c9
MH
301}
302
303void
304sim_set_profile_size (n)
305 int n;
306{
7eebfc62 307 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
2934d1c9
MH
308}
309
310void
311sim_resume (step, siggnal)
312 int step, siggnal;
313{
314 uint32 inst;
315 int i;
316 reg_t oldpc;
317
7eebfc62 318/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
2934d1c9 319
d70b4d42
MH
320 if (step)
321 State.exception = SIGTRAP;
322 else
323 State.exception = 0;
324
325 do
326 {
57bc1a72
MM
327 uint32 byte_pc = ((uint32)PC) << 2;
328 if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max))
d70b4d42 329 {
57bc1a72
MM
330 (*d10v_callback->printf_filtered) (d10v_callback,
331 "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n",
332 (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max);
333 State.exception = SIGILL;
d70b4d42 334 }
57bc1a72 335 else
d70b4d42 336 {
57bc1a72
MM
337 inst = RLW (byte_pc);
338 oldpc = PC;
339 switch (inst & 0xC0000000)
340 {
341 case 0xC0000000:
342 /* long instruction */
343 do_long (inst & 0x3FFFFFFF);
344 break;
345 case 0x80000000:
346 /* R -> L */
347 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
348 break;
349 case 0x40000000:
350 /* L -> R */
351 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
352 break;
353 case 0:
354 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
355 break;
356 }
d70b4d42 357
57bc1a72
MM
358 if (State.RP && PC == RPT_E)
359 {
360 RPT_C -= 1;
361 if (RPT_C == 0)
362 State.RP = 0;
363 else
364 PC = RPT_S;
365 }
366
367 /* FIXME */
368 if (PC == oldpc)
369 PC++;
370 }
d70b4d42
MH
371 }
372 while (!State.exception);
2934d1c9
MH
373}
374
375int
376sim_trace ()
377{
7eebfc62
MM
378#ifdef DEBUG
379 d10v_debug = DEBUG;
380#endif
381 sim_resume (0, 0);
382 return 1;
2934d1c9
MH
383}
384
385void
386sim_info (verbose)
387 int verbose;
388{
7eebfc62
MM
389 char buf[40];
390 int size;
391 long total = (ins_type_counters[ (int)INS_LONG ]
392 + ins_type_counters[ (int)INS_LEFT ]
393 + ins_type_counters[ (int)INS_LEFT_PARALLEL ]
394 + ins_type_counters[ (int)INS_RIGHT ]
395 + ins_type_counters[ (int)INS_RIGHT_PARALLEL ]);
396
397 sprintf (buf, "%ld", total);
398 size = strlen (buf);
399
400 (*d10v_callback->printf_filtered) (d10v_callback,
401 "executed %*ld instructions in the left container, %*ld parallel, %*ld nops\n",
402 size, ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_PARALLEL ],
403 size, ins_type_counters[ (int)INS_LEFT_PARALLEL ],
404 size, left_nops);
405
406 (*d10v_callback->printf_filtered) (d10v_callback,
407 "executed %*ld instructions in the right container, %*ld parallel, %*ld nops\n",
408 size, ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
409 size, ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
410 size, right_nops);
411
412 (*d10v_callback->printf_filtered) (d10v_callback,
413 "executed %*ld long instructions\n",
414 size, ins_type_counters[ (int)INS_LONG ]);
415
416 (*d10v_callback->printf_filtered) (d10v_callback,
417 "executed %*ld total instructions\n",
418 size, total);
2934d1c9
MH
419}
420
421void
422sim_create_inferior (start_address, argv, env)
423 SIM_ADDR start_address;
424 char **argv;
425 char **env;
426{
57bc1a72
MM
427 uint8 *imem, *dmem;
428 uint32 mem_min, mem_max;
7eebfc62
MM
429#ifdef DEBUG
430 if (d10v_debug)
431 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%x\n", start_address);
432#endif
57bc1a72
MM
433 /* save memory pointers */
434 imem = State.imem;
435 dmem = State.dmem;
436 mem_min = State.mem_min;
437 mem_max = State.mem_max;
438 /* reset all state information */
439 memset (&State, 0, sizeof(State));
440 /* restore memory pointers */
441 State.imem = imem;
442 State.dmem = dmem;
443 State.mem_min = mem_min;
444 State.mem_max = mem_max;
445 /* set PC */
2934d1c9
MH
446 PC = start_address >> 2;
447}
448
449
450void
451sim_kill ()
452{
453 /* nothing to do */
454}
455
456void
457sim_set_callbacks(p)
458 host_callback *p;
459{
87178dbd
MM
460/* printf ("sim_set_callbacks\n"); */
461 d10v_callback = p;
2934d1c9
MH
462}
463
464void
465sim_stop_reason (reason, sigrc)
466 enum sim_stop *reason;
467 int *sigrc;
468{
7eebfc62 469/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
d70b4d42 470
a49a15ad 471 switch (State.exception)
d70b4d42 472 {
a49a15ad 473 case SIG_D10V_STOP: /* stop instruction */
d70b4d42 474 *reason = sim_exited;
a49a15ad
MM
475 *sigrc = 0;
476 break;
477
478 case SIG_D10V_EXIT: /* exit trap */
479 *reason = sim_exited;
480 *sigrc = State.regs[2];
481 break;
482
483 default: /* some signal */
d70b4d42
MH
484 *reason = sim_stopped;
485 *sigrc = State.exception;
a49a15ad 486 break;
d70b4d42
MH
487 }
488}
489
490void
491sim_fetch_register (rn, memory)
492 int rn;
493 unsigned char *memory;
494{
495 if (rn > 31)
496 {
497 WRITE_64 (memory, State.a[rn-32]);
7eebfc62 498 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%llx\n",rn,State.a[rn-32]); */
d70b4d42
MH
499 }
500 else
501 {
502 WRITE_16 (memory, State.regs[rn]);
7eebfc62 503 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
d70b4d42
MH
504 }
505}
506
507void
508sim_store_register (rn, memory)
509 int rn;
510 unsigned char *memory;
511{
512 if (rn > 31)
513 {
514 State.a[rn-32] = READ_64 (memory) & MASK40;
7eebfc62 515 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: a%d=0x%llx\n",rn-32,State.a[rn-32]); */
d70b4d42
MH
516 }
517 else
518 {
519 State.regs[rn]= READ_16 (memory);
7eebfc62 520 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: r%d=0x%x\n",rn,State.regs[rn]); */
d70b4d42 521 }
2934d1c9 522}
d70b4d42
MH
523
524sim_read (addr, buffer, size)
525 SIM_ADDR addr;
526 unsigned char *buffer;
527 int size;
528{
529 int i;
530 for (i = 0; i < size; i++)
531 {
532 buffer[i] = State.imem[addr + i];
533 }
534 return size;
535}
536
537void
538sim_do_command (cmd)
539 char *cmd;
540{
7eebfc62 541 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
d70b4d42
MH
542}
543
544int
545sim_load (prog, from_tty)
546 char *prog;
547 int from_tty;
548{
549 /* Return nonzero so GDB will handle it. */
550 return 1;
551}
This page took 0.085881 seconds and 4 git commands to generate.