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