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