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