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