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