]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/d10v/interp.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[thirdparty/binutils-gdb.git] / sim / d10v / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4 #include "callback.h"
5 #include "remote-sim.h"
6
7 #include "d10v_sim.h"
8
9 #define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
10 #define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */
11 #define UMEM_SIZE 17 /* Each unified memory segment is 17 bits */
12 #define UMEM_SEGMENTS 128 /* Number of segments in unified memory region */
13
14 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
15
16 static char *myname;
17 static SIM_OPEN_KIND sim_kind;
18 int d10v_debug;
19 host_callback *d10v_callback;
20 unsigned long ins_type_counters[ (int)INS_MAX ];
21
22 uint16 OP[4];
23
24 static int init_text_p = 0;
25 /* non-zero if we opened prog_bfd */
26 static int prog_bfd_was_opened_p;
27 bfd *prog_bfd;
28 asection *text;
29 bfd_vma text_start;
30 bfd_vma text_end;
31
32 static long hash PARAMS ((long insn, int format));
33 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
34 static void get_operands PARAMS ((struct simops *s, uint32 ins));
35 static void do_long PARAMS ((uint32 ins));
36 static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
37 static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
38 static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
39 extern void sim_set_profile PARAMS ((int n));
40 extern void sim_set_profile_size PARAMS ((int n));
41
42 #ifdef NEED_UI_LOOP_HOOK
43 /* How often to run the ui_loop update, when in use */
44 #define UI_LOOP_POLL_INTERVAL 0x14000
45
46 /* Counter for the ui_loop_hook update */
47 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
48
49 /* Actual hook to call to run through gdb's gui event loop */
50 extern int (*ui_loop_hook) PARAMS ((int signo));
51 #endif /* NEED_UI_LOOP_HOOK */
52
53 #ifndef INLINE
54 #if defined(__GNUC__) && defined(__OPTIMIZE__)
55 #define INLINE __inline__
56 #else
57 #define INLINE
58 #endif
59 #endif
60
61 #define MAX_HASH 63
62 struct hash_entry
63 {
64 struct hash_entry *next;
65 uint32 opcode;
66 uint32 mask;
67 int size;
68 struct simops *ops;
69 };
70
71 struct hash_entry hash_table[MAX_HASH+1];
72
73 INLINE static long
74 hash(insn, format)
75 long insn;
76 int format;
77 {
78 if (format & LONG_OPCODE)
79 return ((insn & 0x3F000000) >> 24);
80 else
81 return((insn & 0x7E00) >> 9);
82 }
83
84 INLINE static struct hash_entry *
85 lookup_hash (ins, size)
86 uint32 ins;
87 int size;
88 {
89 struct hash_entry *h;
90
91 if (size)
92 h = &hash_table[(ins & 0x3F000000) >> 24];
93 else
94 h = &hash_table[(ins & 0x7E00) >> 9];
95
96 while ((ins & h->mask) != h->opcode || h->size != size)
97 {
98 if (h->next == NULL)
99 {
100 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
101 exit (1);
102 }
103 h = h->next;
104 }
105 return (h);
106 }
107
108 INLINE static void
109 get_operands (struct simops *s, uint32 ins)
110 {
111 int i, shift, bits, flags;
112 uint32 mask;
113 for (i=0; i < s->numops; i++)
114 {
115 shift = s->operands[3*i];
116 bits = s->operands[3*i+1];
117 flags = s->operands[3*i+2];
118 mask = 0x7FFFFFFF >> (31 - bits);
119 OP[i] = (ins >> shift) & mask;
120 }
121 /* FIXME: for tracing, update values that need to be updated each
122 instruction decode cycle */
123 State.trace.psw = PSW;
124 }
125
126 bfd_vma
127 decode_pc ()
128 {
129 asection *s;
130 if (!init_text_p && prog_bfd != NULL)
131 {
132 init_text_p = 1;
133 for (s = prog_bfd->sections; s; s = s->next)
134 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
135 {
136 text = s;
137 text_start = bfd_get_section_vma (prog_bfd, s);
138 text_end = text_start + bfd_section_size (prog_bfd, s);
139 break;
140 }
141 }
142
143 return (PC << 2) + text_start;
144 }
145
146 static void
147 do_long (ins)
148 uint32 ins;
149 {
150 struct hash_entry *h;
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
155 h = lookup_hash (ins, 1);
156 get_operands (h->ops, ins);
157 State.ins_type = INS_LONG;
158 ins_type_counters[ (int)State.ins_type ]++;
159 (h->ops->func)();
160 }
161
162 static void
163 do_2_short (ins1, ins2, leftright)
164 uint16 ins1, ins2;
165 enum _leftright leftright;
166 {
167 struct hash_entry *h;
168 enum _ins_type first, second;
169
170 #ifdef DEBUG
171 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
172 (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
173 ins1, (leftright) ? "left" : "right", ins2);
174 #endif
175
176 if (leftright == LEFT_FIRST)
177 {
178 first = INS_LEFT;
179 second = INS_RIGHT;
180 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
181 }
182 else
183 {
184 first = INS_RIGHT;
185 second = INS_LEFT;
186 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
187 }
188
189 /* Issue the first instruction */
190 h = lookup_hash (ins1, 0);
191 get_operands (h->ops, ins1);
192 State.ins_type = first;
193 ins_type_counters[ (int)State.ins_type ]++;
194 (h->ops->func)();
195
196 /* Issue the second instruction (if the PC hasn't changed) */
197 if (!State.pc_changed && !State.exception)
198 {
199 /* finish any existing instructions */
200 SLOT_FLUSH ();
201 h = lookup_hash (ins2, 0);
202 get_operands (h->ops, ins2);
203 State.ins_type = second;
204 ins_type_counters[ (int)State.ins_type ]++;
205 ins_type_counters[ (int)INS_CYCLES ]++;
206 (h->ops->func)();
207 }
208 else if (!State.exception)
209 ins_type_counters[ (int)INS_COND_JUMP ]++;
210 }
211
212 static void
213 do_parallel (ins1, ins2)
214 uint16 ins1, ins2;
215 {
216 struct hash_entry *h1, *h2;
217 #ifdef DEBUG
218 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
219 (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
220 #endif
221 ins_type_counters[ (int)INS_PARALLEL ]++;
222 h1 = lookup_hash (ins1, 0);
223 h2 = lookup_hash (ins2, 0);
224
225 if (h1->ops->exec_type == PARONLY)
226 {
227 get_operands (h1->ops, ins1);
228 State.ins_type = INS_LEFT_COND_TEST;
229 ins_type_counters[ (int)State.ins_type ]++;
230 (h1->ops->func)();
231 if (State.exe)
232 {
233 ins_type_counters[ (int)INS_COND_TRUE ]++;
234 get_operands (h2->ops, ins2);
235 State.ins_type = INS_RIGHT_COND_EXE;
236 ins_type_counters[ (int)State.ins_type ]++;
237 (h2->ops->func)();
238 }
239 else
240 ins_type_counters[ (int)INS_COND_FALSE ]++;
241 }
242 else if (h2->ops->exec_type == PARONLY)
243 {
244 get_operands (h2->ops, ins2);
245 State.ins_type = INS_RIGHT_COND_TEST;
246 ins_type_counters[ (int)State.ins_type ]++;
247 (h2->ops->func)();
248 if (State.exe)
249 {
250 ins_type_counters[ (int)INS_COND_TRUE ]++;
251 get_operands (h1->ops, ins1);
252 State.ins_type = INS_LEFT_COND_EXE;
253 ins_type_counters[ (int)State.ins_type ]++;
254 (h1->ops->func)();
255 }
256 else
257 ins_type_counters[ (int)INS_COND_FALSE ]++;
258 }
259 else
260 {
261 get_operands (h1->ops, ins1);
262 State.ins_type = INS_LEFT_PARALLEL;
263 ins_type_counters[ (int)State.ins_type ]++;
264 (h1->ops->func)();
265 if (!State.exception)
266 {
267 get_operands (h2->ops, ins2);
268 State.ins_type = INS_RIGHT_PARALLEL;
269 ins_type_counters[ (int)State.ins_type ]++;
270 (h2->ops->func)();
271 }
272 }
273 }
274
275 static char *
276 add_commas(buf, sizeof_buf, value)
277 char *buf;
278 int sizeof_buf;
279 unsigned long value;
280 {
281 int comma = 3;
282 char *endbuf = buf + sizeof_buf - 1;
283
284 *--endbuf = '\0';
285 do {
286 if (comma-- == 0)
287 {
288 *--endbuf = ',';
289 comma = 2;
290 }
291
292 *--endbuf = (value % 10) + '0';
293 } while ((value /= 10) != 0);
294
295 return endbuf;
296 }
297
298 void
299 sim_size (power)
300 int power;
301
302 {
303 int i;
304
305 if (State.imem)
306 {
307 for (i=0;i<UMEM_SEGMENTS;i++)
308 {
309 if (State.umem[i])
310 {
311 free (State.umem[i]);
312 State.umem[i] = NULL;
313 }
314 }
315 free (State.imem);
316 free (State.dmem);
317 }
318
319 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
320 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
321 for (i=1;i<(UMEM_SEGMENTS-1);i++)
322 State.umem[i] = NULL;
323 State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
324 State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
325 State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
326 State.umem[UMEM_SEGMENTS-1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
327 if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[UMEM_SEGMENTS-1] )
328 {
329 (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
330 exit(1);
331 }
332
333 #ifdef DEBUG
334 if ((d10v_debug & DEBUG_MEMSIZE) != 0)
335 {
336 char buffer[20];
337 (*d10v_callback->printf_filtered) (d10v_callback,
338 "Allocated %s bytes instruction memory and\n",
339 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
340
341 (*d10v_callback->printf_filtered) (d10v_callback, " %s bytes data memory.\n",
342 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
343 }
344 #endif
345 }
346
347 /* Transfer data to/from simulated memory. Since a bug in either the
348 simulated program or in gdb or the simulator itself may cause a
349 bogus address to be passed in, we need to do some sanity checking
350 on addresses to make sure they are within bounds. When an address
351 fails the bounds check, treat it as a zero length read/write rather
352 than aborting the entire run. */
353
354 static int
355 xfer_mem (SIM_ADDR addr,
356 unsigned char *buffer,
357 int size,
358 int write_p)
359 {
360 unsigned char *memory;
361 int segment = ((addr >> 24) & 0xff);
362 addr = (addr & 0x00ffffff);
363
364 #ifdef DEBUG
365 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
366 {
367 if (write_p)
368 {
369 (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%02x:%06x\n", size, segment, addr);
370 }
371 else
372 {
373 (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%2x:%6x\n", size, segment, addr);
374 }
375 }
376 #endif
377
378 /* to access data, we use the following mapping
379 0x00xxxxxx: Logical data address segment (DMAP translated memory)
380 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
381 0x10xxxxxx: Physical data memory segment (On-chip data memory)
382 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
383 0x12xxxxxx: Phisical unified memory segment (Unified memory)
384 */
385
386 switch (segment)
387 {
388 case 0x00: /* DMAP translated memory */
389 {
390 int byte;
391 for (byte = 0; byte < size; byte++)
392 {
393 uint8 *mem = dmem_addr (addr + byte);
394 if (mem == NULL)
395 return byte;
396 else if (write_p)
397 *mem = buffer[byte];
398 else
399 buffer[byte] = *mem;
400 }
401 return byte;
402 }
403
404 case 0x01: /* IMAP translated memory */
405 {
406 int byte;
407 for (byte = 0; byte < size; byte++)
408 {
409 uint8 *mem = imem_addr (addr + byte);
410 if (mem == NULL)
411 return byte;
412 else if (write_p)
413 *mem = buffer[byte];
414 else
415 buffer[byte] = *mem;
416 }
417 return byte;
418 }
419
420 case 0x10: /* On-chip data memory */
421 {
422 addr &= ((1 << DMEM_SIZE) - 1);
423 if ((addr + size) > (1 << DMEM_SIZE))
424 {
425 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data address 0x%x is outside range 0-0x%x.\n",
426 addr + size - 1, (1 << DMEM_SIZE) - 1);
427 return (0);
428 }
429 memory = State.dmem + addr;
430 break;
431 }
432
433 case 0x11: /* On-chip insn memory */
434 {
435 addr &= ((1 << IMEM_SIZE) - 1);
436 if ((addr + size) > (1 << IMEM_SIZE))
437 {
438 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: instruction address 0x%x is outside range 0-0x%x.\n",
439 addr + size - 1, (1 << IMEM_SIZE) - 1);
440 return (0);
441 }
442 memory = State.imem + addr;
443 break;
444 }
445
446 case 0x12: /* Unified memory */
447 {
448 int startsegment, startoffset; /* Segment and offset within segment where xfer starts */
449 int endsegment, endoffset; /* Segment and offset within segment where xfer ends */
450
451 startsegment = addr >> UMEM_SIZE;
452 startoffset = addr & ((1 << UMEM_SIZE) - 1);
453 endsegment = (addr + size) >> UMEM_SIZE;
454 endoffset = (addr + size) & ((1 << UMEM_SIZE) - 1);
455
456 /* FIXME: We do not currently implement xfers across segments,
457 so detect this case and fail gracefully. */
458
459 if ((startsegment != endsegment) && !((endsegment == (startsegment + 1)) && endoffset == 0))
460 {
461 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Unimplemented support for transfers across unified memory segment boundaries\n");
462 return (0);
463 }
464 if (!State.umem[startsegment])
465 {
466 #ifdef DEBUG
467 if ((d10v_debug & DEBUG_MEMSIZE) != 0)
468 {
469 (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n",
470 add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), startsegment);
471 }
472 #endif
473 State.umem[startsegment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
474 }
475 if (!State.umem[startsegment])
476 {
477 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Memory allocation of 0x%x bytes failed.\n", 1<<UMEM_SIZE);
478 return (0);
479 }
480 memory = State.umem[startsegment] + startoffset;
481 break;
482 }
483
484 default:
485 {
486 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%lx is not in valid range\n", (long) addr);
487 (*d10v_callback->printf_filtered) (d10v_callback, "0x00xxxxxx: Logical data address segment (DMAP translated memory)\n");
488 (*d10v_callback->printf_filtered) (d10v_callback, "0x01xxxxxx: Logical instruction address segment (IMAP translated memory)\n");
489 (*d10v_callback->printf_filtered) (d10v_callback, "0x10xxxxxx: Physical data memory segment (On-chip data memory)\n");
490 (*d10v_callback->printf_filtered) (d10v_callback, "0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)\n");
491 (*d10v_callback->printf_filtered) (d10v_callback, "0x12xxxxxx: Phisical unified memory segment (Unified memory)\n");
492 return (0);
493 }
494 }
495
496 if (write_p)
497 {
498 memcpy (memory, buffer, size);
499 }
500 else
501 {
502 memcpy (buffer, memory, size);
503 }
504
505 return size;
506 }
507
508
509 int
510 sim_write (sd, addr, buffer, size)
511 SIM_DESC sd;
512 SIM_ADDR addr;
513 unsigned char *buffer;
514 int size;
515 {
516 /* FIXME: this should be performing a virtual transfer */
517 return xfer_mem( addr, buffer, size, 1);
518 }
519
520 int
521 sim_read (sd, addr, buffer, size)
522 SIM_DESC sd;
523 SIM_ADDR addr;
524 unsigned char *buffer;
525 int size;
526 {
527 /* FIXME: this should be performing a virtual transfer */
528 return xfer_mem( addr, buffer, size, 0);
529 }
530
531
532 SIM_DESC
533 sim_open (kind, callback, abfd, argv)
534 SIM_OPEN_KIND kind;
535 host_callback *callback;
536 struct _bfd *abfd;
537 char **argv;
538 {
539 struct simops *s;
540 struct hash_entry *h;
541 static int init_p = 0;
542 char **p;
543
544 sim_kind = kind;
545 d10v_callback = callback;
546 myname = argv[0];
547
548 for (p = argv + 1; *p; ++p)
549 {
550 #ifdef DEBUG
551 if (strcmp (*p, "-t") == 0)
552 d10v_debug = DEBUG;
553 else
554 #endif
555 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
556 }
557
558 /* put all the opcodes in the hash table */
559 if (!init_p++)
560 {
561 for (s = Simops; s->func; s++)
562 {
563 h = &hash_table[hash(s->opcode,s->format)];
564
565 /* go to the last entry in the chain */
566 while (h->next)
567 h = h->next;
568
569 if (h->ops)
570 {
571 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
572 if (!h->next)
573 perror ("malloc failure");
574
575 h = h->next;
576 }
577 h->ops = s;
578 h->mask = s->mask;
579 h->opcode = s->opcode;
580 h->size = s->is_long;
581 }
582 }
583
584 /* reset the processor state */
585 if (!State.imem)
586 sim_size(1);
587 sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
588
589 /* Fudge our descriptor. */
590 return (SIM_DESC) 1;
591 }
592
593
594 void
595 sim_close (sd, quitting)
596 SIM_DESC sd;
597 int quitting;
598 {
599 if (prog_bfd != NULL && prog_bfd_was_opened_p)
600 {
601 bfd_close (prog_bfd);
602 prog_bfd = NULL;
603 prog_bfd_was_opened_p = 0;
604 }
605 }
606
607 void
608 sim_set_profile (n)
609 int n;
610 {
611 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
612 }
613
614 void
615 sim_set_profile_size (n)
616 int n;
617 {
618 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
619 }
620
621
622 uint8 *
623 dmem_addr( addr )
624 uint32 addr;
625 {
626 int seg;
627
628 addr &= 0xffff;
629
630 if (addr > 0xbfff)
631 {
632 if ( (addr & 0xfff0) != 0xff00)
633 {
634 (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n",
635 (long)addr, (long)decode_pc ());
636 State.exception = SIGBUS;
637 }
638
639 return State.dmem + addr;
640 }
641
642 if (addr > 0x7fff)
643 {
644 if (DMAP & 0x1000)
645 {
646 /* instruction memory */
647 return (DMAP & 0xf) * 0x4000 + State.imem + (addr - 0x8000);
648 }
649 else
650 {
651 /* unified memory */
652 /* this is ugly because we allocate unified memory in 128K segments and */
653 /* dmap addresses 16k segments */
654 seg = (DMAP & 0x3ff) >> 3;
655 if (State.umem[seg] == NULL)
656 {
657 #ifdef DEBUG
658 (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %d bytes unified memory to region %d\n", 1<<UMEM_SIZE, seg);
659 #endif
660 State.umem[seg] = (uint8 *)calloc(1,1<<UMEM_SIZE);
661 if (!State.umem[seg])
662 {
663 (*d10v_callback->printf_filtered) (d10v_callback,
664 "ERROR: alloc failed. unified memory region %d unmapped, pc = 0x%lx\n",
665 seg, (long)decode_pc ());
666 State.exception = SIGBUS;
667 }
668 }
669 return State.umem[seg] + (DMAP & 7) * 0x4000 + (addr - 0x8000);
670 }
671 }
672 return State.dmem + addr;
673 }
674
675
676 uint8 *
677 imem_addr (uint32 pc)
678 {
679 uint16 imap;
680
681 if (pc & 0x20000)
682 imap = IMAP1;
683 else
684 imap = IMAP0;
685
686 if (imap & 0x1000)
687 return State.imem + pc;
688
689 if (State.umem[imap & 0xff] == NULL)
690 return 0;
691
692 /* Discard upper bit(s) of PC in case IMAP1 selects unified memory. */
693 pc &= (1 << UMEM_SIZE) - 1;
694
695 return State.umem[imap & 0xff] + pc;
696 }
697
698
699 static int stop_simulator = 0;
700
701 int
702 sim_stop (sd)
703 SIM_DESC sd;
704 {
705 stop_simulator = 1;
706 return 1;
707 }
708
709
710 /* Run (or resume) the program. */
711 void
712 sim_resume (sd, step, siggnal)
713 SIM_DESC sd;
714 int step, siggnal;
715 {
716 uint32 inst;
717 uint8 *iaddr;
718
719 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
720 State.exception = 0;
721 if (step)
722 sim_stop (sd);
723
724 do
725 {
726 iaddr = imem_addr ((uint32)PC << 2);
727 if (iaddr == NULL)
728 {
729 State.exception = SIGBUS;
730 break;
731 }
732
733 inst = get_longword( iaddr );
734
735 State.pc_changed = 0;
736 ins_type_counters[ (int)INS_CYCLES ]++;
737
738 switch (inst & 0xC0000000)
739 {
740 case 0xC0000000:
741 /* long instruction */
742 do_long (inst & 0x3FFFFFFF);
743 break;
744 case 0x80000000:
745 /* R -> L */
746 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
747 break;
748 case 0x40000000:
749 /* L -> R */
750 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
751 break;
752 case 0:
753 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
754 break;
755 }
756
757 /* If the PC of the current instruction matches RPT_E then
758 schedule a branch to the loop start. If one of those
759 instructions happens to be a branch, than that instruction
760 will be ignored */
761 if (!State.pc_changed)
762 {
763 if (PSW_RP && PC == RPT_E)
764 {
765 /* Note: The behavour of a branch instruction at RPT_E
766 is implementation dependant, this simulator takes the
767 branch. Branching to RPT_E is valid, the instruction
768 must be executed before the loop is taken. */
769 if (RPT_C == 1)
770 {
771 SET_PSW_RP (0);
772 SET_RPT_C (0);
773 SET_PC (PC + 1);
774 }
775 else
776 {
777 SET_RPT_C (RPT_C - 1);
778 SET_PC (RPT_S);
779 }
780 }
781 else
782 SET_PC (PC + 1);
783 }
784
785 /* Check for a breakpoint trap on this instruction. This
786 overrides any pending branches or loops */
787 if (PSW_DB && PC == IBA)
788 {
789 SET_BPC (PC);
790 SET_BPSW (PSW);
791 SET_PSW (PSW & PSW_SM_BIT);
792 SET_PC (SDBT_VECTOR_START);
793 }
794
795 /* Writeback all the DATA / PC changes */
796 SLOT_FLUSH ();
797
798 #ifdef NEED_UI_LOOP_HOOK
799 if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
800 {
801 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
802 ui_loop_hook (0);
803 }
804 #endif /* NEED_UI_LOOP_HOOK */
805 }
806 while ( !State.exception && !stop_simulator);
807
808 if (step && !State.exception)
809 State.exception = SIGTRAP;
810 }
811
812 int
813 sim_trace (sd)
814 SIM_DESC sd;
815 {
816 #ifdef DEBUG
817 d10v_debug = DEBUG;
818 #endif
819 sim_resume (sd, 0, 0);
820 return 1;
821 }
822
823 void
824 sim_info (sd, verbose)
825 SIM_DESC sd;
826 int verbose;
827 {
828 char buf1[40];
829 char buf2[40];
830 char buf3[40];
831 char buf4[40];
832 char buf5[40];
833 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
834 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
835 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
836 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
837 unsigned long left_total = left + left_parallel + left_cond + left_nops;
838
839 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
840 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
841 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
842 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
843 unsigned long right_total = right + right_parallel + right_cond + right_nops;
844
845 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
846 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
847 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
848 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
849 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
850 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
851 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
852 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
853 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
854 unsigned long total = (unknown + left_total + right_total + ins_long);
855
856 int size = strlen (add_commas (buf1, sizeof (buf1), total));
857 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
858 (left_parallel > right_parallel) ? left_parallel : right_parallel));
859 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
860 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
861 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
862
863 (*d10v_callback->printf_filtered) (d10v_callback,
864 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
865 size, add_commas (buf1, sizeof (buf1), left_total),
866 normal_size, add_commas (buf2, sizeof (buf2), left),
867 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
868 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
869 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
870
871 (*d10v_callback->printf_filtered) (d10v_callback,
872 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
873 size, add_commas (buf1, sizeof (buf1), right_total),
874 normal_size, add_commas (buf2, sizeof (buf2), right),
875 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
876 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
877 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
878
879 if (ins_long)
880 (*d10v_callback->printf_filtered) (d10v_callback,
881 "executed %*s long instruction(s)\n",
882 size, add_commas (buf1, sizeof (buf1), ins_long));
883
884 if (parallel)
885 (*d10v_callback->printf_filtered) (d10v_callback,
886 "executed %*s parallel instruction(s)\n",
887 size, add_commas (buf1, sizeof (buf1), parallel));
888
889 if (leftright)
890 (*d10v_callback->printf_filtered) (d10v_callback,
891 "executed %*s instruction(s) encoded L->R\n",
892 size, add_commas (buf1, sizeof (buf1), leftright));
893
894 if (rightleft)
895 (*d10v_callback->printf_filtered) (d10v_callback,
896 "executed %*s instruction(s) encoded R->L\n",
897 size, add_commas (buf1, sizeof (buf1), rightleft));
898
899 if (unknown)
900 (*d10v_callback->printf_filtered) (d10v_callback,
901 "executed %*s unknown instruction(s)\n",
902 size, add_commas (buf1, sizeof (buf1), unknown));
903
904 if (cond_true)
905 (*d10v_callback->printf_filtered) (d10v_callback,
906 "executed %*s instruction(s) due to EXExxx condition being true\n",
907 size, add_commas (buf1, sizeof (buf1), cond_true));
908
909 if (cond_false)
910 (*d10v_callback->printf_filtered) (d10v_callback,
911 "skipped %*s instruction(s) due to EXExxx condition being false\n",
912 size, add_commas (buf1, sizeof (buf1), cond_false));
913
914 if (cond_jump)
915 (*d10v_callback->printf_filtered) (d10v_callback,
916 "skipped %*s instruction(s) due to conditional branch succeeding\n",
917 size, add_commas (buf1, sizeof (buf1), cond_jump));
918
919 (*d10v_callback->printf_filtered) (d10v_callback,
920 "executed %*s cycle(s)\n",
921 size, add_commas (buf1, sizeof (buf1), cycles));
922
923 (*d10v_callback->printf_filtered) (d10v_callback,
924 "executed %*s total instructions\n",
925 size, add_commas (buf1, sizeof (buf1), total));
926 }
927
928 SIM_RC
929 sim_create_inferior (sd, abfd, argv, env)
930 SIM_DESC sd;
931 struct _bfd *abfd;
932 char **argv;
933 char **env;
934 {
935 bfd_vma start_address;
936
937 /* reset all state information */
938 memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]);
939
940 if (argv)
941 {
942 /* a hack to set r0/r1 with argc/argv */
943 /* some high memory that won't be overwritten by the stack soon */
944 bfd_vma addr = 0x7C00;
945 int p = 20;
946 int i = 0;
947 while (argv[i])
948 {
949 int size = strlen (argv[i]) + 1;
950 SW (addr + 2*i, addr + p);
951 sim_write (sd, addr + 0, argv[i], size);
952 p += size;
953 i++;
954 }
955 SET_GPR (0, addr);
956 SET_GPR (1, i);
957 }
958
959 /* set PC */
960 if (abfd != NULL)
961 start_address = bfd_get_start_address (abfd);
962 else
963 start_address = 0xffc0 << 2;
964 #ifdef DEBUG
965 if (d10v_debug)
966 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
967 #endif
968 SET_CREG (PC_CR, start_address >> 2);
969
970 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
971 /* resets imap0 and imap1 to 0x1000. */
972 if (1)
973 {
974 SET_IMAP0 (0x0000);
975 SET_IMAP1 (0x007f);
976 SET_DMAP (0x0000);
977 }
978 else
979 {
980 SET_IMAP0 (0x1000);
981 SET_IMAP1 (0x1000);
982 SET_DMAP(0);
983 }
984
985 SLOT_FLUSH ();
986 return SIM_RC_OK;
987 }
988
989
990 void
991 sim_set_callbacks (p)
992 host_callback *p;
993 {
994 d10v_callback = p;
995 }
996
997 void
998 sim_stop_reason (sd, reason, sigrc)
999 SIM_DESC sd;
1000 enum sim_stop *reason;
1001 int *sigrc;
1002 {
1003 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1004
1005 switch (State.exception)
1006 {
1007 case SIG_D10V_STOP: /* stop instruction */
1008 *reason = sim_exited;
1009 *sigrc = 0;
1010 break;
1011
1012 case SIG_D10V_EXIT: /* exit trap */
1013 *reason = sim_exited;
1014 *sigrc = GPR (0);
1015 break;
1016
1017 default: /* some signal */
1018 *reason = sim_stopped;
1019 if (stop_simulator && !State.exception)
1020 *sigrc = SIGINT;
1021 else
1022 *sigrc = State.exception;
1023 break;
1024 }
1025
1026 stop_simulator = 0;
1027 }
1028
1029 int
1030 sim_fetch_register (sd, rn, memory, length)
1031 SIM_DESC sd;
1032 int rn;
1033 unsigned char *memory;
1034 int length;
1035 {
1036 if (rn > 34)
1037 WRITE_64 (memory, ACC (rn-35));
1038 else if (rn == 32)
1039 WRITE_16 (memory, IMAP0);
1040 else if (rn == 33)
1041 WRITE_16 (memory, IMAP1);
1042 else if (rn == 34)
1043 WRITE_16 (memory, DMAP);
1044 else if (rn >= 16)
1045 WRITE_16 (memory, CREG (rn - 16));
1046 else
1047 WRITE_16 (memory, GPR (rn));
1048 return -1;
1049 }
1050
1051 int
1052 sim_store_register (sd, rn, memory, length)
1053 SIM_DESC sd;
1054 int rn;
1055 unsigned char *memory;
1056 int length;
1057 {
1058 if (rn > 34)
1059 SET_ACC (rn-35, READ_64 (memory) & MASK40);
1060 else if (rn == 34)
1061 SET_DMAP( READ_16(memory) );
1062 else if (rn == 33)
1063 SET_IMAP1( READ_16(memory) );
1064 else if (rn == 32)
1065 SET_IMAP0( READ_16(memory) );
1066 else if (rn >= 16)
1067 SET_CREG (rn - 16, READ_16 (memory));
1068 else
1069 SET_GPR (rn, READ_16 (memory));
1070 SLOT_FLUSH ();
1071 return -1;
1072 }
1073
1074
1075 void
1076 sim_do_command (sd, cmd)
1077 SIM_DESC sd;
1078 char *cmd;
1079 {
1080 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
1081 }
1082
1083 SIM_RC
1084 sim_load (sd, prog, abfd, from_tty)
1085 SIM_DESC sd;
1086 char *prog;
1087 bfd *abfd;
1088 int from_tty;
1089 {
1090 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1091
1092 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1093 {
1094 bfd_close (prog_bfd);
1095 prog_bfd_was_opened_p = 0;
1096 }
1097 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
1098 sim_kind == SIM_OPEN_DEBUG,
1099 1/*LMA*/, sim_write);
1100 if (prog_bfd == NULL)
1101 return SIM_RC_FAIL;
1102 prog_bfd_was_opened_p = abfd == NULL;
1103 return SIM_RC_OK;
1104 }