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