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