Flush defunct sim_kill.
[deliverable/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
d70b4d42 1#include <signal.h>
2934d1c9 2#include "sysdep.h"
04885cc3 3#include "bfd.h"
cee402dd 4#include "callback.h"
2934d1c9 5#include "remote-sim.h"
2934d1c9
MH
6
7#include "d10v_sim.h"
8
9#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
c422ecc7
MH
10#define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */
11#define UMEM_SIZE 17 /* each unified memory region is 17 bits */
2934d1c9 12
87178dbd
MM
13enum _leftright { LEFT_FIRST, RIGHT_FIRST };
14
04885cc3
DE
15static char *myname;
16static SIM_OPEN_KIND sim_kind;
17static bfd_vma start_address;
7eebfc62 18int d10v_debug;
87178dbd 19host_callback *d10v_callback;
aeb1f26b 20unsigned long ins_type_counters[ (int)INS_MAX ];
87178dbd 21
2934d1c9
MH
22uint16 OP[4];
23
b30cdd35 24static int init_text_p = 0;
04885cc3
DE
25/* non-zero if we opened prog_bfd */
26static int prog_bfd_was_opened_p;
27bfd *prog_bfd;
b30cdd35
MM
28asection *text;
29bfd_vma text_start;
30bfd_vma text_end;
31
aeb1f26b 32static long hash PARAMS ((long insn, int format));
2934d1c9 33static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
aeb1f26b
MM
34static void get_operands PARAMS ((struct simops *s, uint32 ins));
35static void do_long PARAMS ((uint32 ins));
36static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
37static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
38static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
aeb1f26b 39static void init_system PARAMS ((void));
aeb1f26b
MM
40extern void sim_set_profile PARAMS ((int n));
41extern void sim_set_profile_size PARAMS ((int n));
aeb1f26b
MM
42
43#ifndef INLINE
44#if defined(__GNUC__) && defined(__OPTIMIZE__)
45#define INLINE __inline__
46#else
47#define INLINE
48#endif
49#endif
2934d1c9
MH
50
51#define MAX_HASH 63
52struct hash_entry
53{
54 struct hash_entry *next;
55 long opcode;
56 long mask;
cee402dd 57 int size;
2934d1c9
MH
58 struct simops *ops;
59};
60
61struct hash_entry hash_table[MAX_HASH+1];
62
aeb1f26b 63INLINE static long
2934d1c9
MH
64hash(insn, format)
65 long insn;
66 int format;
67{
68 if (format & LONG_OPCODE)
69 return ((insn & 0x3F000000) >> 24);
70 else
71 return((insn & 0x7E00) >> 9);
72}
73
aeb1f26b 74INLINE static struct hash_entry *
2934d1c9
MH
75lookup_hash (ins, size)
76 uint32 ins;
77 int size;
78{
79 struct hash_entry *h;
80
81 if (size)
82 h = &hash_table[(ins & 0x3F000000) >> 24];
83 else
84 h = &hash_table[(ins & 0x7E00) >> 9];
85
cee402dd 86 while ((ins & h->mask) != h->opcode || h->size != size)
2934d1c9
MH
87 {
88 if (h->next == NULL)
89 {
7eebfc62 90 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
aeb1f26b 91 exit (1);
2934d1c9
MH
92 }
93 h = h->next;
94 }
95 return (h);
96}
97
aeb1f26b 98INLINE static void
2934d1c9
MH
99get_operands (struct simops *s, uint32 ins)
100{
101 int i, shift, bits, flags;
102 uint32 mask;
103 for (i=0; i < s->numops; i++)
104 {
105 shift = s->operands[3*i];
106 bits = s->operands[3*i+1];
107 flags = s->operands[3*i+2];
108 mask = 0x7FFFFFFF >> (31 - bits);
109 OP[i] = (ins >> shift) & mask;
110 }
111}
112
b30cdd35
MM
113bfd_vma
114decode_pc ()
115{
116 asection *s;
117 if (!init_text_p)
118 {
119 init_text_p = 1;
04885cc3
DE
120 for (s = prog_bfd->sections; s; s = s->next)
121 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
b30cdd35
MM
122 {
123 text = s;
04885cc3
DE
124 text_start = bfd_get_section_vma (prog_bfd, s);
125 text_end = text_start + bfd_section_size (prog_bfd, s);
b30cdd35
MM
126 break;
127 }
128 }
129
130 return (PC << 2) + text_start;
131}
132
2934d1c9
MH
133static void
134do_long (ins)
135 uint32 ins;
136{
137 struct hash_entry *h;
7eebfc62
MM
138#ifdef DEBUG
139 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
140 (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
141#endif
2934d1c9
MH
142 h = lookup_hash (ins, 1);
143 get_operands (h->ops, ins);
87178dbd 144 State.ins_type = INS_LONG;
7eebfc62 145 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
146 (h->ops->func)();
147}
215ac953 148
2934d1c9 149static void
87178dbd 150do_2_short (ins1, ins2, leftright)
2934d1c9 151 uint16 ins1, ins2;
87178dbd 152 enum _leftright leftright;
2934d1c9
MH
153{
154 struct hash_entry *h;
215ac953 155 reg_t orig_pc = PC;
c422ecc7 156 enum _ins_type first, second;
215ac953 157
7eebfc62
MM
158#ifdef DEBUG
159 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
160 (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
161 ins1, (leftright) ? "left" : "right", ins2);
162#endif
c422ecc7
MH
163
164 if (leftright == LEFT_FIRST)
165 {
166 first = INS_LEFT;
167 second = INS_RIGHT;
168 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
169 }
170 else
171 {
172 first = INS_RIGHT;
173 second = INS_LEFT;
174 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
175 }
176
2934d1c9
MH
177 h = lookup_hash (ins1, 0);
178 get_operands (h->ops, ins1);
c422ecc7 179 State.ins_type = first;
7eebfc62 180 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9 181 (h->ops->func)();
215ac953
MM
182
183 /* If the PC has changed (ie, a jump), don't do the second instruction */
57bc1a72 184 if (orig_pc == PC && !State.exception)
215ac953
MM
185 {
186 h = lookup_hash (ins2, 0);
187 get_operands (h->ops, ins2);
c422ecc7 188 State.ins_type = second;
215ac953 189 ins_type_counters[ (int)State.ins_type ]++;
c422ecc7 190 ins_type_counters[ (int)INS_CYCLES ]++;
215ac953
MM
191 (h->ops->func)();
192 }
c422ecc7
MH
193 else if (orig_pc != PC && !State.exception)
194 ins_type_counters[ (int)INS_COND_JUMP ]++;
2934d1c9 195}
215ac953 196
2934d1c9
MH
197static void
198do_parallel (ins1, ins2)
199 uint16 ins1, ins2;
200{
201 struct hash_entry *h1, *h2;
7eebfc62
MM
202#ifdef DEBUG
203 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
204 (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
205#endif
c422ecc7 206 ins_type_counters[ (int)INS_PARALLEL ]++;
2934d1c9 207 h1 = lookup_hash (ins1, 0);
2934d1c9 208 h2 = lookup_hash (ins2, 0);
d70b4d42 209
2934d1c9
MH
210 if (h1->ops->exec_type == PARONLY)
211 {
d70b4d42 212 get_operands (h1->ops, ins1);
aeb1f26b 213 State.ins_type = INS_LEFT_COND_TEST;
7eebfc62 214 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
215 (h1->ops->func)();
216 if (State.exe)
d70b4d42 217 {
aeb1f26b 218 ins_type_counters[ (int)INS_COND_TRUE ]++;
d70b4d42 219 get_operands (h2->ops, ins2);
aeb1f26b
MM
220 State.ins_type = INS_RIGHT_COND_EXE;
221 ins_type_counters[ (int)State.ins_type ]++;
d70b4d42
MH
222 (h2->ops->func)();
223 }
aeb1f26b
MM
224 else
225 ins_type_counters[ (int)INS_COND_FALSE ]++;
2934d1c9
MH
226 }
227 else if (h2->ops->exec_type == PARONLY)
228 {
d70b4d42 229 get_operands (h2->ops, ins2);
aeb1f26b 230 State.ins_type = INS_RIGHT_COND_TEST;
7eebfc62 231 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9
MH
232 (h2->ops->func)();
233 if (State.exe)
d70b4d42 234 {
aeb1f26b 235 ins_type_counters[ (int)INS_COND_TRUE ]++;
d70b4d42 236 get_operands (h1->ops, ins1);
aeb1f26b
MM
237 State.ins_type = INS_LEFT_COND_EXE;
238 ins_type_counters[ (int)State.ins_type ]++;
d70b4d42
MH
239 (h1->ops->func)();
240 }
aeb1f26b
MM
241 else
242 ins_type_counters[ (int)INS_COND_FALSE ]++;
2934d1c9
MH
243 }
244 else
245 {
d70b4d42 246 get_operands (h1->ops, ins1);
87178dbd 247 State.ins_type = INS_LEFT_PARALLEL;
7eebfc62 248 ins_type_counters[ (int)State.ins_type ]++;
2934d1c9 249 (h1->ops->func)();
57bc1a72
MM
250 if (!State.exception)
251 {
252 get_operands (h2->ops, ins2);
253 State.ins_type = INS_RIGHT_PARALLEL;
254 ins_type_counters[ (int)State.ins_type ]++;
255 (h2->ops->func)();
256 }
2934d1c9
MH
257 }
258}
259
aeb1f26b
MM
260static char *
261add_commas(buf, sizeof_buf, value)
262 char *buf;
263 int sizeof_buf;
264 unsigned long value;
265{
266 int comma = 3;
267 char *endbuf = buf + sizeof_buf - 1;
268
269 *--endbuf = '\0';
270 do {
271 if (comma-- == 0)
272 {
273 *--endbuf = ',';
274 comma = 2;
275 }
276
277 *--endbuf = (value % 10) + '0';
278 } while ((value /= 10) != 0);
279
280 return endbuf;
281}
2934d1c9
MH
282
283void
284sim_size (power)
285 int power;
286
287{
c422ecc7
MH
288 int i;
289
2934d1c9
MH
290 if (State.imem)
291 {
c422ecc7
MH
292 for (i=0;i<128;i++)
293 {
294 if (State.umem[i])
295 {
296 free (State.umem[i]);
297 State.umem[i] = NULL;
298 }
299 }
2934d1c9
MH
300 free (State.imem);
301 free (State.dmem);
302 }
303
304 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
305 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
c422ecc7
MH
306 for (i=1;i<127;i++)
307 State.umem[i] = NULL;
308 State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
309 State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
310 State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
311 State.umem[127] = (uint8 *)calloc(1,1<<UMEM_SIZE);
312 if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[127] )
2934d1c9 313 {
7eebfc62 314 (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
2934d1c9
MH
315 exit(1);
316 }
c422ecc7
MH
317
318 SET_IMAP0(0x1000);
319 SET_IMAP1(0x1000);
320 SET_DMAP(0);
57bc1a72 321
7eebfc62
MM
322#ifdef DEBUG
323 if ((d10v_debug & DEBUG_MEMSIZE) != 0)
324 {
aeb1f26b
MM
325 char buffer[20];
326 (*d10v_callback->printf_filtered) (d10v_callback,
327 "Allocated %s bytes instruction memory and\n",
328 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
329
330 (*d10v_callback->printf_filtered) (d10v_callback, " %s bytes data memory.\n",
331 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
7eebfc62 332 }
87178dbd 333#endif
2934d1c9
MH
334}
335
336static void
337init_system ()
338{
339 if (!State.imem)
340 sim_size(1);
341}
342
c422ecc7
MH
343static int
344xfer_mem (addr, buffer, size, write)
2934d1c9
MH
345 SIM_ADDR addr;
346 unsigned char *buffer;
347 int size;
c422ecc7 348 int write;
2934d1c9 349{
c422ecc7
MH
350 if (!State.imem)
351 init_system ();
2934d1c9 352
57bc1a72
MM
353#ifdef DEBUG
354 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
c422ecc7
MH
355 {
356 if (write)
357 (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x\n", size, addr);
358 else
359 (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%x\n", size, addr);
360 }
57bc1a72
MM
361#endif
362
c422ecc7
MH
363 /* to access data, we use the following mapping */
364 /* 0x01000000 - 0x0103ffff : instruction memory */
365 /* 0x02000000 - 0x0200ffff : data memory */
04885cc3 366 /* 0x00000000 - 0x00ffffff : unified memory */
57bc1a72 367
04885cc3 368 if ( (addr & 0x03000000) == 0)
c422ecc7
MH
369 {
370 /* UNIFIED MEMORY */
371 int segment;
c422ecc7
MH
372 segment = addr >> UMEM_SIZE;
373 addr &= 0x1ffff;
374 if (!State.umem[segment])
04885cc3
DE
375 {
376#ifdef DEBUG
377 (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n",
378 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), segment);
379#endif
380 State.umem[segment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
381 }
c422ecc7
MH
382 if (!State.umem[segment])
383 {
384 (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
385 exit(1);
386 }
c422ecc7
MH
387 /* FIXME: need to check size and read/write multiple segments if necessary */
388 if (write)
04885cc3 389 memcpy (State.umem[segment]+addr, buffer, size) ;
c422ecc7
MH
390 else
391 memcpy (buffer, State.umem[segment]+addr, size);
392 }
393 else if ( (addr & 0x03000000) == 0x02000000)
394 {
395 /* DATA MEMORY */
396 addr &= ~0x02000000;
397 if (size > (1<<(DMEM_SIZE-1)))
398 {
399 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data section is only %d bytes.\n",1<<(DMEM_SIZE-1));
400 exit(1);
401 }
402 if (write)
403 memcpy (State.dmem+addr, buffer, size);
404 else
405 memcpy (buffer, State.dmem+addr, size);
406 }
407 else if ( (addr & 0x03000000) == 0x01000000)
408 {
409 /* INSTRUCTION MEMORY */
410 addr &= ~0x01000000;
411 if (size > (1<<IMEM_SIZE))
412 {
413 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: inst section is only %d bytes.\n",1<<IMEM_SIZE);
414 exit(1);
415 }
416 if (write)
417 memcpy (State.imem+addr, buffer, size);
418 else
419 memcpy (buffer, State.imem+addr, size);
420 }
421 else if (write)
422 {
423 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr);
424 (*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses start at 0x01000000\n");
425 (*d10v_callback->printf_filtered) (d10v_callback, "Data addresses start at 0x02000000\n");
04885cc3 426 (*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x00000000\n");
c422ecc7
MH
427 exit(1);
428 }
429 else
430 return 0;
57bc1a72 431
2934d1c9
MH
432 return size;
433}
434
c422ecc7
MH
435
436int
04885cc3
DE
437sim_write (sd, addr, buffer, size)
438 SIM_DESC sd;
c422ecc7
MH
439 SIM_ADDR addr;
440 unsigned char *buffer;
441 int size;
442{
443 return xfer_mem( addr, buffer, size, 1);
444}
445
446int
04885cc3
DE
447sim_read (sd, addr, buffer, size)
448 SIM_DESC sd;
c422ecc7
MH
449 SIM_ADDR addr;
450 unsigned char *buffer;
451 int size;
452{
453 return xfer_mem( addr, buffer, size, 0);
454}
455
456
04885cc3 457SIM_DESC
247fccde 458sim_open (kind, callback, abfd, argv)
04885cc3 459 SIM_OPEN_KIND kind;
247fccde
AC
460 host_callback *callback;
461 struct _bfd *abfd;
04885cc3 462 char **argv;
2934d1c9
MH
463{
464 struct simops *s;
aeb1f26b 465 struct hash_entry *h;
1eaaf305 466 static int init_p = 0;
04885cc3
DE
467 char **p;
468
469 sim_kind = kind;
247fccde 470 d10v_callback = callback;
04885cc3 471 myname = argv[0];
1eaaf305 472
04885cc3 473 for (p = argv + 1; *p; ++p)
1eaaf305
MM
474 {
475#ifdef DEBUG
04885cc3 476 if (strcmp (*p, "-t") == 0)
1eaaf305
MM
477 d10v_debug = DEBUG;
478 else
479#endif
04885cc3 480 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
1eaaf305 481 }
c422ecc7 482
2934d1c9 483 /* put all the opcodes in the hash table */
1eaaf305 484 if (!init_p++)
2934d1c9 485 {
1eaaf305 486 for (s = Simops; s->func; s++)
2934d1c9 487 {
1eaaf305
MM
488 h = &hash_table[hash(s->opcode,s->format)];
489
490 /* go to the last entry in the chain */
491 while (h->next)
492 h = h->next;
493
494 if (h->ops)
495 {
04885cc3
DE
496 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
497 if (!h->next)
498 perror ("malloc failure");
499
1eaaf305
MM
500 h = h->next;
501 }
502 h->ops = s;
503 h->mask = s->mask;
504 h->opcode = s->opcode;
cee402dd 505 h->size = s->is_long;
2934d1c9 506 }
2934d1c9 507 }
04885cc3
DE
508
509 /* Fudge our descriptor. */
510 return (SIM_DESC) 1;
2934d1c9
MH
511}
512
513
514void
04885cc3
DE
515sim_close (sd, quitting)
516 SIM_DESC sd;
2934d1c9
MH
517 int quitting;
518{
04885cc3
DE
519 if (prog_bfd != NULL && prog_bfd_was_opened_p)
520 bfd_close (prog_bfd);
2934d1c9
MH
521}
522
523void
524sim_set_profile (n)
525 int n;
526{
7eebfc62 527 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
2934d1c9
MH
528}
529
530void
531sim_set_profile_size (n)
532 int n;
533{
7eebfc62 534 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
2934d1c9
MH
535}
536
c422ecc7
MH
537
538uint8 *
539dmem_addr( addr )
540 uint32 addr;
541{
542 int seg;
543
544 addr &= 0xffff;
545
546 if (addr > 0xbfff)
547 {
548 if ( (addr & 0xfff0) != 0xff00)
04885cc3
DE
549 {
550 (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n",
551 (long)addr, (long)decode_pc ());
552 State.exception = SIGBUS;
553 }
554
c422ecc7
MH
555 return State.dmem + addr;
556 }
557
558 if (addr > 0x7fff)
559 {
560 if (DMAP & 0x1000)
561 {
562 /* instruction memory */
563 return (DMAP & 0xf) * 0x4000 + State.imem;
564 }
565 /* unified memory */
566 /* this is ugly because we allocate unified memory in 128K segments and */
567 /* dmap addresses 16k segments */
cee402dd 568 seg = (DMAP & 0x3ff) >> 3;
c422ecc7
MH
569 if (State.umem[seg] == NULL)
570 {
b30cdd35
MM
571 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n",
572 seg, (long)decode_pc ());
04885cc3 573 State.exception = SIGBUS;
c422ecc7 574 }
cee402dd 575 return State.umem[seg] + (DMAP & 7) * 0x4000;
c422ecc7
MH
576 }
577
578 return State.dmem + addr;
579}
580
581
582static uint8 *
583pc_addr()
584{
585 uint32 pc = ((uint32)PC) << 2;
586 uint16 imap;
587
588 if (pc & 0x20000)
589 imap = IMAP1;
590 else
591 imap = IMAP0;
592
593 if (imap & 0x1000)
594 return State.imem + pc;
595
596 if (State.umem[imap & 0xff] == NULL)
597 {
b30cdd35
MM
598 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n",
599 imap & 0xff, (long)PC);
04885cc3 600 State.exception = SIGBUS;
c422ecc7
MH
601 return 0;
602 }
603
604 return State.umem[imap & 0xff] + pc;
605}
606
607
cee402dd
DE
608static int stop_simulator;
609
610static void
611sim_ctrl_c()
612{
613 stop_simulator = 1;
614}
615
616
8517f62b
AC
617int
618sim_stop (sd)
619 SIM_DESC sd;
620{
621 stop_simulator = 1;
622 return 1;
623}
624
625
cee402dd 626/* Run (or resume) the program. */
2934d1c9 627void
04885cc3
DE
628sim_resume (sd, step, siggnal)
629 SIM_DESC sd;
2934d1c9
MH
630 int step, siggnal;
631{
cee402dd 632 void (*prev) ();
2934d1c9 633 uint32 inst;
2934d1c9 634
7eebfc62 635/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
eca43eb1 636 State.exception = 0;
cee402dd
DE
637 prev = signal(SIGINT, sim_ctrl_c);
638 stop_simulator = step;
639
aeb1f26b
MM
640 do
641 {
c422ecc7 642 inst = get_longword( pc_addr() );
cee402dd 643 State.pc_changed = 0;
c422ecc7
MH
644 ins_type_counters[ (int)INS_CYCLES ]++;
645 switch (inst & 0xC0000000)
aeb1f26b 646 {
c422ecc7
MH
647 case 0xC0000000:
648 /* long instruction */
649 do_long (inst & 0x3FFFFFFF);
650 break;
651 case 0x80000000:
652 /* R -> L */
653 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
654 break;
655 case 0x40000000:
656 /* L -> R */
657 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
658 break;
659 case 0:
660 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
661 break;
aeb1f26b 662 }
c422ecc7
MH
663
664 if (State.RP && PC == RPT_E)
aeb1f26b 665 {
c422ecc7
MH
666 RPT_C -= 1;
667 if (RPT_C == 0)
668 State.RP = 0;
669 else
670 PC = RPT_S;
aeb1f26b 671 }
cee402dd 672 else if (!State.pc_changed)
c422ecc7 673 PC++;
aeb1f26b 674 }
cee402dd 675 while ( !State.exception && !stop_simulator);
c422ecc7 676
aeb1f26b
MM
677 if (step && !State.exception)
678 State.exception = SIGTRAP;
cee402dd
DE
679
680 signal(SIGINT, prev);
2934d1c9
MH
681}
682
683int
04885cc3
DE
684sim_trace (sd)
685 SIM_DESC sd;
2934d1c9 686{
7eebfc62
MM
687#ifdef DEBUG
688 d10v_debug = DEBUG;
689#endif
04885cc3 690 sim_resume (sd, 0, 0);
7eebfc62 691 return 1;
2934d1c9
MH
692}
693
694void
04885cc3
DE
695sim_info (sd, verbose)
696 SIM_DESC sd;
2934d1c9
MH
697 int verbose;
698{
aeb1f26b
MM
699 char buf1[40];
700 char buf2[40];
701 char buf3[40];
702 char buf4[40];
703 char buf5[40];
704 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
705 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
706 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
707 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
708 unsigned long left_total = left + left_parallel + left_cond + left_nops;
709
710 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
711 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
712 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
713 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
714 unsigned long right_total = right + right_parallel + right_cond + right_nops;
715
716 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
717 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
c422ecc7
MH
718 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
719 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
720 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
aeb1f26b
MM
721 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
722 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
c422ecc7 723 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
aeb1f26b
MM
724 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
725 unsigned long total = (unknown + left_total + right_total + ins_long);
726
727 int size = strlen (add_commas (buf1, sizeof (buf1), total));
728 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
729 (left_parallel > right_parallel) ? left_parallel : right_parallel));
730 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
731 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
732 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
733
734 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 735 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
aeb1f26b
MM
736 size, add_commas (buf1, sizeof (buf1), left_total),
737 normal_size, add_commas (buf2, sizeof (buf2), left),
738 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
739 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
740 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
741
742 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 743 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
aeb1f26b
MM
744 size, add_commas (buf1, sizeof (buf1), right_total),
745 normal_size, add_commas (buf2, sizeof (buf2), right),
746 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
747 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
748 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
749
c422ecc7
MH
750 if (ins_long)
751 (*d10v_callback->printf_filtered) (d10v_callback,
752 "executed %*s long instruction(s)\n",
753 size, add_commas (buf1, sizeof (buf1), ins_long));
754
755 if (parallel)
756 (*d10v_callback->printf_filtered) (d10v_callback,
757 "executed %*s parallel instruction(s)\n",
758 size, add_commas (buf1, sizeof (buf1), parallel));
759
760 if (leftright)
761 (*d10v_callback->printf_filtered) (d10v_callback,
762 "executed %*s instruction(s) encoded L->R\n",
763 size, add_commas (buf1, sizeof (buf1), leftright));
764
765 if (rightleft)
766 (*d10v_callback->printf_filtered) (d10v_callback,
767 "executed %*s instruction(s) encoded R->L\n",
768 size, add_commas (buf1, sizeof (buf1), rightleft));
7eebfc62 769
aeb1f26b
MM
770 if (unknown)
771 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 772 "executed %*s unknown instruction(s)\n",
aeb1f26b 773 size, add_commas (buf1, sizeof (buf1), unknown));
7eebfc62 774
c422ecc7
MH
775 if (cond_true)
776 (*d10v_callback->printf_filtered) (d10v_callback,
777 "executed %*s instruction(s) due to EXExxx condition being true\n",
778 size, add_commas (buf1, sizeof (buf1), cond_true));
7eebfc62 779
c422ecc7
MH
780 if (cond_false)
781 (*d10v_callback->printf_filtered) (d10v_callback,
782 "skipped %*s instruction(s) due to EXExxx condition being false\n",
783 size, add_commas (buf1, sizeof (buf1), cond_false));
784
785 if (cond_jump)
786 (*d10v_callback->printf_filtered) (d10v_callback,
787 "skipped %*s instruction(s) due to conditional branch succeeding\n",
788 size, add_commas (buf1, sizeof (buf1), cond_jump));
7eebfc62
MM
789
790 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 791 "executed %*s cycle(s)\n",
aeb1f26b 792 size, add_commas (buf1, sizeof (buf1), cycles));
7eebfc62
MM
793
794 (*d10v_callback->printf_filtered) (d10v_callback,
aeb1f26b
MM
795 "executed %*s total instructions\n",
796 size, add_commas (buf1, sizeof (buf1), total));
2934d1c9
MH
797}
798
04885cc3
DE
799SIM_RC
800sim_create_inferior (sd, argv, env)
801 SIM_DESC sd;
2934d1c9
MH
802 char **argv;
803 char **env;
804{
7eebfc62
MM
805#ifdef DEBUG
806 if (d10v_debug)
807 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%x\n", start_address);
808#endif
c422ecc7 809
57bc1a72 810 /* reset all state information */
c422ecc7
MH
811 memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]);
812
57bc1a72 813 /* set PC */
2934d1c9 814 PC = start_address >> 2;
c422ecc7
MH
815
816 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
817 /* resets imap0 and imap1 to 0x1000. */
818
819 SET_IMAP0(0x1000);
820 SET_IMAP1(0x1000);
821 SET_DMAP(0);
04885cc3
DE
822
823 return SIM_RC_OK;
2934d1c9
MH
824}
825
826
2934d1c9 827void
247fccde 828sim_set_callbacks (p)
2934d1c9
MH
829 host_callback *p;
830{
87178dbd 831 d10v_callback = p;
2934d1c9
MH
832}
833
834void
04885cc3
DE
835sim_stop_reason (sd, reason, sigrc)
836 SIM_DESC sd;
2934d1c9
MH
837 enum sim_stop *reason;
838 int *sigrc;
839{
7eebfc62 840/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
d70b4d42 841
a49a15ad 842 switch (State.exception)
d70b4d42 843 {
a49a15ad 844 case SIG_D10V_STOP: /* stop instruction */
d70b4d42 845 *reason = sim_exited;
a49a15ad
MM
846 *sigrc = 0;
847 break;
848
849 case SIG_D10V_EXIT: /* exit trap */
850 *reason = sim_exited;
851 *sigrc = State.regs[2];
852 break;
853
854 default: /* some signal */
d70b4d42
MH
855 *reason = sim_stopped;
856 *sigrc = State.exception;
a49a15ad 857 break;
d70b4d42
MH
858 }
859}
860
861void
04885cc3
DE
862sim_fetch_register (sd, rn, memory)
863 SIM_DESC sd;
d70b4d42
MH
864 int rn;
865 unsigned char *memory;
866{
c422ecc7
MH
867 if (!State.imem)
868 init_system();
869
870 if (rn > 34)
5c839c67 871 WRITE_64 (memory, State.a[rn-35]);
c422ecc7
MH
872 else if (rn == 32)
873 WRITE_16 (memory, IMAP0);
874 else if (rn == 33)
875 WRITE_16 (memory, IMAP1);
876 else if (rn == 34)
877 WRITE_16 (memory, DMAP);
d70b4d42 878 else
c422ecc7 879 WRITE_16 (memory, State.regs[rn]);
d70b4d42
MH
880}
881
882void
04885cc3
DE
883sim_store_register (sd, rn, memory)
884 SIM_DESC sd;
d70b4d42
MH
885 int rn;
886 unsigned char *memory;
887{
c422ecc7
MH
888 if (!State.imem)
889 init_system();
890
891 if (rn > 34)
5c839c67 892 State.a[rn-35] = READ_64 (memory) & MASK40;
c422ecc7
MH
893 else if (rn == 34)
894 SET_DMAP( READ_16(memory) );
895 else if (rn == 33)
896 SET_IMAP1( READ_16(memory) );
897 else if (rn == 32)
898 SET_IMAP0( READ_16(memory) );
d70b4d42 899 else
c422ecc7 900 State.regs[rn]= READ_16 (memory);
2934d1c9 901}
d70b4d42 902
d70b4d42
MH
903
904void
04885cc3
DE
905sim_do_command (sd, cmd)
906 SIM_DESC sd;
d70b4d42
MH
907 char *cmd;
908{
7eebfc62 909 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
d70b4d42
MH
910}
911
04885cc3
DE
912SIM_RC
913sim_load (sd, prog, abfd, from_tty)
914 SIM_DESC sd;
d70b4d42 915 char *prog;
04885cc3 916 bfd *abfd;
d70b4d42
MH
917 int from_tty;
918{
04885cc3
DE
919 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
920
921 if (prog_bfd != NULL && prog_bfd_was_opened_p)
922 bfd_close (prog_bfd);
923 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
924 sim_kind == SIM_OPEN_DEBUG);
925 if (prog_bfd == NULL)
926 return SIM_RC_FAIL;
927 start_address = bfd_get_start_address (prog_bfd);
928 prog_bfd_was_opened_p = abfd == NULL;
929 return SIM_RC_OK;
d70b4d42 930}
This page took 0.096685 seconds and 4 git commands to generate.