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