sim: mcore: drop sbrk support
[deliverable/binutils-gdb.git] / sim / mcore / interp.c
CommitLineData
0fda6bd2 1/* Simulator for Motorola's MCore processor
32d0add0 2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
2d514e6f
SS
3 Contributed by Cygnus Solutions.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
2d514e6f
SS
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
2d514e6f 19
3550b236 20#include "config.h"
2d514e6f 21#include <signal.h>
dc049bf4
MF
22#include <stdlib.h>
23#include <string.h>
2d514e6f
SS
24#include <sys/times.h>
25#include <sys/param.h>
4185814e 26#include <unistd.h>
2d514e6f 27#include "bfd.h"
3c25f8c7 28#include "gdb/callback.h"
2d514e6f 29#include "libiberty.h"
3c25f8c7 30#include "gdb/remote-sim.h"
2d514e6f
SS
31
32#ifndef NUM_ELEM
33#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
34#endif
35
36
37typedef long int word;
38typedef unsigned long int uword;
39
63a027a3 40static int target_big_endian = 0;
2d514e6f
SS
41host_callback * callback;
42
43
feb703b3
MF
44static unsigned long
45mcore_extract_unsigned_integer (unsigned char *addr, int len)
2d514e6f
SS
46{
47 unsigned long retval;
48 unsigned char * p;
49 unsigned char * startaddr = (unsigned char *)addr;
50 unsigned char * endaddr = startaddr + len;
ba14f941 51
2d514e6f 52 if (len > (int) sizeof (unsigned long))
feb703b3 53 printf ("That operation is not available on integers of more than %zu bytes.",
2d514e6f 54 sizeof (unsigned long));
ba14f941 55
2d514e6f
SS
56 /* Start at the most significant end of the integer, and work towards
57 the least significant. */
58 retval = 0;
cd0fc7c3 59
63a027a3
NC
60 if (! target_big_endian)
61 {
62 for (p = endaddr; p > startaddr;)
63 retval = (retval << 8) | * -- p;
64 }
65 else
cd0fc7c3
SS
66 {
67 for (p = startaddr; p < endaddr;)
68 retval = (retval << 8) | * p ++;
69 }
ba14f941 70
2d514e6f
SS
71 return retval;
72}
73
feb703b3
MF
74static void
75mcore_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
2d514e6f
SS
76{
77 unsigned char * p;
78 unsigned char * startaddr = (unsigned char *)addr;
79 unsigned char * endaddr = startaddr + len;
cd0fc7c3 80
63a027a3
NC
81 if (! target_big_endian)
82 {
83 for (p = startaddr; p < endaddr;)
84 {
85 * p ++ = val & 0xff;
86 val >>= 8;
87 }
88 }
89 else
2d514e6f 90 {
cd0fc7c3
SS
91 for (p = endaddr; p > startaddr;)
92 {
93 * -- p = val & 0xff;
94 val >>= 8;
95 }
2d514e6f
SS
96 }
97}
98
99/* The machine state.
ba14f941 100 This state is maintained in host byte order. The
2d514e6f 101 fetch/store register functions must translate between host
ba14f941 102 byte order and the target processor byte order.
2d514e6f
SS
103 Keeping this data in target byte order simplifies the register
104 read/write functions. Keeping this data in native order improves
105 the performance of the simulator. Simulation speed is deemed more
63a027a3 106 important. */
2d514e6f
SS
107
108/* The ordering of the mcore_regset structure is matched in the
109 gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro. */
110struct mcore_regset
111{
112 word gregs [16]; /* primary registers */
113 word alt_gregs [16]; /* alt register file */
114 word cregs [32]; /* control registers */
115 word pc; /* the pc */
116 int ticks;
117 int stalls;
118 int cycles;
119 int insts;
120 int exception;
121 unsigned long msize;
122 unsigned char * memory;
123 word * active_gregs;
124};
125
126union
127{
128 struct mcore_regset asregs;
129 word asints [1]; /* but accessed larger... */
130} cpu;
131
9e086581
JM
132#define LAST_VALID_CREG 32 /* only 0..12 implemented */
133#define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
2d514e6f
SS
134
135int memcycles = 1;
136
137static SIM_OPEN_KIND sim_kind;
138static char * myname;
139
140static int issue_messages = 0;
141
142#define gr asregs.active_gregs
143#define cr asregs.cregs
144#define sr asregs.cregs[0]
145#define vbr asregs.cregs[1]
146#define esr asregs.cregs[2]
147#define fsr asregs.cregs[3]
148#define epc asregs.cregs[4]
149#define fpc asregs.cregs[5]
150#define ss0 asregs.cregs[6]
151#define ss1 asregs.cregs[7]
152#define ss2 asregs.cregs[8]
153#define ss3 asregs.cregs[9]
154#define ss4 asregs.cregs[10]
155#define gcr asregs.cregs[11]
156#define gsr asregs.cregs[12]
157#define mem asregs.memory
158
159/* maniuplate the carry bit */
cd0fc7c3 160#define C_ON() (cpu.sr & 1)
2d514e6f 161#define C_VALUE() (cpu.sr & 1)
cd0fc7c3
SS
162#define C_OFF() ((cpu.sr & 1) == 0)
163#define SET_C() {cpu.sr |= 1;}
164#define CLR_C() {cpu.sr &= 0xfffffffe;}
165#define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
2d514e6f
SS
166
167#define SR_AF() ((cpu.sr >> 1) & 1)
168
169#define TRAPCODE 1 /* r1 holds which function we want */
170#define PARM1 2 /* first parameter */
171#define PARM2 3
172#define PARM3 4
173#define PARM4 5
174#define RET1 2 /* register for return values. */
175
feb703b3
MF
176static void
177wbat (word x, word v)
2d514e6f
SS
178{
179 if (((uword)x) >= cpu.asregs.msize)
180 {
181 if (issue_messages)
182 fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
ba14f941 183
2d514e6f
SS
184 cpu.asregs.exception = SIGSEGV;
185 }
186 else
187 {
188 unsigned char *p = cpu.mem + x;
189 p[0] = v;
190 }
191}
192
feb703b3
MF
193static void
194wlat (word x, word v)
2d514e6f
SS
195{
196 if (((uword)x) >= cpu.asregs.msize)
197 {
198 if (issue_messages)
199 fprintf (stderr, "word write to 0x%x outside memory range\n", x);
ba14f941 200
2d514e6f
SS
201 cpu.asregs.exception = SIGSEGV;
202 }
203 else
204 {
205 if ((x & 3) != 0)
206 {
207 if (issue_messages)
208 fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
ba14f941 209
2d514e6f
SS
210 cpu.asregs.exception = SIGBUS;
211 }
63a027a3
NC
212 else if (! target_big_endian)
213 {
214 unsigned char * p = cpu.mem + x;
215 p[3] = v >> 24;
216 p[2] = v >> 16;
217 p[1] = v >> 8;
218 p[0] = v;
219 }
2d514e6f
SS
220 else
221 {
222 unsigned char * p = cpu.mem + x;
223 p[0] = v >> 24;
224 p[1] = v >> 16;
225 p[2] = v >> 8;
226 p[3] = v;
227 }
228 }
229}
230
feb703b3
MF
231static void
232what (word x, word v)
2d514e6f
SS
233{
234 if (((uword)x) >= cpu.asregs.msize)
235 {
236 if (issue_messages)
237 fprintf (stderr, "short write to 0x%x outside memory range\n", x);
ba14f941 238
2d514e6f
SS
239 cpu.asregs.exception = SIGSEGV;
240 }
241 else
242 {
243 if ((x & 1) != 0)
244 {
245 if (issue_messages)
cd0fc7c3
SS
246 fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
247 x);
ba14f941 248
2d514e6f
SS
249 cpu.asregs.exception = SIGBUS;
250 }
63a027a3
NC
251 else if (! target_big_endian)
252 {
253 unsigned char * p = cpu.mem + x;
254 p[1] = v >> 8;
255 p[0] = v;
256 }
2d514e6f
SS
257 else
258 {
259 unsigned char * p = cpu.mem + x;
260 p[0] = v >> 8;
261 p[1] = v;
262 }
263 }
264}
265
4cd93614 266/* Read functions. */
feb703b3
MF
267static int
268rbat (word x)
2d514e6f
SS
269{
270 if (((uword)x) >= cpu.asregs.msize)
271 {
272 if (issue_messages)
273 fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
ba14f941 274
2d514e6f
SS
275 cpu.asregs.exception = SIGSEGV;
276 return 0;
277 }
278 else
279 {
280 unsigned char * p = cpu.mem + x;
281 return p[0];
282 }
283}
284
feb703b3
MF
285static int
286rlat (word x)
2d514e6f
SS
287{
288 if (((uword) x) >= cpu.asregs.msize)
289 {
290 if (issue_messages)
291 fprintf (stderr, "word read from 0x%x outside memory range\n", x);
ba14f941 292
2d514e6f
SS
293 cpu.asregs.exception = SIGSEGV;
294 return 0;
295 }
296 else
297 {
298 if ((x & 3) != 0)
299 {
300 if (issue_messages)
301 fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
ba14f941 302
2d514e6f
SS
303 cpu.asregs.exception = SIGBUS;
304 return 0;
305 }
63a027a3
NC
306 else if (! target_big_endian)
307 {
308 unsigned char * p = cpu.mem + x;
309 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
310 }
2d514e6f
SS
311 else
312 {
313 unsigned char * p = cpu.mem + x;
314 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
315 }
316 }
317}
318
feb703b3
MF
319static int
320rhat (word x)
2d514e6f
SS
321{
322 if (((uword)x) >= cpu.asregs.msize)
323 {
324 if (issue_messages)
325 fprintf (stderr, "short read from 0x%x outside memory range\n", x);
ba14f941 326
2d514e6f
SS
327 cpu.asregs.exception = SIGSEGV;
328 return 0;
329 }
330 else
331 {
332 if ((x & 1) != 0)
333 {
334 if (issue_messages)
335 fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
ba14f941 336
2d514e6f
SS
337 cpu.asregs.exception = SIGBUS;
338 return 0;
339 }
63a027a3
NC
340 else if (! target_big_endian)
341 {
342 unsigned char * p = cpu.mem + x;
343 return (p[1] << 8) | p[0];
344 }
2d514e6f
SS
345 else
346 {
347 unsigned char * p = cpu.mem + x;
348 return (p[0] << 8) | p[1];
349 }
350 }
351}
352
353
4cd93614 354/* Default to a 8 Mbyte (== 2^23) memory space. */
2d514e6f
SS
355static int sim_memory_size = 23;
356
357#define MEM_SIZE_FLOOR 64
358void
feb703b3 359sim_size (int power)
2d514e6f
SS
360{
361 sim_memory_size = power;
362 cpu.asregs.msize = 1 << sim_memory_size;
363
364 if (cpu.mem)
365 free (cpu.mem);
366
4cd93614
FCE
367 /* Watch out for the '0 count' problem. There's probably a better
368 way.. e.g., why do we use 64 here? */
369 if (cpu.asregs.msize < 64) /* Ensure a boundary. */
2d514e6f
SS
370 cpu.mem = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
371 else
372 cpu.mem = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
373
374 if (!cpu.mem)
375 {
376 if (issue_messages)
377 fprintf (stderr,
feb703b3 378 "Not enough VM for simulation of %lu bytes of RAM\n",
cd0fc7c3 379 cpu.asregs.msize);
2d514e6f
SS
380
381 cpu.asregs.msize = 1;
382 cpu.mem = (unsigned char *) calloc (1, 1);
383 }
384}
385
386static void
feb703b3 387init_pointers (void)
2d514e6f
SS
388{
389 if (cpu.asregs.msize != (1 << sim_memory_size))
390 sim_size (sim_memory_size);
391}
392
393static void
feb703b3 394set_initial_gprs (void)
2d514e6f
SS
395{
396 int i;
397 long space;
398 unsigned long memsize;
ba14f941 399
2d514e6f
SS
400 init_pointers ();
401
402 /* Set up machine just out of reset. */
403 cpu.asregs.pc = 0;
404 cpu.sr = 0;
ba14f941 405
2d514e6f
SS
406 memsize = cpu.asregs.msize / (1024 * 1024);
407
b83266a0 408 if (issue_messages > 1)
feb703b3 409 fprintf (stderr, "Simulated memory of %lu Mbytes (0x0 .. 0x%08lx)\n",
2d514e6f
SS
410 memsize, cpu.asregs.msize - 1);
411
412 /* Clean out the GPRs and alternate GPRs. */
413 for (i = 0; i < 16; i++)
414 {
415 cpu.asregs.gregs[i] = 0;
416 cpu.asregs.alt_gregs[i] = 0;
417 }
ba14f941 418
2d514e6f
SS
419 /* Make our register set point to the right place. */
420 if (SR_AF())
421 cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
422 else
423 cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
ba14f941 424
2d514e6f
SS
425 /* ABI specifies initial values for these registers. */
426 cpu.gr[0] = cpu.asregs.msize - 4;
ba14f941 427
2d514e6f
SS
428 /* dac fix, the stack address must be 8-byte aligned! */
429 cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
430 cpu.gr[PARM1] = 0;
431 cpu.gr[PARM2] = 0;
432 cpu.gr[PARM3] = 0;
433 cpu.gr[PARM4] = cpu.gr[0];
434}
435
2d514e6f
SS
436/* Functions so that trapped open/close don't interfere with the
437 parent's functions. We say that we can't close the descriptors
438 that we didn't open. exit() and cleanup() get in trouble here,
439 to some extent. That's the price of emulation. */
440
441unsigned char opened[100];
442
443static void
feb703b3 444log_open (int fd)
2d514e6f
SS
445{
446 if (fd < 0 || fd > NUM_ELEM (opened))
447 return;
ba14f941 448
2d514e6f
SS
449 opened[fd] = 1;
450}
451
452static void
feb703b3 453log_close (int fd)
2d514e6f
SS
454{
455 if (fd < 0 || fd > NUM_ELEM (opened))
456 return;
ba14f941 457
2d514e6f
SS
458 opened[fd] = 0;
459}
460
461static int
feb703b3 462is_opened (int fd)
2d514e6f
SS
463{
464 if (fd < 0 || fd > NUM_ELEM (opened))
465 return 0;
466
467 return opened[fd];
468}
469
470static void
feb703b3 471handle_trap1 (void)
2d514e6f
SS
472{
473 unsigned long a[3];
474
cd0fc7c3 475 switch ((unsigned long) (cpu.gr [TRAPCODE]))
2d514e6f
SS
476 {
477 case 3:
478 a[0] = (unsigned long) (cpu.gr[PARM1]);
479 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
480 a[2] = (unsigned long) (cpu.gr[PARM3]);
481 cpu.gr[RET1] = callback->read (callback, a[0], (char *) a[1], a[2]);
482 break;
ba14f941 483
2d514e6f
SS
484 case 4:
485 a[0] = (unsigned long) (cpu.gr[PARM1]);
486 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
487 a[2] = (unsigned long) (cpu.gr[PARM3]);
488 cpu.gr[RET1] = (int)callback->write (callback, a[0], (char *) a[1], a[2]);
489 break;
ba14f941 490
2d514e6f
SS
491 case 5:
492 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
493 a[1] = (unsigned long) (cpu.gr[PARM2]);
494 /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
495 cpu.gr[RET1] = callback->open (callback, (char *) a[0], a[1]);
496 log_open (cpu.gr[RET1]);
497 break;
ba14f941 498
2d514e6f 499 case 6:
3dfcd3c6 500 a[0] = (unsigned long) (cpu.gr[PARM1]);
2d514e6f
SS
501 /* Watch out for debugger's files. */
502 if (is_opened (a[0]))
503 {
504 log_close (a[0]);
505 cpu.gr[RET1] = callback->close (callback, a[0]);
506 }
507 else
508 {
509 /* Don't let him close it. */
510 cpu.gr[RET1] = (-1);
511 }
512 break;
ba14f941 513
2d514e6f
SS
514 case 9:
515 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
516 a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
517 cpu.gr[RET1] = link ((char *) a[0], (char *) a[1]);
518 break;
ba14f941 519
2d514e6f
SS
520 case 10:
521 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
522 cpu.gr[RET1] = callback->unlink (callback, (char *) a[0]);
523 break;
ba14f941 524
2d514e6f
SS
525 case 13:
526 /* handle time(0) vs time(&var) */
527 a[0] = (unsigned long) (cpu.gr[PARM1]);
528 if (a[0])
529 a[0] += (unsigned long) cpu.mem;
530 cpu.gr[RET1] = callback->time (callback, (time_t *) a[0]);
531 break;
ba14f941 532
2d514e6f
SS
533 case 19:
534 a[0] = (unsigned long) (cpu.gr[PARM1]);
535 a[1] = (unsigned long) (cpu.gr[PARM2]);
536 a[2] = (unsigned long) (cpu.gr[PARM3]);
537 cpu.gr[RET1] = callback->lseek (callback, a[0], a[1], a[2]);
538 break;
ba14f941 539
2d514e6f
SS
540 case 33:
541 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
542 a[1] = (unsigned long) (cpu.gr[PARM2]);
543 cpu.gr[RET1] = access ((char *) a[0], a[1]);
544 break;
ba14f941 545
2d514e6f
SS
546 case 43:
547 a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
548#if 0
549 cpu.gr[RET1] = times ((char *)a[0]);
550#else
551 {
552 /* Give him simulated cycles for utime
553 and an instruction count for stime. */
554 struct tms
555 {
556 time_t tms_utime;
557 time_t tms_stime;
558 time_t tms_cutime;
559 time_t tms_cstime;
560 } t;
561
562 t.tms_utime = cpu.asregs.cycles;
563 t.tms_stime = cpu.asregs.insts;
564 t.tms_cutime = t.tms_utime;
565 t.tms_cstime = t.tms_stime;
ba14f941 566
2d514e6f 567 memcpy ((struct tms *)(a[0]), &t, sizeof (t));
ba14f941 568
2d514e6f
SS
569 cpu.gr[RET1] = cpu.asregs.cycles;
570 }
571#endif
572 break;
ba14f941 573
2d514e6f 574 case 69:
aac18a69
MF
575 /* Historically this was sbrk(), but no one used it, and the
576 implementation didn't actually work, so it's a stub now. */
2d514e6f 577 a[0] = (unsigned long) (cpu.gr[PARM1]);
aac18a69 578 cpu.gr[RET1] = -1;
2d514e6f 579 break;
ba14f941 580
2d514e6f
SS
581 default:
582 if (issue_messages)
cd0fc7c3
SS
583 fprintf (stderr, "WARNING: sys call %d unimplemented\n",
584 cpu.gr[TRAPCODE]);
2d514e6f
SS
585 break;
586 }
587}
588
589static void
feb703b3 590process_stub (int what)
2d514e6f
SS
591{
592 /* These values should match those in libgloss/mcore/syscalls.s. */
593 switch (what)
594 {
595 case 3: /* _read */
cd0fc7c3 596 case 4: /* _write */
2d514e6f
SS
597 case 5: /* _open */
598 case 6: /* _close */
599 case 10: /* _unlink */
600 case 19: /* _lseek */
601 case 43: /* _times */
602 cpu.gr [TRAPCODE] = what;
603 handle_trap1 ();
604 break;
ba14f941 605
2d514e6f
SS
606 default:
607 if (issue_messages)
608 fprintf (stderr, "Unhandled stub opcode: %d\n", what);
609 break;
610 }
611}
612
613static void
feb703b3 614util (unsigned what)
2d514e6f
SS
615{
616 switch (what)
617 {
618 case 0: /* exit */
619 cpu.asregs.exception = SIGQUIT;
620 break;
621
622 case 1: /* printf */
623 {
624 unsigned long a[6];
625 unsigned char *s;
626 int i;
627
628 a[0] = (unsigned long)(cpu.mem + cpu.gr[PARM1]);
629
630 for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
631 {
632 if (*s == '%')
633 {
634 if (*++s == 's')
635 a[i] = (unsigned long)(cpu.mem + cpu.gr[PARM1+i]);
636 else
637 a[i] = cpu.gr[i+PARM1];
638 i++;
639 }
640 }
ba14f941 641
2d514e6f
SS
642 cpu.gr[RET1] = printf ((char *)a[0], a[1], a[2], a[3], a[4], a[5]);
643 }
644 break;
ba14f941 645
2d514e6f
SS
646 case 2: /* scanf */
647 if (issue_messages)
648 fprintf (stderr, "WARNING: scanf unimplemented\n");
649 break;
ba14f941 650
2d514e6f
SS
651 case 3: /* utime */
652 cpu.gr[RET1] = cpu.asregs.insts;
653 break;
654
655 case 0xFF:
cd0fc7c3 656 process_stub (cpu.gr[1]);
2d514e6f 657 break;
ba14f941 658
2d514e6f
SS
659 default:
660 if (issue_messages)
661 fprintf (stderr, "Unhandled util code: %x\n", what);
662 break;
663 }
ba14f941 664}
2d514e6f
SS
665
666/* For figuring out whether we carried; addc/subc use this. */
667static int
feb703b3 668iu_carry (unsigned long a, unsigned long b, int cin)
2d514e6f
SS
669{
670 unsigned long x;
ba14f941 671
2d514e6f
SS
672 x = (a & 0xffff) + (b & 0xffff) + cin;
673 x = (x >> 16) + (a >> 16) + (b >> 16);
674 x >>= 16;
675
676 return (x != 0);
677}
678
679#define WATCHFUNCTIONS 1
680#ifdef WATCHFUNCTIONS
681
682#define MAXWL 80
683word WL[MAXWL];
684char * WLstr[MAXWL];
685
686int ENDWL=0;
687int WLincyc;
688int WLcyc[MAXWL];
689int WLcnts[MAXWL];
690int WLmax[MAXWL];
691int WLmin[MAXWL];
692word WLendpc;
693int WLbcyc;
694int WLW;
695#endif
696
697#define RD (inst & 0xF)
698#define RS ((inst >> 4) & 0xF)
699#define RX ((inst >> 8) & 0xF)
700#define IMM5 ((inst >> 4) & 0x1F)
701#define IMM4 ((inst) & 0xF)
702
703static int tracing = 0;
704
705void
feb703b3 706sim_resume (SIM_DESC sd, int step, int siggnal)
2d514e6f
SS
707{
708 int needfetch;
709 word ibuf;
710 word pc;
711 unsigned short inst;
2d514e6f
SS
712 int memops;
713 int bonus_cycles;
714 int insts;
715 int w;
716 int cycs;
717 word WLhash;
718
2d514e6f
SS
719 cpu.asregs.exception = step ? SIGTRAP: 0;
720 pc = cpu.asregs.pc;
721
cd0fc7c3 722 /* Fetch the initial instructions that we'll decode. */
2d514e6f
SS
723 ibuf = rlat (pc & 0xFFFFFFFC);
724 needfetch = 0;
725
726 memops = 0;
727 bonus_cycles = 0;
728 insts = 0;
ba14f941 729
2d514e6f
SS
730 /* make our register set point to the right place */
731 if (SR_AF ())
732 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
733 else
734 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
ba14f941 735
2d514e6f
SS
736 /* make a hash to speed exec loop, hope it's nonzero */
737 WLhash = 0xFFFFFFFF;
738
739 for (w = 1; w <= ENDWL; w++)
740 WLhash = WLhash & WL[w];
741
742 do
743 {
cd0fc7c3 744 word oldpc;
ba14f941 745
2d514e6f 746 insts ++;
ba14f941 747
2d514e6f
SS
748 if (pc & 02)
749 {
63a027a3
NC
750 if (! target_big_endian)
751 inst = ibuf >> 16;
752 else
cd0fc7c3 753 inst = ibuf & 0xFFFF;
2d514e6f
SS
754 needfetch = 1;
755 }
756 else
757 {
63a027a3
NC
758 if (! target_big_endian)
759 inst = ibuf & 0xFFFF;
760 else
cd0fc7c3 761 inst = ibuf >> 16;
2d514e6f
SS
762 }
763
764#ifdef WATCHFUNCTIONS
765 /* now scan list of watch addresses, if match, count it and
766 note return address and count cycles until pc=return address */
ba14f941 767
2d514e6f
SS
768 if ((WLincyc == 1) && (pc == WLendpc))
769 {
770 cycs = (cpu.asregs.cycles + (insts + bonus_cycles +
771 (memops * memcycles)) - WLbcyc);
ba14f941 772
2d514e6f
SS
773 if (WLcnts[WLW] == 1)
774 {
775 WLmax[WLW] = cycs;
776 WLmin[WLW] = cycs;
777 WLcyc[WLW] = 0;
778 }
ba14f941 779
2d514e6f
SS
780 if (cycs > WLmax[WLW])
781 {
782 WLmax[WLW] = cycs;
783 }
ba14f941 784
2d514e6f
SS
785 if (cycs < WLmin[WLW])
786 {
787 WLmin[WLW] = cycs;
788 }
ba14f941 789
2d514e6f
SS
790 WLcyc[WLW] += cycs;
791 WLincyc = 0;
792 WLendpc = 0;
ba14f941 793 }
2d514e6f 794
cd0fc7c3 795 /* Optimize with a hash to speed loop. */
2d514e6f
SS
796 if (WLincyc == 0)
797 {
798 if ((WLhash == 0) || ((WLhash & pc) != 0))
799 {
800 for (w=1; w <= ENDWL; w++)
801 {
802 if (pc == WL[w])
803 {
804 WLcnts[w]++;
ba14f941 805 WLbcyc = cpu.asregs.cycles + insts
2d514e6f
SS
806 + bonus_cycles + (memops * memcycles);
807 WLendpc = cpu.gr[15];
808 WLincyc = 1;
809 WLW = w;
810 break;
811 }
812 }
813 }
814 }
815#endif
816
817 if (tracing)
818 fprintf (stderr, "%.4x: inst = %.4x ", pc, inst);
cd0fc7c3
SS
819
820 oldpc = pc;
ba14f941 821
2d514e6f 822 pc += 2;
ba14f941 823
2d514e6f
SS
824 switch (inst >> 8)
825 {
826 case 0x00:
827 switch RS
828 {
829 case 0x0:
830 switch RD
831 {
832 case 0x0: /* bkpt */
833 cpu.asregs.exception = SIGTRAP;
9e086581 834 pc -= 2;
2d514e6f 835 break;
ba14f941 836
2d514e6f
SS
837 case 0x1: /* sync */
838 break;
ba14f941 839
2d514e6f
SS
840 case 0x2: /* rte */
841 pc = cpu.epc;
842 cpu.sr = cpu.esr;
843 needfetch = 1;
ba14f941 844
cd0fc7c3 845 if (SR_AF ())
2d514e6f
SS
846 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
847 else
848 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
849 break;
850
851 case 0x3: /* rfi */
852 pc = cpu.fpc;
853 cpu.sr = cpu.fsr;
854 needfetch = 1;
855
856 if (SR_AF ())
857 cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
858 else
859 cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
860 break;
ba14f941 861
2d514e6f
SS
862 case 0x4: /* stop */
863 if (issue_messages)
864 fprintf (stderr, "WARNING: stop unimplemented\n");
865 break;
ba14f941 866
2d514e6f
SS
867 case 0x5: /* wait */
868 if (issue_messages)
869 fprintf (stderr, "WARNING: wait unimplemented\n");
870 break;
ba14f941 871
2d514e6f
SS
872 case 0x6: /* doze */
873 if (issue_messages)
cd0fc7c3 874 fprintf (stderr, "WARNING: doze unimplemented\n");
2d514e6f 875 break;
ba14f941 876
2d514e6f
SS
877 case 0x7:
878 cpu.asregs.exception = SIGILL; /* illegal */
879 break;
ba14f941 880
2d514e6f
SS
881 case 0x8: /* trap 0 */
882 case 0xA: /* trap 2 */
883 case 0xB: /* trap 3 */
884 cpu.asregs.exception = SIGTRAP;
885 break;
ba14f941 886
2d514e6f
SS
887 case 0xC: /* trap 4 */
888 case 0xD: /* trap 5 */
889 case 0xE: /* trap 6 */
890 cpu.asregs.exception = SIGILL; /* illegal */
891 break;
ba14f941 892
2d514e6f
SS
893 case 0xF: /* trap 7 */
894 cpu.asregs.exception = SIGTRAP; /* integer div-by-0 */
895 break;
ba14f941 896
2d514e6f
SS
897 case 0x9: /* trap 1 */
898 handle_trap1 ();
899 break;
900 }
901 break;
ba14f941 902
2d514e6f
SS
903 case 0x1:
904 cpu.asregs.exception = SIGILL; /* illegal */
905 break;
ba14f941 906
2d514e6f
SS
907 case 0x2: /* mvc */
908 cpu.gr[RD] = C_VALUE();
909 break;
910 case 0x3: /* mvcv */
911 cpu.gr[RD] = C_OFF();
912 break;
913 case 0x4: /* ldq */
914 {
feb703b3 915 word addr = cpu.gr[RD];
2d514e6f 916 int regno = 4; /* always r4-r7 */
ba14f941 917
2d514e6f
SS
918 bonus_cycles++;
919 memops += 4;
920 do
921 {
922 cpu.gr[regno] = rlat(addr);
923 addr += 4;
924 regno++;
925 }
926 while ((regno&0x3) != 0);
927 }
928 break;
929 case 0x5: /* stq */
930 {
feb703b3 931 word addr = cpu.gr[RD];
2d514e6f 932 int regno = 4; /* always r4-r7 */
ba14f941 933
2d514e6f
SS
934 memops += 4;
935 bonus_cycles++;
936 do
937 {
938 wlat(addr, cpu.gr[regno]);
939 addr += 4;
940 regno++;
941 }
942 while ((regno & 0x3) != 0);
943 }
944 break;
945 case 0x6: /* ldm */
946 {
feb703b3 947 word addr = cpu.gr[0];
2d514e6f 948 int regno = RD;
ba14f941 949
2d514e6f
SS
950 /* bonus cycle is really only needed if
951 the next insn shifts the last reg loaded.
ba14f941 952
2d514e6f
SS
953 bonus_cycles++;
954 */
955 memops += 16-regno;
956 while (regno <= 0xF)
957 {
958 cpu.gr[regno] = rlat(addr);
959 addr += 4;
960 regno++;
961 }
962 }
963 break;
964 case 0x7: /* stm */
965 {
feb703b3 966 word addr = cpu.gr[0];
2d514e6f 967 int regno = RD;
ba14f941 968
2d514e6f
SS
969 /* this should be removed! */
970 /* bonus_cycles ++; */
971
972 memops += 16 - regno;
973 while (regno <= 0xF)
974 {
975 wlat(addr, cpu.gr[regno]);
976 addr += 4;
977 regno++;
978 }
979 }
980 break;
981
982 case 0x8: /* dect */
983 cpu.gr[RD] -= C_VALUE();
984 break;
985 case 0x9: /* decf */
986 cpu.gr[RD] -= C_OFF();
987 break;
988 case 0xA: /* inct */
989 cpu.gr[RD] += C_VALUE();
990 break;
991 case 0xB: /* incf */
992 cpu.gr[RD] += C_OFF();
993 break;
994 case 0xC: /* jmp */
995 pc = cpu.gr[RD];
392a587b
JM
996 if (tracing && RD == 15)
997 fprintf (stderr, "Func return, r2 = %x, r3 = %x\n",
998 cpu.gr[2], cpu.gr[3]);
2d514e6f
SS
999 bonus_cycles++;
1000 needfetch = 1;
1001 break;
1002 case 0xD: /* jsr */
1003 cpu.gr[15] = pc;
1004 pc = cpu.gr[RD];
1005 bonus_cycles++;
1006 needfetch = 1;
1007 break;
1008 case 0xE: /* ff1 */
1009 {
1010 word tmp, i;
1011 tmp = cpu.gr[RD];
1012 for (i = 0; !(tmp & 0x80000000) && i < 32; i++)
1013 tmp <<= 1;
1014 cpu.gr[RD] = i;
1015 }
1016 break;
1017 case 0xF: /* brev */
1018 {
1019 word tmp;
1020 tmp = cpu.gr[RD];
1021 tmp = ((tmp & 0xaaaaaaaa) >> 1) | ((tmp & 0x55555555) << 1);
1022 tmp = ((tmp & 0xcccccccc) >> 2) | ((tmp & 0x33333333) << 2);
1023 tmp = ((tmp & 0xf0f0f0f0) >> 4) | ((tmp & 0x0f0f0f0f) << 4);
1024 tmp = ((tmp & 0xff00ff00) >> 8) | ((tmp & 0x00ff00ff) << 8);
1025 cpu.gr[RD] = ((tmp & 0xffff0000) >> 16) | ((tmp & 0x0000ffff) << 16);
1026 }
1027 break;
1028 }
1029 break;
1030 case 0x01:
1031 switch RS
1032 {
ba14f941 1033 case 0x0: /* xtrb3 */
2d514e6f
SS
1034 cpu.gr[1] = (cpu.gr[RD]) & 0xFF;
1035 NEW_C (cpu.gr[RD] != 0);
1036 break;
1037 case 0x1: /* xtrb2 */
1038 cpu.gr[1] = (cpu.gr[RD]>>8) & 0xFF;
1039 NEW_C (cpu.gr[RD] != 0);
1040 break;
1041 case 0x2: /* xtrb1 */
1042 cpu.gr[1] = (cpu.gr[RD]>>16) & 0xFF;
1043 NEW_C (cpu.gr[RD] != 0);
1044 break;
1045 case 0x3: /* xtrb0 */
1046 cpu.gr[1] = (cpu.gr[RD]>>24) & 0xFF;
1047 NEW_C (cpu.gr[RD] != 0);
1048 break;
1049 case 0x4: /* zextb */
1050 cpu.gr[RD] &= 0x000000FF;
1051 break;
1052 case 0x5: /* sextb */
1053 {
1054 long tmp;
1055 tmp = cpu.gr[RD];
1056 tmp <<= 24;
1057 tmp >>= 24;
1058 cpu.gr[RD] = tmp;
1059 }
1060 break;
1061 case 0x6: /* zexth */
1062 cpu.gr[RD] &= 0x0000FFFF;
1063 break;
1064 case 0x7: /* sexth */
1065 {
1066 long tmp;
1067 tmp = cpu.gr[RD];
1068 tmp <<= 16;
1069 tmp >>= 16;
1070 cpu.gr[RD] = tmp;
1071 }
1072 break;
ba14f941 1073 case 0x8: /* declt */
2d514e6f
SS
1074 --cpu.gr[RD];
1075 NEW_C ((long)cpu.gr[RD] < 0);
1076 break;
1077 case 0x9: /* tstnbz */
1078 {
1079 word tmp = cpu.gr[RD];
1080 NEW_C ((tmp & 0xFF000000) != 0 &&
1081 (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 &&
1082 (tmp & 0x000000FF) != 0);
1083 }
ba14f941 1084 break;
2d514e6f
SS
1085 case 0xA: /* decgt */
1086 --cpu.gr[RD];
1087 NEW_C ((long)cpu.gr[RD] > 0);
1088 break;
1089 case 0xB: /* decne */
1090 --cpu.gr[RD];
1091 NEW_C ((long)cpu.gr[RD] != 0);
1092 break;
1093 case 0xC: /* clrt */
1094 if (C_ON())
1095 cpu.gr[RD] = 0;
1096 break;
1097 case 0xD: /* clrf */
1098 if (C_OFF())
1099 cpu.gr[RD] = 0;
1100 break;
1101 case 0xE: /* abs */
1102 if (cpu.gr[RD] & 0x80000000)
1103 cpu.gr[RD] = ~cpu.gr[RD] + 1;
1104 break;
1105 case 0xF: /* not */
1106 cpu.gr[RD] = ~cpu.gr[RD];
1107 break;
1108 }
1109 break;
1110 case 0x02: /* movt */
1111 if (C_ON())
1112 cpu.gr[RD] = cpu.gr[RS];
1113 break;
1114 case 0x03: /* mult */
1115 /* consume 2 bits per cycle from rs, until rs is 0 */
1116 {
1117 unsigned int t = cpu.gr[RS];
1118 int ticks;
ba14f941 1119 for (ticks = 0; t != 0 ; t >>= 2)
2d514e6f
SS
1120 ticks++;
1121 bonus_cycles += ticks;
1122 }
1123 bonus_cycles += 2; /* min. is 3, so add 2, plus ticks above */
392a587b
JM
1124 if (tracing)
1125 fprintf (stderr, " mult %x by %x to give %x",
1126 cpu.gr[RD], cpu.gr[RS], cpu.gr[RD] * cpu.gr[RS]);
2d514e6f
SS
1127 cpu.gr[RD] = cpu.gr[RD] * cpu.gr[RS];
1128 break;
1129 case 0x04: /* loopt */
1130 if (C_ON())
1131 {
1132 pc += (IMM4 << 1) - 32;
1133 bonus_cycles ++;
1134 needfetch = 1;
1135 }
1136 --cpu.gr[RS]; /* not RD! */
1137 NEW_C (((long)cpu.gr[RS]) > 0);
ba14f941 1138 break;
2d514e6f
SS
1139 case 0x05: /* subu */
1140 cpu.gr[RD] -= cpu.gr[RS];
1141 break;
1142 case 0x06: /* addc */
1143 {
1144 unsigned long tmp, a, b;
1145 a = cpu.gr[RD];
1146 b = cpu.gr[RS];
1147 cpu.gr[RD] = a + b + C_VALUE ();
1148 tmp = iu_carry (a, b, C_VALUE ());
1149 NEW_C (tmp);
1150 }
1151 break;
1152 case 0x07: /* subc */
1153 {
1154 unsigned long tmp, a, b;
1155 a = cpu.gr[RD];
1156 b = cpu.gr[RS];
1157 cpu.gr[RD] = a - b + C_VALUE () - 1;
1158 tmp = iu_carry (a,~b, C_VALUE ());
1159 NEW_C (tmp);
1160 }
1161 break;
1162 case 0x08: /* illegal */
1163 case 0x09: /* illegal*/
1164 cpu.asregs.exception = SIGILL;
1165 break;
1166 case 0x0A: /* movf */
1167 if (C_OFF())
1168 cpu.gr[RD] = cpu.gr[RS];
1169 break;
1170 case 0x0B: /* lsr */
ba14f941 1171 {
2d514e6f
SS
1172 unsigned long dst, src;
1173 dst = cpu.gr[RD];
1174 src = cpu.gr[RS];
c5394b80
JM
1175 /* We must not rely solely upon the native shift operations, since they
1176 may not match the M*Core's behaviour on boundary conditions. */
1177 dst = src > 31 ? 0 : dst >> src;
2d514e6f
SS
1178 cpu.gr[RD] = dst;
1179 }
1180 break;
1181 case 0x0C: /* cmphs */
ba14f941 1182 NEW_C ((unsigned long )cpu.gr[RD] >=
2d514e6f
SS
1183 (unsigned long)cpu.gr[RS]);
1184 break;
1185 case 0x0D: /* cmplt */
1186 NEW_C ((long)cpu.gr[RD] < (long)cpu.gr[RS]);
1187 break;
1188 case 0x0E: /* tst */
1189 NEW_C ((cpu.gr[RD] & cpu.gr[RS]) != 0);
1190 break;
1191 case 0x0F: /* cmpne */
1192 NEW_C (cpu.gr[RD] != cpu.gr[RS]);
1193 break;
1194 case 0x10: case 0x11: /* mfcr */
1195 {
1196 unsigned r;
1197 r = IMM5;
1198 if (r <= LAST_VALID_CREG)
1199 cpu.gr[RD] = cpu.cr[r];
1200 else
1201 cpu.asregs.exception = SIGILL;
1202 }
1203 break;
1204
1205 case 0x12: /* mov */
1206 cpu.gr[RD] = cpu.gr[RS];
392a587b
JM
1207 if (tracing)
1208 fprintf (stderr, "MOV %x into reg %d", cpu.gr[RD], RD);
2d514e6f
SS
1209 break;
1210
1211 case 0x13: /* bgenr */
1212 if (cpu.gr[RS] & 0x20)
1213 cpu.gr[RD] = 0;
1214 else
1215 cpu.gr[RD] = 1 << (cpu.gr[RS] & 0x1F);
1216 break;
1217
1218 case 0x14: /* rsub */
1219 cpu.gr[RD] = cpu.gr[RS] - cpu.gr[RD];
1220 break;
1221
1222 case 0x15: /* ixw */
1223 cpu.gr[RD] += cpu.gr[RS]<<2;
1224 break;
1225
1226 case 0x16: /* and */
1227 cpu.gr[RD] &= cpu.gr[RS];
1228 break;
1229
1230 case 0x17: /* xor */
1231 cpu.gr[RD] ^= cpu.gr[RS];
1232 break;
1233
1234 case 0x18: case 0x19: /* mtcr */
1235 {
1236 unsigned r;
1237 r = IMM5;
1238 if (r <= LAST_VALID_CREG)
1239 cpu.cr[r] = cpu.gr[RD];
1240 else
1241 cpu.asregs.exception = SIGILL;
ba14f941 1242
2d514e6f
SS
1243 /* we might have changed register sets... */
1244 if (SR_AF ())
1245 cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
1246 else
1247 cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
1248 }
1249 break;
1250
1251 case 0x1A: /* asr */
c5394b80
JM
1252 /* We must not rely solely upon the native shift operations, since they
1253 may not match the M*Core's behaviour on boundary conditions. */
1254 if (cpu.gr[RS] > 30)
1255 cpu.gr[RD] = ((long) cpu.gr[RD]) < 0 ? -1 : 0;
1256 else
1257 cpu.gr[RD] = (long) cpu.gr[RD] >> cpu.gr[RS];
2d514e6f
SS
1258 break;
1259
1260 case 0x1B: /* lsl */
c5394b80
JM
1261 /* We must not rely solely upon the native shift operations, since they
1262 may not match the M*Core's behaviour on boundary conditions. */
1263 cpu.gr[RD] = cpu.gr[RS] > 31 ? 0 : cpu.gr[RD] << cpu.gr[RS];
2d514e6f
SS
1264 break;
1265
1266 case 0x1C: /* addu */
1267 cpu.gr[RD] += cpu.gr[RS];
1268 break;
1269
1270 case 0x1D: /* ixh */
1271 cpu.gr[RD] += cpu.gr[RS] << 1;
1272 break;
1273
1274 case 0x1E: /* or */
1275 cpu.gr[RD] |= cpu.gr[RS];
1276 break;
1277
1278 case 0x1F: /* andn */
1279 cpu.gr[RD] &= ~cpu.gr[RS];
1280 break;
1281 case 0x20: case 0x21: /* addi */
1282 cpu.gr[RD] =
1283 cpu.gr[RD] + (IMM5 + 1);
1284 break;
1285 case 0x22: case 0x23: /* cmplti */
1286 {
1287 int tmp = (IMM5 + 1);
1288 if (cpu.gr[RD] < tmp)
1289 {
1290 SET_C();
1291 }
1292 else
1293 {
1294 CLR_C();
1295 }
1296 }
1297 break;
1298 case 0x24: case 0x25: /* subi */
1299 cpu.gr[RD] =
1300 cpu.gr[RD] - (IMM5 + 1);
1301 break;
1302 case 0x26: case 0x27: /* illegal */
1303 cpu.asregs.exception = SIGILL;
1304 break;
1305 case 0x28: case 0x29: /* rsubi */
1306 cpu.gr[RD] =
1307 IMM5 - cpu.gr[RD];
1308 break;
1309 case 0x2A: case 0x2B: /* cmpnei */
1310 if (cpu.gr[RD] != IMM5)
1311 {
1312 SET_C();
1313 }
1314 else
1315 {
1316 CLR_C();
1317 }
1318 break;
ba14f941 1319
2d514e6f
SS
1320 case 0x2C: case 0x2D: /* bmaski, divu */
1321 {
1322 unsigned imm = IMM5;
ba14f941 1323
2d514e6f
SS
1324 if (imm == 1)
1325 {
1326 int exe;
1327 int rxnlz, r1nlz;
1328 unsigned int rx, r1;
1329
1330 rx = cpu.gr[RD];
1331 r1 = cpu.gr[1];
1332 exe = 0;
1333
1334 /* unsigned divide */
1335 cpu.gr[RD] = (word) ((unsigned int) cpu.gr[RD] / (unsigned int)cpu.gr[1] );
ba14f941 1336
2d514e6f
SS
1337 /* compute bonus_cycles for divu */
1338 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++)
1339 r1 = r1 << 1;
1340
1341 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32); rxnlz ++)
1342 rx = rx << 1;
1343
1344 if (r1nlz < rxnlz)
1345 exe += 4;
1346 else
1347 exe += 5 + r1nlz - rxnlz;
1348
1349 if (exe >= (2 * memcycles - 1))
1350 {
1351 bonus_cycles += exe - (2 * memcycles) + 1;
1352 }
1353 }
1354 else if (imm == 0 || imm >= 8)
1355 {
1356 /* bmaski */
1357 if (imm == 0)
1358 cpu.gr[RD] = -1;
1359 else
1360 cpu.gr[RD] = (1 << imm) - 1;
1361 }
1362 else
1363 {
1364 /* illegal */
1365 cpu.asregs.exception = SIGILL;
1366 }
1367 }
1368 break;
1369 case 0x2E: case 0x2F: /* andi */
1370 cpu.gr[RD] = cpu.gr[RD] & IMM5;
1371 break;
1372 case 0x30: case 0x31: /* bclri */
1373 cpu.gr[RD] = cpu.gr[RD] & ~(1<<IMM5);
1374 break;
1375 case 0x32: case 0x33: /* bgeni, divs */
1376 {
1377 unsigned imm = IMM5;
1378 if (imm == 1)
1379 {
1380 int exe,sc;
1381 int rxnlz, r1nlz;
1382 signed int rx, r1;
ba14f941 1383
2d514e6f
SS
1384 /* compute bonus_cycles for divu */
1385 rx = cpu.gr[RD];
1386 r1 = cpu.gr[1];
1387 exe = 0;
ba14f941 1388
2d514e6f
SS
1389 if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0)))
1390 sc = 1;
1391 else
1392 sc = 0;
ba14f941 1393
2d514e6f
SS
1394 rx = abs (rx);
1395 r1 = abs (r1);
ba14f941 1396
2d514e6f
SS
1397 /* signed divide, general registers are of type int, so / op is OK */
1398 cpu.gr[RD] = cpu.gr[RD] / cpu.gr[1];
ba14f941 1399
2d514e6f
SS
1400 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ )
1401 r1 = r1 << 1;
ba14f941 1402
2d514e6f
SS
1403 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ )
1404 rx = rx << 1;
ba14f941 1405
2d514e6f
SS
1406 if (r1nlz < rxnlz)
1407 exe += 5;
1408 else
1409 exe += 6 + r1nlz - rxnlz + sc;
ba14f941 1410
2d514e6f
SS
1411 if (exe >= (2 * memcycles - 1))
1412 {
1413 bonus_cycles += exe - (2 * memcycles) + 1;
1414 }
1415 }
1416 else if (imm >= 7)
1417 {
1418 /* bgeni */
1419 cpu.gr[RD] = (1 << IMM5);
1420 }
1421 else
1422 {
1423 /* illegal */
1424 cpu.asregs.exception = SIGILL;
1425 }
1426 break;
1427 }
1428 case 0x34: case 0x35: /* bseti */
1429 cpu.gr[RD] = cpu.gr[RD] | (1 << IMM5);
1430 break;
1431 case 0x36: case 0x37: /* btsti */
1432 NEW_C (cpu.gr[RD] >> IMM5);
1433 break;
1434 case 0x38: case 0x39: /* xsr, rotli */
1435 {
1436 unsigned imm = IMM5;
1437 unsigned long tmp = cpu.gr[RD];
1438 if (imm == 0)
1439 {
1440 word cbit;
1441 cbit = C_VALUE();
1442 NEW_C (tmp);
1443 cpu.gr[RD] = (cbit << 31) | (tmp >> 1);
1444 }
1445 else
1446 cpu.gr[RD] = (tmp << imm) | (tmp >> (32 - imm));
1447 }
1448 break;
1449 case 0x3A: case 0x3B: /* asrc, asri */
1450 {
1451 unsigned imm = IMM5;
1452 long tmp = cpu.gr[RD];
1453 if (imm == 0)
1454 {
1455 NEW_C (tmp);
1456 cpu.gr[RD] = tmp >> 1;
1457 }
1458 else
1459 cpu.gr[RD] = tmp >> imm;
1460 }
1461 break;
1462 case 0x3C: case 0x3D: /* lslc, lsli */
1463 {
1464 unsigned imm = IMM5;
1465 unsigned long tmp = cpu.gr[RD];
1466 if (imm == 0)
1467 {
1468 NEW_C (tmp >> 31);
1469 cpu.gr[RD] = tmp << 1;
1470 }
1471 else
1472 cpu.gr[RD] = tmp << imm;
1473 }
1474 break;
1475 case 0x3E: case 0x3F: /* lsrc, lsri */
1476 {
1477 unsigned imm = IMM5;
1478 unsigned long tmp = cpu.gr[RD];
1479 if (imm == 0)
1480 {
1481 NEW_C (tmp);
1482 cpu.gr[RD] = tmp >> 1;
1483 }
1484 else
1485 cpu.gr[RD] = tmp >> imm;
1486 }
1487 break;
1488 case 0x40: case 0x41: case 0x42: case 0x43:
1489 case 0x44: case 0x45: case 0x46: case 0x47:
1490 case 0x48: case 0x49: case 0x4A: case 0x4B:
1491 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1492 cpu.asregs.exception = SIGILL;
1493 break;
1494 case 0x50:
ba14f941 1495 util (inst & 0xFF);
2d514e6f
SS
1496 break;
1497 case 0x51: case 0x52: case 0x53:
1498 case 0x54: case 0x55: case 0x56: case 0x57:
1499 case 0x58: case 0x59: case 0x5A: case 0x5B:
1500 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1501 cpu.asregs.exception = SIGILL;
1502 break;
1503 case 0x60: case 0x61: case 0x62: case 0x63: /* movi */
1504 case 0x64: case 0x65: case 0x66: case 0x67:
1505 cpu.gr[RD] = (inst >> 4) & 0x7F;
1506 break;
1507 case 0x68: case 0x69: case 0x6A: case 0x6B:
1508 case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */
1509 cpu.asregs.exception = SIGILL;
1510 break;
1511 case 0x71: case 0x72: case 0x73:
1512 case 0x74: case 0x75: case 0x76: case 0x77:
1513 case 0x78: case 0x79: case 0x7A: case 0x7B:
1514 case 0x7C: case 0x7D: case 0x7E: /* lrw */
1515 cpu.gr[RX] = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1516 if (tracing)
1517 fprintf (stderr, "LRW of 0x%x from 0x%x to reg %d",
1518 rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC),
1519 (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX);
1520 memops++;
1521 break;
1522 case 0x7F: /* jsri */
1523 cpu.gr[15] = pc;
392a587b
JM
1524 if (tracing)
1525 fprintf (stderr, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1526 cpu.gr[2], cpu.gr[3], cpu.gr[4], cpu.gr[5], cpu.gr[6], cpu.gr[7]);
2d514e6f
SS
1527 case 0x70: /* jmpi */
1528 pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1529 memops++;
1530 bonus_cycles++;
1531 needfetch = 1;
1532 break;
1533
1534 case 0x80: case 0x81: case 0x82: case 0x83:
1535 case 0x84: case 0x85: case 0x86: case 0x87:
1536 case 0x88: case 0x89: case 0x8A: case 0x8B:
1537 case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */
1538 cpu.gr[RX] = rlat (cpu.gr[RD] + ((inst >> 2) & 0x003C));
1539 if (tracing)
1540 fprintf (stderr, "load reg %d from 0x%x with 0x%x",
1541 RX,
1542 cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1543 memops++;
1544 break;
1545 case 0x90: case 0x91: case 0x92: case 0x93:
1546 case 0x94: case 0x95: case 0x96: case 0x97:
1547 case 0x98: case 0x99: case 0x9A: case 0x9B:
1548 case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */
1549 wlat (cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1550 if (tracing)
1551 fprintf (stderr, "store reg %d (containing 0x%x) to 0x%x",
1552 RX, cpu.gr[RX],
1553 cpu.gr[RD] + ((inst >> 2) & 0x003C));
1554 memops++;
1555 break;
1556 case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1557 case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1558 case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1559 case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */
1560 cpu.gr[RX] = rbat (cpu.gr[RD] + RS);
1561 memops++;
1562 break;
1563 case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1564 case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1565 case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1566 case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */
1567 wbat (cpu.gr[RD] + RS, cpu.gr[RX]);
1568 memops++;
1569 break;
1570 case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1571 case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1572 case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1573 case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */
1574 cpu.gr[RX] = rhat (cpu.gr[RD] + ((inst >> 3) & 0x001E));
1575 memops++;
1576 break;
1577 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1578 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1579 case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1580 case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */
1581 what (cpu.gr[RD] + ((inst >> 3) & 0x001E), cpu.gr[RX]);
1582 memops++;
1583 break;
1584 case 0xE8: case 0xE9: case 0xEA: case 0xEB:
ba14f941 1585 case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */
2d514e6f
SS
1586 if (C_OFF())
1587 {
1588 int disp;
1589 disp = inst & 0x03FF;
1590 if (inst & 0x0400)
1591 disp |= 0xFFFFFC00;
1592 pc += disp<<1;
1593 bonus_cycles++;
1594 needfetch = 1;
1595 }
1596 break;
1597 case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1598 case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */
1599 if (C_ON())
1600 {
1601 int disp;
1602 disp = inst & 0x03FF;
1603 if (inst & 0x0400)
1604 disp |= 0xFFFFFC00;
1605 pc += disp<<1;
1606 bonus_cycles++;
1607 needfetch = 1;
1608 }
1609 break;
1610
1611 case 0xF8: case 0xF9: case 0xFA: case 0xFB:
ba14f941 1612 case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */
2d514e6f
SS
1613 cpu.gr[15] = pc;
1614 case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1615 case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */
1616 {
1617 int disp;
1618 disp = inst & 0x03FF;
1619 if (inst & 0x0400)
1620 disp |= 0xFFFFFC00;
1621 pc += disp<<1;
1622 bonus_cycles++;
1623 needfetch = 1;
1624 }
1625 break;
1626
1627 }
1628
1629 if (tracing)
1630 fprintf (stderr, "\n");
cd0fc7c3 1631
ba14f941 1632 if (needfetch)
2d514e6f
SS
1633 {
1634 /* Do not let him fetch from a bad address! */
1635 if (((uword)pc) >= cpu.asregs.msize)
1636 {
1637 if (issue_messages)
cd0fc7c3 1638 fprintf (stderr, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc, pc);
ba14f941 1639
2d514e6f
SS
1640 cpu.asregs.exception = SIGSEGV;
1641 }
1642 else
1643 {
1644 ibuf = rlat (pc & 0xFFFFFFFC);
1645 needfetch = 0;
1646 }
1647 }
1648 }
1649 while (!cpu.asregs.exception);
1650
1651 /* Hide away the things we've cached while executing. */
1652 cpu.asregs.pc = pc;
1653 cpu.asregs.insts += insts; /* instructions done ... */
1654 cpu.asregs.cycles += insts; /* and each takes a cycle */
1655 cpu.asregs.cycles += bonus_cycles; /* and extra cycles for branches */
1656 cpu.asregs.cycles += memops * memcycles; /* and memop cycle delays */
2d514e6f
SS
1657}
1658
1659
1660int
feb703b3 1661sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
2d514e6f
SS
1662{
1663 int i;
1664 init_pointers ();
ba14f941 1665
2d514e6f 1666 memcpy (& cpu.mem[addr], buffer, size);
ba14f941 1667
2d514e6f
SS
1668 return size;
1669}
1670
1671int
feb703b3 1672sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
2d514e6f
SS
1673{
1674 int i;
1675 init_pointers ();
ba14f941 1676
2d514e6f 1677 memcpy (buffer, & cpu.mem[addr], size);
ba14f941 1678
2d514e6f
SS
1679 return size;
1680}
1681
1682
1683int
feb703b3 1684sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
2d514e6f
SS
1685{
1686 init_pointers ();
1687
1688 if (rn < NUM_MCORE_REGS && rn >= 0)
1689 {
1690 if (length == 4)
1691 {
2d514e6f 1692 long ival;
ba14f941 1693
cd0fc7c3
SS
1694 /* misalignment safe */
1695 ival = mcore_extract_unsigned_integer (memory, 4);
2d514e6f
SS
1696 cpu.asints[rn] = ival;
1697 }
1698
1699 return 4;
1700 }
1701 else
1702 return 0;
1703}
1704
1705int
feb703b3 1706sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
2d514e6f
SS
1707{
1708 init_pointers ();
ba14f941 1709
2d514e6f
SS
1710 if (rn < NUM_MCORE_REGS && rn >= 0)
1711 {
1712 if (length == 4)
1713 {
2d514e6f 1714 long ival = cpu.asints[rn];
cd0fc7c3
SS
1715
1716 /* misalignment-safe */
1717 mcore_store_unsigned_integer (memory, 4, ival);
2d514e6f 1718 }
ba14f941 1719
2d514e6f
SS
1720 return 4;
1721 }
1722 else
1723 return 0;
1724}
1725
1726
1727int
feb703b3 1728sim_trace (SIM_DESC sd)
2d514e6f
SS
1729{
1730 tracing = 1;
ba14f941 1731
2d514e6f
SS
1732 sim_resume (sd, 0, 0);
1733
1734 tracing = 0;
ba14f941 1735
2d514e6f
SS
1736 return 1;
1737}
1738
1739void
feb703b3 1740sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
2d514e6f
SS
1741{
1742 if (cpu.asregs.exception == SIGQUIT)
1743 {
1744 * reason = sim_exited;
1745 * sigrc = cpu.gr[PARM1];
1746 }
1747 else
1748 {
1749 * reason = sim_stopped;
1750 * sigrc = cpu.asregs.exception;
1751 }
1752}
1753
1754
1755int
feb703b3 1756sim_stop (SIM_DESC sd)
2d514e6f
SS
1757{
1758 cpu.asregs.exception = SIGINT;
1759 return 1;
1760}
1761
1762
1763void
feb703b3 1764sim_info (SIM_DESC sd, int verbose)
2d514e6f
SS
1765{
1766#ifdef WATCHFUNCTIONS
1767 int w, wcyc;
1768#endif
1769 double virttime = cpu.asregs.cycles / 36.0e6;
1770
cd0fc7c3
SS
1771 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1772 cpu.asregs.insts);
1773 callback->printf_filtered (callback, "# cycles %10d\n",
1774 cpu.asregs.cycles);
1775 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1776 cpu.asregs.stalls);
1777 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1778 virttime);
2d514e6f
SS
1779
1780#ifdef WATCHFUNCTIONS
cd0fc7c3
SS
1781 callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
1782 ENDWL);
2d514e6f
SS
1783
1784 wcyc = 0;
ba14f941 1785
2d514e6f
SS
1786 for (w = 1; w <= ENDWL; w++)
1787 {
1788 callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
cd0fc7c3
SS
1789 callback->printf_filtered (callback, " calls = %d, cycles = %d\n",
1790 WLcnts[w],WLcyc[w]);
ba14f941 1791
2d514e6f 1792 if (WLcnts[w] != 0)
cd0fc7c3
SS
1793 callback->printf_filtered (callback,
1794 " maxcpc = %d, mincpc = %d, avecpc = %d\n",
1795 WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
2d514e6f
SS
1796 wcyc += WLcyc[w];
1797 }
ba14f941 1798
cd0fc7c3
SS
1799 callback->printf_filtered (callback,
1800 "Total cycles for watched functions: %d\n",wcyc);
2d514e6f
SS
1801#endif
1802}
1803
1804struct aout
1805{
1806 unsigned char sa_machtype[2];
1807 unsigned char sa_magic[2];
1808 unsigned char sa_tsize[4];
1809 unsigned char sa_dsize[4];
1810 unsigned char sa_bsize[4];
1811 unsigned char sa_syms[4];
1812 unsigned char sa_entry[4];
1813 unsigned char sa_trelo[4];
1814 unsigned char sa_drelo[4];
1815} aout;
1816
1817#define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1818#define SHORT(x) (((x)[0]<<8)|(x)[1])
1819
1820SIM_DESC
feb703b3 1821sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
2d514e6f
SS
1822{
1823 int osize = sim_memory_size;
1824 myname = argv[0];
1825 callback = cb;
ba14f941 1826
2d514e6f
SS
1827 if (kind == SIM_OPEN_STANDALONE)
1828 issue_messages = 1;
ba14f941 1829
2d514e6f
SS
1830 /* Discard and reacquire memory -- start with a clean slate. */
1831 sim_size (1); /* small */
1832 sim_size (osize); /* and back again */
1833
1834 set_initial_gprs (); /* Reset the GPR registers. */
ba14f941 1835
2d514e6f
SS
1836 /* Fudge our descriptor for now. */
1837 return (SIM_DESC) 1;
1838}
1839
1840void
feb703b3 1841sim_close (SIM_DESC sd, int quitting)
2d514e6f
SS
1842{
1843 /* nothing to do */
1844}
1845
1846SIM_RC
feb703b3 1847sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
2d514e6f
SS
1848{
1849 /* Do the right thing for ELF executables; this turns out to be
1850 just about the right thing for any object format that:
1851 - we crack using BFD routines
1852 - follows the traditional UNIX text/data/bss layout
1853 - calls the bss section ".bss". */
1854
1855 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
1856 bfd * prog_bfd;
1857
1858 {
1859 bfd * handle;
2d514e6f 1860 handle = bfd_openr (prog, 0); /* could be "mcore" */
ba14f941 1861
2d514e6f
SS
1862 if (!handle)
1863 {
1864 printf("``%s'' could not be opened.\n", prog);
1865 return SIM_RC_FAIL;
1866 }
ba14f941
MF
1867
1868 /* Makes sure that we have an object file, also cleans gets the
2d514e6f
SS
1869 section headers in place. */
1870 if (!bfd_check_format (handle, bfd_object))
1871 {
1872 /* wasn't an object file */
1873 bfd_close (handle);
1874 printf ("``%s'' is not appropriate object file.\n", prog);
1875 return SIM_RC_FAIL;
1876 }
cd0fc7c3 1877
2d514e6f
SS
1878 /* Clean up after ourselves. */
1879 bfd_close (handle);
ba14f941 1880
2d514e6f
SS
1881 /* XXX: do we need to free the s_bss and handle structures? */
1882 }
1883
1884 /* from sh -- dac */
1885 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1886 sim_kind == SIM_OPEN_DEBUG,
1887 0, sim_write);
1888 if (prog_bfd == NULL)
1889 return SIM_RC_FAIL;
ba14f941 1890
63a027a3 1891 target_big_endian = bfd_big_endian (prog_bfd);
ba14f941 1892
2d514e6f
SS
1893 if (abfd == NULL)
1894 bfd_close (prog_bfd);
1895
1896 return SIM_RC_OK;
1897}
1898
1899SIM_RC
feb703b3 1900sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
2d514e6f
SS
1901{
1902 char ** avp;
1903 int nargs = 0;
1904 int nenv = 0;
1905 int s_length;
1906 int l;
1907 unsigned long strings;
1908 unsigned long pointers;
1909 unsigned long hi_stack;
1910
1911
1912 /* Set the initial register set. */
1913 l = issue_messages;
1914 issue_messages = 0;
1915 set_initial_gprs ();
1916 issue_messages = l;
ba14f941 1917
2d514e6f
SS
1918 hi_stack = cpu.asregs.msize - 4;
1919 cpu.asregs.pc = bfd_get_start_address (prog_bfd);
1920
1921 /* Calculate the argument and environment strings. */
1922 s_length = 0;
1923 nargs = 0;
1924 avp = argv;
1925 while (avp && *avp)
1926 {
1927 l = strlen (*avp) + 1; /* include the null */
1928 s_length += (l + 3) & ~3; /* make it a 4 byte boundary */
1929 nargs++; avp++;
1930 }
1931
1932 nenv = 0;
1933 avp = env;
1934 while (avp && *avp)
1935 {
1936 l = strlen (*avp) + 1; /* include the null */
1937 s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */
1938 nenv++; avp++;
1939 }
1940
1941 /* Claim some memory for the pointers and strings. */
1942 pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1);
1943 pointers &= ~3; /* must be 4-byte aligned */
1944 cpu.gr[0] = pointers;
1945
1946 strings = cpu.gr[0] - s_length;
1947 strings &= ~3; /* want to make it 4-byte aligned */
1948 cpu.gr[0] = strings;
1949 /* dac fix, the stack address must be 8-byte aligned! */
1950 cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
1951
1952 /* Loop through the arguments and fill them in. */
1953 cpu.gr[PARM1] = nargs;
1954 if (nargs == 0)
1955 {
1956 /* No strings to fill in. */
1957 cpu.gr[PARM2] = 0;
1958 }
1959 else
1960 {
1961 cpu.gr[PARM2] = pointers;
1962 avp = argv;
1963 while (avp && *avp)
1964 {
1965 /* Save where we're putting it. */
1966 wlat (pointers, strings);
1967
1968 /* Copy the string. */
1969 l = strlen (* avp) + 1;
1970 strcpy ((char *)(cpu.mem + strings), *avp);
1971
1972 /* Bump the pointers. */
1973 avp++;
1974 pointers += 4;
1975 strings += l+1;
1976 }
ba14f941 1977
2d514e6f
SS
1978 /* A null to finish the list. */
1979 wlat (pointers, 0);
1980 pointers += 4;
1981 }
1982
1983 /* Now do the environment pointers. */
1984 if (nenv == 0)
1985 {
1986 /* No strings to fill in. */
1987 cpu.gr[PARM3] = 0;
1988 }
1989 else
1990 {
1991 cpu.gr[PARM3] = pointers;
1992 avp = env;
ba14f941 1993
2d514e6f
SS
1994 while (avp && *avp)
1995 {
1996 /* Save where we're putting it. */
1997 wlat (pointers, strings);
1998
1999 /* Copy the string. */
2000 l = strlen (* avp) + 1;
2001 strcpy ((char *)(cpu.mem + strings), *avp);
2002
2003 /* Bump the pointers. */
2004 avp++;
2005 pointers += 4;
2006 strings += l+1;
2007 }
ba14f941 2008
2d514e6f
SS
2009 /* A null to finish the list. */
2010 wlat (pointers, 0);
2011 pointers += 4;
2012 }
ba14f941 2013
2d514e6f
SS
2014 return SIM_RC_OK;
2015}
2016
2d514e6f 2017void
feb703b3 2018sim_do_command (SIM_DESC sd, const char *cmd)
2d514e6f
SS
2019{
2020 /* Nothing there yet; it's all an error. */
ba14f941 2021
2d514e6f
SS
2022 if (cmd != NULL)
2023 {
2024 char ** simargv = buildargv (cmd);
ba14f941 2025
2d514e6f
SS
2026 if (strcmp (simargv[0], "watch") == 0)
2027 {
2028 if ((simargv[1] == NULL) || (simargv[2] == NULL))
2029 {
2030 fprintf (stderr, "Error: missing argument to watch cmd.\n");
cd71915c 2031 freeargv (simargv);
2d514e6f
SS
2032 return;
2033 }
ba14f941 2034
2d514e6f 2035 ENDWL++;
ba14f941 2036
2d514e6f
SS
2037 WL[ENDWL] = strtol (simargv[2], NULL, 0);
2038 WLstr[ENDWL] = strdup (simargv[1]);
2039 fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
2040 WL[ENDWL], ENDWL);
2041
2042 }
2043 else if (strcmp (simargv[0], "dumpmem") == 0)
2044 {
2045 unsigned char * p;
2046 FILE * dumpfile;
2047
2048 if (simargv[1] == NULL)
2049 fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
2050
2051 fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
ba14f941 2052
2d514e6f
SS
2053 dumpfile = fopen (simargv[1], "w");
2054 p = cpu.mem;
2055 fwrite (p, cpu.asregs.msize-1, 1, dumpfile);
2056 fclose (dumpfile);
ba14f941 2057
2d514e6f
SS
2058 fprintf (stderr, "done.\n");
2059 }
2060 else if (strcmp (simargv[0], "clearstats") == 0)
2061 {
2062 cpu.asregs.cycles = 0;
2063 cpu.asregs.insts = 0;
2064 cpu.asregs.stalls = 0;
2065 ENDWL = 0;
2066 }
2067 else if (strcmp (simargv[0], "verbose") == 0)
2068 {
b83266a0 2069 issue_messages = 2;
2d514e6f
SS
2070 }
2071 else
2072 {
2073 fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2074 cmd);
2075 }
cd71915c
CG
2076
2077 freeargv (simargv);
2d514e6f
SS
2078 }
2079 else
2080 {
2081 fprintf (stderr, "M.CORE sim commands: \n");
2082 fprintf (stderr, " watch <funcname> <addr>\n");
2083 fprintf (stderr, " dumpmem <filename>\n");
2084 fprintf (stderr, " clearstats\n");
2085 fprintf (stderr, " verbose\n");
2086 }
2087}
2088
2089void
feb703b3 2090sim_set_callbacks (host_callback *ptr)
2d514e6f 2091{
ba14f941 2092 callback = ptr;
2d514e6f 2093}
This page took 0.835742 seconds and 4 git commands to generate.