Simplify logic behind the generic configuration option --enable-sim-alignment.
[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
MH
434
435int
04885cc3
DE
436sim_write (sd, addr, buffer, size)
437 SIM_DESC sd;
c422ecc7
MH
438 SIM_ADDR addr;
439 unsigned char *buffer;
440 int size;
441{
442 return xfer_mem( addr, buffer, size, 1);
443}
444
445int
04885cc3
DE
446sim_read (sd, addr, buffer, size)
447 SIM_DESC sd;
c422ecc7
MH
448 SIM_ADDR addr;
449 unsigned char *buffer;
450 int size;
451{
452 return xfer_mem( addr, buffer, size, 0);
453}
454
455
04885cc3 456SIM_DESC
247fccde 457sim_open (kind, callback, abfd, argv)
04885cc3 458 SIM_OPEN_KIND kind;
247fccde
AC
459 host_callback *callback;
460 struct _bfd *abfd;
04885cc3 461 char **argv;
2934d1c9
MH
462{
463 struct simops *s;
aeb1f26b 464 struct hash_entry *h;
1eaaf305 465 static int init_p = 0;
04885cc3
DE
466 char **p;
467
468 sim_kind = kind;
247fccde 469 d10v_callback = callback;
04885cc3 470 myname = argv[0];
1eaaf305 471
04885cc3 472 for (p = argv + 1; *p; ++p)
1eaaf305
MM
473 {
474#ifdef DEBUG
04885cc3 475 if (strcmp (*p, "-t") == 0)
1eaaf305
MM
476 d10v_debug = DEBUG;
477 else
478#endif
04885cc3 479 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
1eaaf305 480 }
c422ecc7 481
2934d1c9 482 /* put all the opcodes in the hash table */
1eaaf305 483 if (!init_p++)
2934d1c9 484 {
1eaaf305 485 for (s = Simops; s->func; s++)
2934d1c9 486 {
1eaaf305
MM
487 h = &hash_table[hash(s->opcode,s->format)];
488
489 /* go to the last entry in the chain */
490 while (h->next)
491 h = h->next;
492
493 if (h->ops)
494 {
04885cc3
DE
495 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
496 if (!h->next)
497 perror ("malloc failure");
498
1eaaf305
MM
499 h = h->next;
500 }
501 h->ops = s;
502 h->mask = s->mask;
503 h->opcode = s->opcode;
cee402dd 504 h->size = s->is_long;
2934d1c9 505 }
2934d1c9 506 }
04885cc3
DE
507
508 /* Fudge our descriptor. */
509 return (SIM_DESC) 1;
2934d1c9
MH
510}
511
512
513void
04885cc3
DE
514sim_close (sd, quitting)
515 SIM_DESC sd;
2934d1c9
MH
516 int quitting;
517{
04885cc3
DE
518 if (prog_bfd != NULL && prog_bfd_was_opened_p)
519 bfd_close (prog_bfd);
2934d1c9
MH
520}
521
522void
523sim_set_profile (n)
524 int n;
525{
7eebfc62 526 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
2934d1c9
MH
527}
528
529void
530sim_set_profile_size (n)
531 int n;
532{
7eebfc62 533 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
2934d1c9
MH
534}
535
c422ecc7
MH
536
537uint8 *
538dmem_addr( addr )
539 uint32 addr;
540{
541 int seg;
542
543 addr &= 0xffff;
544
545 if (addr > 0xbfff)
546 {
547 if ( (addr & 0xfff0) != 0xff00)
04885cc3
DE
548 {
549 (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n",
550 (long)addr, (long)decode_pc ());
551 State.exception = SIGBUS;
552 }
553
c422ecc7
MH
554 return State.dmem + addr;
555 }
556
557 if (addr > 0x7fff)
558 {
559 if (DMAP & 0x1000)
560 {
561 /* instruction memory */
562 return (DMAP & 0xf) * 0x4000 + State.imem;
563 }
564 /* unified memory */
565 /* this is ugly because we allocate unified memory in 128K segments and */
566 /* dmap addresses 16k segments */
cee402dd 567 seg = (DMAP & 0x3ff) >> 3;
c422ecc7
MH
568 if (State.umem[seg] == NULL)
569 {
b30cdd35
MM
570 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n",
571 seg, (long)decode_pc ());
04885cc3 572 State.exception = SIGBUS;
c422ecc7 573 }
cee402dd 574 return State.umem[seg] + (DMAP & 7) * 0x4000;
c422ecc7
MH
575 }
576
577 return State.dmem + addr;
578}
579
580
581static uint8 *
582pc_addr()
583{
584 uint32 pc = ((uint32)PC) << 2;
585 uint16 imap;
586
587 if (pc & 0x20000)
588 imap = IMAP1;
589 else
590 imap = IMAP0;
591
592 if (imap & 0x1000)
593 return State.imem + pc;
594
595 if (State.umem[imap & 0xff] == NULL)
596 {
b30cdd35
MM
597 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n",
598 imap & 0xff, (long)PC);
04885cc3 599 State.exception = SIGBUS;
c422ecc7
MH
600 return 0;
601 }
602
603 return State.umem[imap & 0xff] + pc;
604}
605
606
cee402dd
DE
607static int stop_simulator;
608
609static void
610sim_ctrl_c()
611{
612 stop_simulator = 1;
613}
614
615
8517f62b
AC
616int
617sim_stop (sd)
618 SIM_DESC sd;
619{
620 stop_simulator = 1;
621 return 1;
622}
623
624
cee402dd 625/* Run (or resume) the program. */
2934d1c9 626void
04885cc3
DE
627sim_resume (sd, step, siggnal)
628 SIM_DESC sd;
2934d1c9
MH
629 int step, siggnal;
630{
cee402dd 631 void (*prev) ();
2934d1c9 632 uint32 inst;
2934d1c9 633
7eebfc62 634/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
eca43eb1 635 State.exception = 0;
cee402dd
DE
636 prev = signal(SIGINT, sim_ctrl_c);
637 stop_simulator = step;
638
aeb1f26b
MM
639 do
640 {
c422ecc7 641 inst = get_longword( pc_addr() );
cee402dd 642 State.pc_changed = 0;
c422ecc7
MH
643 ins_type_counters[ (int)INS_CYCLES ]++;
644 switch (inst & 0xC0000000)
aeb1f26b 645 {
c422ecc7
MH
646 case 0xC0000000:
647 /* long instruction */
648 do_long (inst & 0x3FFFFFFF);
649 break;
650 case 0x80000000:
651 /* R -> L */
652 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
653 break;
654 case 0x40000000:
655 /* L -> R */
656 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
657 break;
658 case 0:
659 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
660 break;
aeb1f26b 661 }
c422ecc7
MH
662
663 if (State.RP && PC == RPT_E)
aeb1f26b 664 {
c422ecc7
MH
665 RPT_C -= 1;
666 if (RPT_C == 0)
667 State.RP = 0;
668 else
669 PC = RPT_S;
aeb1f26b 670 }
cee402dd 671 else if (!State.pc_changed)
c422ecc7 672 PC++;
aeb1f26b 673 }
cee402dd 674 while ( !State.exception && !stop_simulator);
c422ecc7 675
aeb1f26b
MM
676 if (step && !State.exception)
677 State.exception = SIGTRAP;
cee402dd
DE
678
679 signal(SIGINT, prev);
2934d1c9
MH
680}
681
682int
04885cc3
DE
683sim_trace (sd)
684 SIM_DESC sd;
2934d1c9 685{
7eebfc62
MM
686#ifdef DEBUG
687 d10v_debug = DEBUG;
688#endif
04885cc3 689 sim_resume (sd, 0, 0);
7eebfc62 690 return 1;
2934d1c9
MH
691}
692
693void
04885cc3
DE
694sim_info (sd, verbose)
695 SIM_DESC sd;
2934d1c9
MH
696 int verbose;
697{
aeb1f26b
MM
698 char buf1[40];
699 char buf2[40];
700 char buf3[40];
701 char buf4[40];
702 char buf5[40];
703 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
704 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
705 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
706 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
707 unsigned long left_total = left + left_parallel + left_cond + left_nops;
708
709 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
710 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
711 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
712 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
713 unsigned long right_total = right + right_parallel + right_cond + right_nops;
714
715 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
716 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
c422ecc7
MH
717 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
718 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
719 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
aeb1f26b
MM
720 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
721 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
c422ecc7 722 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
aeb1f26b
MM
723 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
724 unsigned long total = (unknown + left_total + right_total + ins_long);
725
726 int size = strlen (add_commas (buf1, sizeof (buf1), total));
727 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
728 (left_parallel > right_parallel) ? left_parallel : right_parallel));
729 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
730 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
731 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
732
733 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 734 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
aeb1f26b
MM
735 size, add_commas (buf1, sizeof (buf1), left_total),
736 normal_size, add_commas (buf2, sizeof (buf2), left),
737 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
738 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
739 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
740
741 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 742 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
aeb1f26b
MM
743 size, add_commas (buf1, sizeof (buf1), right_total),
744 normal_size, add_commas (buf2, sizeof (buf2), right),
745 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
746 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
747 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
748
c422ecc7
MH
749 if (ins_long)
750 (*d10v_callback->printf_filtered) (d10v_callback,
751 "executed %*s long instruction(s)\n",
752 size, add_commas (buf1, sizeof (buf1), ins_long));
753
754 if (parallel)
755 (*d10v_callback->printf_filtered) (d10v_callback,
756 "executed %*s parallel instruction(s)\n",
757 size, add_commas (buf1, sizeof (buf1), parallel));
758
759 if (leftright)
760 (*d10v_callback->printf_filtered) (d10v_callback,
761 "executed %*s instruction(s) encoded L->R\n",
762 size, add_commas (buf1, sizeof (buf1), leftright));
763
764 if (rightleft)
765 (*d10v_callback->printf_filtered) (d10v_callback,
766 "executed %*s instruction(s) encoded R->L\n",
767 size, add_commas (buf1, sizeof (buf1), rightleft));
7eebfc62 768
aeb1f26b
MM
769 if (unknown)
770 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 771 "executed %*s unknown instruction(s)\n",
aeb1f26b 772 size, add_commas (buf1, sizeof (buf1), unknown));
7eebfc62 773
c422ecc7
MH
774 if (cond_true)
775 (*d10v_callback->printf_filtered) (d10v_callback,
776 "executed %*s instruction(s) due to EXExxx condition being true\n",
777 size, add_commas (buf1, sizeof (buf1), cond_true));
7eebfc62 778
c422ecc7
MH
779 if (cond_false)
780 (*d10v_callback->printf_filtered) (d10v_callback,
781 "skipped %*s instruction(s) due to EXExxx condition being false\n",
782 size, add_commas (buf1, sizeof (buf1), cond_false));
783
784 if (cond_jump)
785 (*d10v_callback->printf_filtered) (d10v_callback,
786 "skipped %*s instruction(s) due to conditional branch succeeding\n",
787 size, add_commas (buf1, sizeof (buf1), cond_jump));
7eebfc62
MM
788
789 (*d10v_callback->printf_filtered) (d10v_callback,
c422ecc7 790 "executed %*s cycle(s)\n",
aeb1f26b 791 size, add_commas (buf1, sizeof (buf1), cycles));
7eebfc62
MM
792
793 (*d10v_callback->printf_filtered) (d10v_callback,
aeb1f26b
MM
794 "executed %*s total instructions\n",
795 size, add_commas (buf1, sizeof (buf1), total));
2934d1c9
MH
796}
797
04885cc3 798SIM_RC
fafce69a 799sim_create_inferior (sd, abfd, argv, env)
04885cc3 800 SIM_DESC sd;
fafce69a 801 struct _bfd *abfd;
2934d1c9
MH
802 char **argv;
803 char **env;
804{
fafce69a 805 bfd_vma start_address;
c422ecc7 806
57bc1a72 807 /* reset all state information */
c422ecc7
MH
808 memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]);
809
57bc1a72 810 /* set PC */
fafce69a
AC
811 if (abfd != NULL)
812 start_address = bfd_get_start_address (prog_bfd);
813 else
814 start_address = 0xffc0 << 2;
815#ifdef DEBUG
816 if (d10v_debug)
817 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
818#endif
2934d1c9 819 PC = start_address >> 2;
c422ecc7
MH
820
821 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
822 /* resets imap0 and imap1 to 0x1000. */
823
824 SET_IMAP0(0x1000);
825 SET_IMAP1(0x1000);
826 SET_DMAP(0);
04885cc3
DE
827
828 return SIM_RC_OK;
2934d1c9
MH
829}
830
831
2934d1c9 832void
247fccde 833sim_set_callbacks (p)
2934d1c9
MH
834 host_callback *p;
835{
87178dbd 836 d10v_callback = p;
2934d1c9
MH
837}
838
839void
04885cc3
DE
840sim_stop_reason (sd, reason, sigrc)
841 SIM_DESC sd;
2934d1c9
MH
842 enum sim_stop *reason;
843 int *sigrc;
844{
7eebfc62 845/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
d70b4d42 846
a49a15ad 847 switch (State.exception)
d70b4d42 848 {
a49a15ad 849 case SIG_D10V_STOP: /* stop instruction */
d70b4d42 850 *reason = sim_exited;
a49a15ad
MM
851 *sigrc = 0;
852 break;
853
854 case SIG_D10V_EXIT: /* exit trap */
855 *reason = sim_exited;
856 *sigrc = State.regs[2];
857 break;
858
859 default: /* some signal */
d70b4d42
MH
860 *reason = sim_stopped;
861 *sigrc = State.exception;
a49a15ad 862 break;
d70b4d42
MH
863 }
864}
865
866void
04885cc3
DE
867sim_fetch_register (sd, rn, memory)
868 SIM_DESC sd;
d70b4d42
MH
869 int rn;
870 unsigned char *memory;
871{
c422ecc7
MH
872 if (!State.imem)
873 init_system();
874
875 if (rn > 34)
5c839c67 876 WRITE_64 (memory, State.a[rn-35]);
c422ecc7
MH
877 else if (rn == 32)
878 WRITE_16 (memory, IMAP0);
879 else if (rn == 33)
880 WRITE_16 (memory, IMAP1);
881 else if (rn == 34)
882 WRITE_16 (memory, DMAP);
d70b4d42 883 else
c422ecc7 884 WRITE_16 (memory, State.regs[rn]);
d70b4d42
MH
885}
886
887void
04885cc3
DE
888sim_store_register (sd, rn, memory)
889 SIM_DESC sd;
d70b4d42
MH
890 int rn;
891 unsigned char *memory;
892{
c422ecc7
MH
893 if (!State.imem)
894 init_system();
895
896 if (rn > 34)
5c839c67 897 State.a[rn-35] = READ_64 (memory) & MASK40;
c422ecc7
MH
898 else if (rn == 34)
899 SET_DMAP( READ_16(memory) );
900 else if (rn == 33)
901 SET_IMAP1( READ_16(memory) );
902 else if (rn == 32)
903 SET_IMAP0( READ_16(memory) );
d70b4d42 904 else
c422ecc7 905 State.regs[rn]= READ_16 (memory);
2934d1c9 906}
d70b4d42 907
d70b4d42
MH
908
909void
04885cc3
DE
910sim_do_command (sd, cmd)
911 SIM_DESC sd;
d70b4d42
MH
912 char *cmd;
913{
7eebfc62 914 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
d70b4d42
MH
915}
916
04885cc3
DE
917SIM_RC
918sim_load (sd, prog, abfd, from_tty)
919 SIM_DESC sd;
d70b4d42 920 char *prog;
04885cc3 921 bfd *abfd;
d70b4d42
MH
922 int from_tty;
923{
04885cc3
DE
924 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
925
926 if (prog_bfd != NULL && prog_bfd_was_opened_p)
927 bfd_close (prog_bfd);
928 prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
929 sim_kind == SIM_OPEN_DEBUG);
930 if (prog_bfd == NULL)
931 return SIM_RC_FAIL;
04885cc3
DE
932 prog_bfd_was_opened_p = abfd == NULL;
933 return SIM_RC_OK;
d70b4d42 934}
This page took 0.103664 seconds and 4 git commands to generate.