1 /* Simulator for Motorola's MCore processor
2    Copyright (C) 1999, 2000, 2002, 2003, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Solutions.
5 
6 This file is part of GDB, the GNU debugger.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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 "gdb/callback.h"
28 #include "libiberty.h"
29 #include "gdb/remote-sim.h"
30 
31 #ifndef NUM_ELEM
32 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
33 #endif
34 
35 
36 typedef long int           word;
37 typedef unsigned long int  uword;
38 
39 static int            target_big_endian = 0;
40 static unsigned long  heap_ptr = 0;
41 host_callback *       callback;
42 
43 
44 unsigned long
mcore_extract_unsigned_integer(addr,len)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
mcore_store_unsigned_integer(addr,len,val)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
int_sbrk(inc_bytes)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
wbat(x,v)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
wlat(x,v)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
what(x,v)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
rbat(x)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
rlat(x)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
rhat(x)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
IOMEM(addr,write,value)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
sim_size(power)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
init_pointers()426 init_pointers ()
427 {
428   if (cpu.asregs.msize != (1 << sim_memory_size))
429     sim_size (sim_memory_size);
430 }
431 
432 static void
set_initial_gprs()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
interrupt()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
log_open(fd)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
log_close(fd)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
is_opened(fd)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
handle_trap1()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
process_stub(what)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
util(what)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
iu_carry(a,b,cin)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
sim_resume(sd,step,siggnal)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      const 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) bfd_get_section_vma (handle, s_bss),
1985 	    (unsigned long) bfd_section_size (handle, s_bss));
1986 #endif
1987     heap_ptr = ((unsigned long) bfd_get_section_vma (handle, s_bss)
1988 		+ (unsigned long) bfd_section_size (handle, s_bss));
1989 
1990     /* Clean up after ourselves.  */
1991     bfd_close (handle);
1992 
1993     /* XXX: do we need to free the s_bss and handle structures? */
1994   }
1995 
1996   /* from sh -- dac */
1997   prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1998                             sim_kind == SIM_OPEN_DEBUG,
1999                             0, sim_write);
2000   if (prog_bfd == NULL)
2001     return SIM_RC_FAIL;
2002 
2003   target_big_endian = bfd_big_endian (prog_bfd);
2004 
2005   if (abfd == NULL)
2006     bfd_close (prog_bfd);
2007 
2008   return SIM_RC_OK;
2009 }
2010 
2011 SIM_RC
2012 sim_create_inferior (sd, prog_bfd, argv, env)
2013      SIM_DESC sd;
2014      struct bfd * prog_bfd;
2015      char ** argv;
2016      char ** env;
2017 {
2018   char ** avp;
2019   int nargs = 0;
2020   int nenv = 0;
2021   int s_length;
2022   int l;
2023   unsigned long strings;
2024   unsigned long pointers;
2025   unsigned long hi_stack;
2026 
2027 
2028   /* Set the initial register set.  */
2029   l = issue_messages;
2030   issue_messages = 0;
2031   set_initial_gprs ();
2032   issue_messages = l;
2033 
2034   hi_stack = cpu.asregs.msize - 4;
2035   cpu.asregs.pc = bfd_get_start_address (prog_bfd);
2036 
2037   /* Calculate the argument and environment strings.  */
2038   s_length = 0;
2039   nargs = 0;
2040   avp = argv;
2041   while (avp && *avp)
2042     {
2043       l = strlen (*avp) + 1;	/* include the null */
2044       s_length += (l + 3) & ~3;	/* make it a 4 byte boundary */
2045       nargs++; avp++;
2046     }
2047 
2048   nenv = 0;
2049   avp = env;
2050   while (avp && *avp)
2051     {
2052       l = strlen (*avp) + 1;	/* include the null */
2053       s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */
2054       nenv++; avp++;
2055     }
2056 
2057   /* Claim some memory for the pointers and strings. */
2058   pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1);
2059   pointers &= ~3;		/* must be 4-byte aligned */
2060   cpu.gr[0] = pointers;
2061 
2062   strings = cpu.gr[0] - s_length;
2063   strings &= ~3;		/* want to make it 4-byte aligned */
2064   cpu.gr[0] = strings;
2065   /* dac fix, the stack address must be 8-byte aligned! */
2066   cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
2067 
2068   /* Loop through the arguments and fill them in.  */
2069   cpu.gr[PARM1] = nargs;
2070   if (nargs == 0)
2071     {
2072       /* No strings to fill in.  */
2073       cpu.gr[PARM2] = 0;
2074     }
2075   else
2076     {
2077       cpu.gr[PARM2] = pointers;
2078       avp = argv;
2079       while (avp && *avp)
2080 	{
2081 	  /* Save where we're putting it.  */
2082 	  wlat (pointers, strings);
2083 
2084 	  /* Copy the string.  */
2085 	  l = strlen (* avp) + 1;
2086 	  strcpy ((char *)(cpu.mem + strings), *avp);
2087 
2088 	  /* Bump the pointers.  */
2089 	  avp++;
2090 	  pointers += 4;
2091 	  strings += l+1;
2092 	}
2093 
2094       /* A null to finish the list.  */
2095       wlat (pointers, 0);
2096       pointers += 4;
2097     }
2098 
2099   /* Now do the environment pointers.  */
2100   if (nenv == 0)
2101     {
2102       /* No strings to fill in.  */
2103       cpu.gr[PARM3] = 0;
2104     }
2105   else
2106     {
2107       cpu.gr[PARM3] = pointers;
2108       avp = env;
2109 
2110       while (avp && *avp)
2111 	{
2112 	  /* Save where we're putting it.  */
2113 	  wlat (pointers, strings);
2114 
2115 	  /* Copy the string.  */
2116 	  l = strlen (* avp) + 1;
2117 	  strcpy ((char *)(cpu.mem + strings), *avp);
2118 
2119 	  /* Bump the pointers.  */
2120 	  avp++;
2121 	  pointers += 4;
2122 	  strings += l+1;
2123 	}
2124 
2125       /* A null to finish the list.  */
2126       wlat (pointers, 0);
2127       pointers += 4;
2128     }
2129 
2130   return SIM_RC_OK;
2131 }
2132 
2133 void
2134 sim_kill (sd)
2135      SIM_DESC sd;
2136 {
2137   /* nothing to do */
2138 }
2139 
2140 void
2141 sim_do_command (sd, cmd)
2142      SIM_DESC sd;
2143      char * cmd;
2144 {
2145   /* Nothing there yet; it's all an error.  */
2146 
2147   if (cmd != NULL)
2148     {
2149       char ** simargv = buildargv (cmd);
2150 
2151       if (strcmp (simargv[0], "watch") == 0)
2152 	{
2153 	  if ((simargv[1] == NULL) || (simargv[2] == NULL))
2154 	    {
2155 	      fprintf (stderr, "Error: missing argument to watch cmd.\n");
2156 	      return;
2157 	    }
2158 
2159 	  ENDWL++;
2160 
2161 	  WL[ENDWL] = strtol (simargv[2], NULL, 0);
2162 	  WLstr[ENDWL] = strdup (simargv[1]);
2163 	  fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
2164 		   WL[ENDWL], ENDWL);
2165 
2166 	}
2167       else if (strcmp (simargv[0], "dumpmem") == 0)
2168 	{
2169 	  unsigned char * p;
2170 	  FILE * dumpfile;
2171 
2172 	  if (simargv[1] == NULL)
2173 	    fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
2174 
2175 	  fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
2176 
2177 	  dumpfile = fopen (simargv[1], "w");
2178 	  p = cpu.mem;
2179 	  fwrite (p, cpu.asregs.msize-1, 1, dumpfile);
2180 	  fclose (dumpfile);
2181 
2182 	  fprintf (stderr, "done.\n");
2183 	}
2184       else if (strcmp (simargv[0], "clearstats") == 0)
2185 	{
2186 	  cpu.asregs.cycles = 0;
2187 	  cpu.asregs.insts = 0;
2188 	  cpu.asregs.stalls = 0;
2189 	  ENDWL = 0;
2190 	}
2191       else if (strcmp (simargv[0], "verbose") == 0)
2192 	{
2193 	  issue_messages = 2;
2194 	}
2195       else
2196 	{
2197 	  fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2198 		   cmd);
2199 	}
2200     }
2201   else
2202     {
2203       fprintf (stderr, "M.CORE sim commands: \n");
2204       fprintf (stderr, "  watch <funcname> <addr>\n");
2205       fprintf (stderr, "  dumpmem <filename>\n");
2206       fprintf (stderr, "  clearstats\n");
2207       fprintf (stderr, "  verbose\n");
2208     }
2209 }
2210 
2211 void
2212 sim_set_callbacks (ptr)
2213      host_callback * ptr;
2214 {
2215   callback = ptr;
2216 }
2217