sim: sim-close: unify sim_close logic
[binutils-gdb.git] / sim / mcore / interp.c
index 810bb0698355faff1f915034b07658b08ca306b8..2a9f19378746cd0b38c141aab777853940ec9413 100644 (file)
@@ -1,81 +1,88 @@
-/* Simulator for Motorolla's MCore processor
-   Copyright (C) 1999 Free Software Foundation, Inc.
+/* Simulator for Motorola's MCore processor
+   Copyright (C) 1999-2015 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions.
 
 This file is part of GDB, the GNU debugger.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include "config.h"
 #include <signal.h>
-#include "sysdep.h"
+#include <stdlib.h>
+#include <string.h>
 #include <sys/times.h>
 #include <sys/param.h>
-#include <netinet/in.h>        /* for byte ordering macros */
+#include <unistd.h>
 #include "bfd.h"
-#include "callback.h"
+#include "gdb/callback.h"
 #include "libiberty.h"
-#include "remote-sim.h"
+#include "gdb/remote-sim.h"
 
-#ifndef NUM_ELEM
-#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
-#endif
-
-
-typedef long int           word;
-typedef unsigned long int  uword;
+#include "sim-main.h"
+#include "sim-base.h"
+#include "sim-syscall.h"
+#include "sim-options.h"
 
-static unsigned long  heap_ptr = 0;
-host_callback *       callback;
+#define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
 
 
-unsigned long
-mcore_extract_unsigned_integer (addr, len)
-     unsigned char * addr;
-     int len;
+static unsigned long
+mcore_extract_unsigned_integer (unsigned char *addr, int len)
 {
   unsigned long retval;
   unsigned char * p;
   unsigned char * startaddr = (unsigned char *)addr;
   unsigned char * endaddr = startaddr + len;
+
   if (len > (int) sizeof (unsigned long))
-    printf ("That operation is not available on integers of more than %d bytes.",
+    printf ("That operation is not available on integers of more than %zu bytes.",
            sizeof (unsigned long));
+
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
   retval = 0;
 
+  if (! target_big_endian)
+    {
+      for (p = endaddr; p > startaddr;)
+       retval = (retval << 8) | * -- p;
+    }
+  else
     {
       for (p = startaddr; p < endaddr;)
        retval = (retval << 8) | * p ++;
     }
-  
+
   return retval;
 }
 
-void
-mcore_store_unsigned_integer (addr, len, val)
-     unsigned char * addr;
-     int len;
-     unsigned long val;
+static void
+mcore_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
 {
   unsigned char * p;
   unsigned char * startaddr = (unsigned char *)addr;
   unsigned char * endaddr = startaddr + len;
 
+  if (! target_big_endian)
+    {
+      for (p = startaddr; p < endaddr;)
+       {
+         * p ++ = val & 0xff;
+         val >>= 8;
+       }
+    }
+  else
     {
       for (p = endaddr; p > startaddr;)
        {
@@ -86,13 +93,14 @@ mcore_store_unsigned_integer (addr, len, val)
 }
 
 /* The machine state.
-   This state is maintained in host byte order.  The 
+   This state is maintained in host byte order.  The
    fetch/store register functions must translate between host
-   byte order and the target processor byte order.  
+   byte order and the target processor byte order.
    Keeping this data in target byte order simplifies the register
    read/write functions.  Keeping this data in native order improves
    the performance of the simulator.  Simulation speed is deemed more
-   important. */
+   important.  */
+/* TODO: Should be moved to sim-main.h:sim_cpu.  */
 
 /* The ordering of the mcore_regset structure is matched in the
    gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro.  */
@@ -101,14 +109,11 @@ struct mcore_regset
   word           gregs [16];           /* primary registers */
   word           alt_gregs [16];       /* alt register file */
   word           cregs [32];           /* control registers */
-  word           pc;                   /* the pc */
   int            ticks;
   int            stalls;
   int            cycles;
   int            insts;
   int            exception;
-  unsigned long   msize;
-  unsigned char * memory;
   word *          active_gregs;
 };
 
@@ -121,12 +126,7 @@ union
 #define LAST_VALID_CREG        32              /* only 0..12 implemented */
 #define        NUM_MCORE_REGS  (16 + 16 + LAST_VALID_CREG + 1)
 
-int memcycles = 1;
-
-static SIM_OPEN_KIND sim_kind;
-static char * myname;
-
-static int issue_messages = 0;
+static int memcycles = 1;
 
 #define gr     asregs.active_gregs
 #define cr     asregs.cregs
@@ -143,7 +143,6 @@ static int issue_messages = 0;
 #define        ss4     asregs.cregs[10]
 #define        gcr     asregs.cregs[11]
 #define        gsr     asregs.cregs[12]
-#define mem    asregs.memory
 
 /* maniuplate the carry bit */
 #define        C_ON()   (cpu.sr & 1)
@@ -162,251 +161,18 @@ static int issue_messages = 0;
 #define        PARM4   5
 #define        RET1    2               /* register for return values. */
 
-long
-int_sbrk (inc_bytes)
-     int inc_bytes;
-{
-  long addr;
-  
-  addr = heap_ptr;
-  
-  heap_ptr += inc_bytes;
-  
-  if (issue_messages && heap_ptr>cpu.gr[0])
-    fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
-  
-  return addr;
-}
-
-static void INLINE 
-wbat (x, v)
-     word x, v;
-{
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-    }
-  else
-    {
-      unsigned char *p = cpu.mem + x;
-      p[0] = v;
-    }
-}
-
-static void INLINE 
-wlat (x, v)
-     word x, v;
-{
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "word write to 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-    }
-  else
-    {
-      if ((x & 3) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-       }
-      else
-       {
-         unsigned char * p = cpu.mem + x;
-         p[0] = v >> 24;
-         p[1] = v >> 16;
-         p[2] = v >> 8;
-         p[3] = v;
-       }
-    }
-}
-
-static void INLINE 
-what (x, v)
-     word x, v;
-{
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short write to 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-    }
-  else
-    {
-      if ((x & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
-                    x);
-      
-         cpu.asregs.exception = SIGBUS;
-       }
-      else
-       {
-         unsigned char * p = cpu.mem + x;
-         p[0] = v >> 8;
-         p[1] = v;
-       }
-    }
-}
-
-/* Read functions */
-static int INLINE 
-rbat (x)
-     word x;
-{
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      unsigned char * p = cpu.mem + x;
-      return p[0];
-    }
-}
-
-static int INLINE 
-rlat (x)
-     word x;
-{
-  if (((uword) x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "word read from 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      if ((x & 3) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-         return 0;
-       }
-      else
-       {
-         unsigned char * p = cpu.mem + x;
-         return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-       }
-    }
-}
-
-static int INLINE 
-rhat (x)
-     word x;
-{
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short read from 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      if ((x & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-         return 0;
-       }
-      else
-       {
-         unsigned char * p = cpu.mem + x;
-         return (p[0] << 8) | p[1];
-       }
-    }
-}
-
-
-#define SEXTB(x)       (((x & 0xff) ^ (~ 0x7f)) + 0x80)
-#define SEXTW(y)       ((int)((short)y))
-
-static int
-IOMEM (addr, write, value)
-     int addr;
-     int write;
-     int value;
-{
-}
-
-/* default to a 8 Mbyte (== 2^23) memory space */
-static int sim_memory_size = 23;
-
-#define        MEM_SIZE_FLOOR  64
-void
-sim_size (power)
-     int power;
-{
-  sim_memory_size = power;
-  cpu.asregs.msize = 1 << sim_memory_size;
-
-  if (cpu.mem)
-    free (cpu.mem);
-
-  /* watch out for the '0 count' problem. There's probably a better
-     way.. e.g., why do we use 64 here? */
-  if (cpu.asregs.msize < 64)   /* ensure a boundary */
-    cpu.mem = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
-  else
-    cpu.mem = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
-
-  if (!cpu.mem)
-    {
-      if (issue_messages)
-       fprintf (stderr,
-                "Not enough VM for simulation of %d bytes of RAM\n",
-                cpu.asregs.msize);
-
-      cpu.asregs.msize = 1;
-      cpu.mem = (unsigned char *) calloc (1, 1);
-    }
-}
+/* Default to a 8 Mbyte (== 2^23) memory space.  */
+#define DEFAULT_MEMORY_SIZE 0x800000
 
 static void
-init_pointers ()
-{
-  if (cpu.asregs.msize != (1 << sim_memory_size))
-    sim_size (sim_memory_size);
-}
-
-static void
-set_initial_gprs ()
+set_initial_gprs (SIM_CPU *scpu)
 {
   int i;
   long space;
-  unsigned long memsize;
-  
-  init_pointers ();
 
   /* Set up machine just out of reset.  */
-  cpu.asregs.pc = 0;
+  CPU_PC_SET (scpu, 0);
   cpu.sr = 0;
-  
-  memsize = cpu.asregs.msize / (1024 * 1024);
-
-  if (issue_messages > 1)
-    fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
-            memsize, cpu.asregs.msize - 1);
 
   /* Clean out the GPRs and alternate GPRs.  */
   for (i = 0; i < 16; i++)
@@ -414,16 +180,16 @@ set_initial_gprs ()
       cpu.asregs.gregs[i] = 0;
       cpu.asregs.alt_gregs[i] = 0;
     }
-  
+
   /* Make our register set point to the right place.  */
   if (SR_AF())
     cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
   else
     cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
-  
+
   /* ABI specifies initial values for these registers.  */
-  cpu.gr[0] = cpu.asregs.msize - 4;
+  cpu.gr[0] = DEFAULT_MEMORY_SIZE - 4;
+
   /* dac fix, the stack address must be 8-byte aligned! */
   cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
   cpu.gr[PARM1] = 0;
@@ -432,169 +198,19 @@ set_initial_gprs ()
   cpu.gr[PARM4] = cpu.gr[0];
 }
 
-static void
-interrupt ()
-{
-  cpu.asregs.exception = SIGINT;
-}
-
-/* Functions so that trapped open/close don't interfere with the
-   parent's functions.  We say that we can't close the descriptors
-   that we didn't open.  exit() and cleanup() get in trouble here,
-   to some extent.  That's the price of emulation.  */
-
-unsigned char opened[100];
+/* Simulate a monitor trap.  */
 
 static void
-log_open (fd)
-    int fd;
+handle_trap1 (SIM_DESC sd)
 {
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return;
-  
-  opened[fd] = 1;
+  /* XXX: We don't pass back the actual errno value.  */
+  cpu.gr[RET1] = sim_syscall (STATE_CPU (sd, 0), cpu.gr[TRAPCODE],
+                             cpu.gr[PARM1], cpu.gr[PARM2], cpu.gr[PARM3],
+                             cpu.gr[PARM4]);
 }
 
 static void
-log_close (fd)
-     int fd;
-{
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return;
-  
-  opened[fd] = 0;
-}
-
-static int
-is_opened (fd)
-    int fd;
-{
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return 0;
-
-  return opened[fd];
-}
-
-static void
-handle_trap1 ()
-{
-  unsigned long a[3];
-
-  switch ((unsigned long) (cpu.gr [TRAPCODE]))
-    {
-    case 3:
-      a[0] = (unsigned long) (cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
-      a[2] = (unsigned long) (cpu.gr[PARM3]);
-      cpu.gr[RET1] = callback->read (callback, a[0], (char *) a[1], a[2]);
-      break;
-      
-    case 4:
-      a[0] = (unsigned long) (cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
-      a[2] = (unsigned long) (cpu.gr[PARM3]);
-      cpu.gr[RET1] = (int)callback->write (callback, a[0], (char *) a[1], a[2]);
-      break;
-      
-    case 5:
-      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.gr[PARM2]);
-      /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
-      cpu.gr[RET1] = callback->open (callback, (char *) a[0], a[1]);
-      log_open (cpu.gr[RET1]);
-      break;
-      
-    case 6:
-      a[0] = (unsigned long) (cpu.gr[4]);
-      /* Watch out for debugger's files. */
-      if (is_opened (a[0]))
-       {
-         log_close (a[0]);
-         cpu.gr[RET1] = callback->close (callback, a[0]);
-       }
-      else
-       {
-         /* Don't let him close it.  */
-         cpu.gr[RET1] = (-1);
-       }
-      break;
-      
-    case 9:
-      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
-      cpu.gr[RET1] = link ((char *) a[0], (char *) a[1]);
-      break;
-      
-    case 10:
-      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
-      cpu.gr[RET1] = callback->unlink (callback, (char *) a[0]);
-      break;
-      
-    case 13:
-      /* handle time(0) vs time(&var) */
-      a[0] = (unsigned long) (cpu.gr[PARM1]);
-      if (a[0])
-       a[0] += (unsigned long) cpu.mem;
-      cpu.gr[RET1] = callback->time (callback, (time_t *) a[0]);
-      break;
-      
-    case 19:
-      a[0] = (unsigned long) (cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.gr[PARM2]);
-      a[2] = (unsigned long) (cpu.gr[PARM3]);
-      cpu.gr[RET1] = callback->lseek (callback, a[0], a[1], a[2]);
-      break;
-      
-    case 33:
-      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
-      a[1] = (unsigned long) (cpu.gr[PARM2]);
-      cpu.gr[RET1] = access ((char *) a[0], a[1]);
-      break;
-      
-    case 43:
-      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
-#if 0
-      cpu.gr[RET1] = times ((char *)a[0]);
-#else
-      {
-       /* Give him simulated cycles for utime
-          and an instruction count for stime. */
-       struct tms
-       {
-         time_t tms_utime;
-         time_t tms_stime;
-         time_t tms_cutime;
-         time_t tms_cstime;
-       } t;
-
-       t.tms_utime = cpu.asregs.cycles;
-       t.tms_stime = cpu.asregs.insts;
-       t.tms_cutime = t.tms_utime;
-       t.tms_cstime = t.tms_stime;
-                           
-       memcpy ((struct tms *)(a[0]), &t, sizeof (t));
-                           
-       cpu.gr[RET1] = cpu.asregs.cycles;
-      }
-#endif
-      break;
-      
-    case 69:
-      a[0] = (unsigned long) (cpu.gr[PARM1]);
-      cpu.gr[RET1] = int_sbrk (a[0]);
-      break;
-      
-    default:
-      if (issue_messages)
-       fprintf (stderr, "WARNING: sys call %d unimplemented\n",
-                cpu.gr[TRAPCODE]);
-      break;
-    }
-}
-
-static void
-process_stub (what)
-     int what;
+process_stub (SIM_DESC sd, int what)
 {
   /* These values should match those in libgloss/mcore/syscalls.s.  */
   switch (what)
@@ -607,19 +223,18 @@ process_stub (what)
     case 19: /* _lseek */
     case 43: /* _times */
       cpu.gr [TRAPCODE] = what;
-      handle_trap1 ();
+      handle_trap1 (sd);
       break;
-      
+
     default:
-      if (issue_messages)
+      if (STATE_VERBOSE_P (sd))
        fprintf (stderr, "Unhandled stub opcode: %d\n", what);
       break;
     }
 }
 
 static void
-util (what)
-     unsigned what;
+util (SIM_DESC sd, unsigned what)
 {
   switch (what)
     {
@@ -628,58 +243,36 @@ util (what)
       break;
 
     case 1:    /* printf */
-      {
-       unsigned long a[6];
-       unsigned char *s;
-       int i;
-
-       a[0] = (unsigned long)(cpu.mem + cpu.gr[PARM1]);
-
-       for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
-         {
-           if (*s == '%')
-             {
-               if (*++s == 's')
-                 a[i] = (unsigned long)(cpu.mem + cpu.gr[PARM1+i]);
-               else
-                 a[i] = cpu.gr[i+PARM1];
-               i++;
-             }
-         }
-       
-       cpu.gr[RET1] = printf ((char *)a[0], a[1], a[2], a[3], a[4], a[5]);
-      }
+      if (STATE_VERBOSE_P (sd))
+       fprintf (stderr, "WARNING: printf unimplemented\n");
       break;
-      
+
     case 2:    /* scanf */
-      if (issue_messages)
+      if (STATE_VERBOSE_P (sd))
        fprintf (stderr, "WARNING: scanf unimplemented\n");
       break;
-      
+
     case 3:    /* utime */
       cpu.gr[RET1] = cpu.asregs.insts;
       break;
 
     case 0xFF:
-      process_stub (cpu.gr[1]);
+      process_stub (sd, cpu.gr[1]);
       break;
-      
+
     default:
-      if (issue_messages)
+      if (STATE_VERBOSE_P (sd))
        fprintf (stderr, "Unhandled util code: %x\n", what);
       break;
     }
-}      
+}
 
 /* For figuring out whether we carried; addc/subc use this. */
 static int
-iu_carry (a, b, cin)
-     unsigned long a;
-     unsigned long b;
-     int cin;
+iu_carry (unsigned long a, unsigned long b, int cin)
 {
   unsigned long        x;
-  
+
   x = (a & 0xffff) + (b & 0xffff) + cin;
   x = (x >> 16) + (a >> 16) + (b >> 16);
   x >>= 16;
@@ -687,7 +280,8 @@ iu_carry (a, b, cin)
   return (x != 0);
 }
 
-#define WATCHFUNCTIONS 1
+/* TODO: Convert to common watchpoints.  */
+#undef WATCHFUNCTIONS
 #ifdef WATCHFUNCTIONS
 
 #define MAXWL 80
@@ -711,28 +305,34 @@ int WLW;
 #define IMM5   ((inst >> 4) & 0x1F)
 #define IMM4   ((inst) & 0xF)
 
+#define rbat(X)        sim_core_read_1 (scpu, 0, read_map, X)
+#define rhat(X)        sim_core_read_2 (scpu, 0, read_map, X)
+#define rlat(X)        sim_core_read_4 (scpu, 0, read_map, X)
+#define wbat(X, D) sim_core_write_1 (scpu, 0, write_map, X, D)
+#define what(X, D) sim_core_write_2 (scpu, 0, write_map, X, D)
+#define wlat(X, D) sim_core_write_4 (scpu, 0, write_map, X, D)
+
 static int tracing = 0;
 
 void
-sim_resume (sd, step, siggnal)
-     SIM_DESC sd;
-     int step, siggnal;
+sim_resume (SIM_DESC sd, int step, int siggnal)
 {
+  SIM_CPU *scpu = STATE_CPU (sd, 0);
   int needfetch;
   word ibuf;
   word pc;
   unsigned short inst;
-  void (* sigsave)();
   int memops;
   int bonus_cycles;
   int insts;
   int w;
   int cycs;
+#ifdef WATCHFUNCTIONS
   word WLhash;
+#endif
 
-  sigsave = signal (SIGINT, interrupt);
   cpu.asregs.exception = step ? SIGTRAP: 0;
-  pc = cpu.asregs.pc;
+  pc = CPU_PC_GET (scpu);
 
   /* Fetch the initial instructions that we'll decode. */
   ibuf = rlat (pc & 0xFFFFFFFC);
@@ -741,65 +341,73 @@ sim_resume (sd, step, siggnal)
   memops = 0;
   bonus_cycles = 0;
   insts = 0;
-  
+
   /* make our register set point to the right place */
   if (SR_AF ())
     cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
   else
     cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
-  
+
+#ifdef WATCHFUNCTIONS
   /* make a hash to speed exec loop, hope it's nonzero */
   WLhash = 0xFFFFFFFF;
 
   for (w = 1; w <= ENDWL; w++)
     WLhash = WLhash & WL[w];
+#endif
 
   do
     {
       word oldpc;
-      
+
       insts ++;
-      
+
       if (pc & 02)
        {
+         if (! target_big_endian)
+           inst = ibuf >> 16;
+         else
            inst = ibuf & 0xFFFF;
          needfetch = 1;
        }
       else
        {
+         if (! target_big_endian)
+           inst = ibuf & 0xFFFF;
+         else
            inst = ibuf >> 16;
        }
 
 #ifdef WATCHFUNCTIONS
       /* now scan list of watch addresses, if match, count it and
         note return address and count cycles until pc=return address */
-      
+
       if ((WLincyc == 1) && (pc == WLendpc))
        {
          cycs = (cpu.asregs.cycles + (insts + bonus_cycles +
                                       (memops * memcycles)) - WLbcyc);
-         
+
          if (WLcnts[WLW] == 1)
            {
              WLmax[WLW] = cycs;
              WLmin[WLW] = cycs;
              WLcyc[WLW] = 0;
            }
-         
+
          if (cycs > WLmax[WLW])
            {
              WLmax[WLW] = cycs;
            }
-         
+
          if (cycs < WLmin[WLW])
            {
              WLmin[WLW] = cycs;
            }
-         
+
          WLcyc[WLW] += cycs;
          WLincyc = 0;
          WLendpc = 0;
-       } 
+       }
 
       /* Optimize with a hash to speed loop.  */
       if (WLincyc == 0)
@@ -811,7 +419,7 @@ sim_resume (sd, step, siggnal)
                  if (pc == WL[w])
                    {
                      WLcnts[w]++;
-                     WLbcyc = cpu.asregs.cycles + insts 
+                     WLbcyc = cpu.asregs.cycles + insts
                        + bonus_cycles + (memops * memcycles);
                      WLendpc = cpu.gr[15];
                      WLincyc = 1;
@@ -824,12 +432,12 @@ sim_resume (sd, step, siggnal)
 #endif
 
       if (tracing)
-       fprintf (stderr, "%.4x: inst = %.4x ", pc, inst);
+       fprintf (stderr, "%.4lx: inst = %.4x ", pc, inst);
 
       oldpc = pc;
-      
+
       pc += 2;
-      
+
       switch (inst >> 8)
        {
        case 0x00:
@@ -842,15 +450,15 @@ sim_resume (sd, step, siggnal)
                  cpu.asregs.exception = SIGTRAP;
                  pc -= 2;
                  break;
-                 
+
                case 0x1:                               /* sync */
                  break;
-                 
+
                case 0x2:                               /* rte */
                  pc = cpu.epc;
                  cpu.sr = cpu.esr;
                  needfetch = 1;
-                 
+
                  if (SR_AF ())
                    cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
                  else
@@ -867,52 +475,52 @@ sim_resume (sd, step, siggnal)
                  else
                    cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
                  break;
-                 
+
                case 0x4:                               /* stop */
-                 if (issue_messages)
+                 if (STATE_VERBOSE_P (sd))
                    fprintf (stderr, "WARNING: stop unimplemented\n");
                  break;
-                   
+
                case 0x5:                               /* wait */
-                 if (issue_messages)
+                 if (STATE_VERBOSE_P (sd))
                    fprintf (stderr, "WARNING: wait unimplemented\n");
                  break;
-                   
+
                case 0x6:                               /* doze */
-                 if (issue_messages)
+                 if (STATE_VERBOSE_P (sd))
                    fprintf (stderr, "WARNING: doze unimplemented\n");
                  break;
-                   
+
                case 0x7:
                  cpu.asregs.exception = SIGILL;        /* illegal */
                  break;
-                   
+
                case 0x8:                               /* trap 0 */
                case 0xA:                               /* trap 2 */
                case 0xB:                               /* trap 3 */
                  cpu.asregs.exception = SIGTRAP;
                  break;
-                   
+
                case 0xC:                               /* trap 4 */
                case 0xD:                               /* trap 5 */
                case 0xE:                               /* trap 6 */
                  cpu.asregs.exception = SIGILL;        /* illegal */
                  break;
-                 
+
                case 0xF:                               /* trap 7 */
                  cpu.asregs.exception = SIGTRAP;       /* integer div-by-0 */
                  break;
-                   
+
                case 0x9:                               /* trap 1 */
-                 handle_trap1 ();
+                 handle_trap1 (sd);
                  break;
                }
              break;
-             
+
            case 0x1:
              cpu.asregs.exception = SIGILL;            /* illegal */
              break;
-             
+
            case 0x2:                                   /* mvc */
              cpu.gr[RD] = C_VALUE();
              break;
@@ -921,9 +529,9 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x4:                                   /* ldq */
              {
-               char *addr = (char *)cpu.gr[RD];
+               word addr = cpu.gr[RD];
                int regno = 4;                  /* always r4-r7 */
-               
+
                bonus_cycles++;
                memops += 4;
                do
@@ -937,9 +545,9 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x5:                                   /* stq */
              {
-               char *addr = (char *)cpu.gr[RD];
+               word addr = cpu.gr[RD];
                int regno = 4;                  /* always r4-r7 */
-               
+
                memops += 4;
                bonus_cycles++;
                do
@@ -953,12 +561,12 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x6:                                   /* ldm */
              {
-               char *addr = (char *)cpu.gr[0];
+               word addr = cpu.gr[0];
                int regno = RD;
-               
+
                /* bonus cycle is really only needed if
                   the next insn shifts the last reg loaded.
-                  
+
                   bonus_cycles++;
                */
                memops += 16-regno;
@@ -972,9 +580,9 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x7:                                   /* stm */
              {
-               char *addr = (char *)cpu.gr[0];
+               word addr = cpu.gr[0];
                int regno = RD;
-               
+
                /* this should be removed! */
                /*  bonus_cycles ++; */
 
@@ -1003,7 +611,7 @@ sim_resume (sd, step, siggnal)
            case 0xC:                                   /* jmp */
              pc = cpu.gr[RD];
              if (tracing && RD == 15)
-               fprintf (stderr, "Func return, r2 = %x, r3 = %x\n",
+               fprintf (stderr, "Func return, r2 = %lxx, r3 = %lx\n",
                         cpu.gr[2], cpu.gr[3]);
              bonus_cycles++;
              needfetch = 1;
@@ -1039,7 +647,7 @@ sim_resume (sd, step, siggnal)
        case 0x01:
          switch RS
            {
-           case 0x0:                                   /* xtrb3 */     
+           case 0x0:                                   /* xtrb3 */
              cpu.gr[1] = (cpu.gr[RD]) & 0xFF;
              NEW_C (cpu.gr[RD] != 0);
              break;
@@ -1079,7 +687,7 @@ sim_resume (sd, step, siggnal)
                cpu.gr[RD] = tmp;
              }
              break;
-           case 0x8:                                   /* declt */ 
+           case 0x8:                                   /* declt */
              --cpu.gr[RD];
              NEW_C ((long)cpu.gr[RD] < 0);
              break;
@@ -1090,7 +698,7 @@ sim_resume (sd, step, siggnal)
                       (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 &&
                       (tmp & 0x000000FF) != 0);
              }
-             break; 
+             break;
            case 0xA:                                   /* decgt */
              --cpu.gr[RD];
              NEW_C ((long)cpu.gr[RD] > 0);
@@ -1125,13 +733,13 @@ sim_resume (sd, step, siggnal)
          {
            unsigned int t = cpu.gr[RS];
            int ticks;
-           for (ticks = 0; t != 0 ; t >>= 2) 
+           for (ticks = 0; t != 0 ; t >>= 2)
              ticks++;
            bonus_cycles += ticks;
          }
          bonus_cycles += 2;  /* min. is 3, so add 2, plus ticks above */
          if (tracing)
-           fprintf (stderr, "  mult %x by %x to give %x",
+           fprintf (stderr, "  mult %lx by %lx to give %lx",
                     cpu.gr[RD], cpu.gr[RS], cpu.gr[RD] * cpu.gr[RS]);
          cpu.gr[RD] = cpu.gr[RD] * cpu.gr[RS];
          break;
@@ -1144,7 +752,7 @@ sim_resume (sd, step, siggnal)
            }
          --cpu.gr[RS];                         /* not RD! */
          NEW_C (((long)cpu.gr[RS]) > 0);
-         break; 
+         break;
        case 0x05:                                      /* subu */
          cpu.gr[RD] -= cpu.gr[RS];
          break;
@@ -1177,16 +785,18 @@ sim_resume (sd, step, siggnal)
            cpu.gr[RD] = cpu.gr[RS];
          break;
        case 0x0B:                                      /* lsr */
-         { 
+         {
            unsigned long dst, src;
            dst = cpu.gr[RD];
            src = cpu.gr[RS];
-           dst = dst >> src;   
+           /* We must not rely solely upon the native shift operations, since they
+              may not match the M*Core's behaviour on boundary conditions.  */
+           dst = src > 31 ? 0 : dst >> src;
            cpu.gr[RD] = dst;
          }
          break;
        case 0x0C:                                      /* cmphs */
-         NEW_C ((unsigned long )cpu.gr[RD] >= 
+         NEW_C ((unsigned long )cpu.gr[RD] >=
                 (unsigned long)cpu.gr[RS]);
          break;
        case 0x0D:                                      /* cmplt */
@@ -1212,7 +822,7 @@ sim_resume (sd, step, siggnal)
        case 0x12:                                      /* mov */
          cpu.gr[RD] = cpu.gr[RS];
          if (tracing)
-           fprintf (stderr, "MOV %x into reg %d", cpu.gr[RD], RD);
+           fprintf (stderr, "MOV %lx into reg %d", cpu.gr[RD], RD);
          break;
 
        case 0x13:                                      /* bgenr */
@@ -1246,7 +856,7 @@ sim_resume (sd, step, siggnal)
              cpu.cr[r] = cpu.gr[RD];
            else
              cpu.asregs.exception = SIGILL;
-           
+
            /* we might have changed register sets... */
            if (SR_AF ())
              cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
@@ -1256,11 +866,18 @@ sim_resume (sd, step, siggnal)
          break;
 
        case 0x1A:                                      /* asr */
-         cpu.gr[RD] = (long)cpu.gr[RD] >> cpu.gr[RS];
+         /* We must not rely solely upon the native shift operations, since they
+            may not match the M*Core's behaviour on boundary conditions.  */
+         if (cpu.gr[RS] > 30)
+           cpu.gr[RD] = ((long) cpu.gr[RD]) < 0 ? -1 : 0;
+         else
+           cpu.gr[RD] = (long) cpu.gr[RD] >> cpu.gr[RS];
          break;
 
        case 0x1B:                                      /* lsl */
-         cpu.gr[RD] = cpu.gr[RD] << cpu.gr[RS];
+         /* We must not rely solely upon the native shift operations, since they
+            may not match the M*Core's behaviour on boundary conditions.  */
+         cpu.gr[RD] = cpu.gr[RS] > 31 ? 0 : cpu.gr[RD] << cpu.gr[RS];
          break;
 
        case 0x1C:                                      /* addu */
@@ -1316,11 +933,11 @@ sim_resume (sd, step, siggnal)
              CLR_C();
            }
          break;
-         
+
        case 0x2C: case 0x2D:                           /* bmaski, divu */
          {
            unsigned imm = IMM5;
-           
+
            if (imm == 1)
              {
                int exe;
@@ -1333,7 +950,7 @@ sim_resume (sd, step, siggnal)
 
                /* unsigned divide */
                cpu.gr[RD] = (word) ((unsigned int) cpu.gr[RD] / (unsigned int)cpu.gr[1] );
-               
+
                /* compute bonus_cycles for divu */
                for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++)
                  r1 = r1 << 1;
@@ -1380,34 +997,34 @@ sim_resume (sd, step, siggnal)
                int exe,sc;
                int rxnlz, r1nlz;
                signed int rx, r1;
-               
+
                /* compute bonus_cycles for divu */
                rx = cpu.gr[RD];
                r1 = cpu.gr[1];
                exe = 0;
-               
+
                if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0)))
                  sc = 1;
                else
                  sc = 0;
-               
+
                rx = abs (rx);
                r1 = abs (r1);
-               
+
                /* signed divide, general registers are of type int, so / op is OK */
                cpu.gr[RD] = cpu.gr[RD] / cpu.gr[1];
-             
+
                for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ )
                  r1 = r1 << 1;
-               
+
                for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ )
                  rx = rx << 1;
-               
+
                if (r1nlz < rxnlz)
                  exe += 5;
                else
                  exe += 6 + r1nlz - rxnlz + sc;
-               
+
                if (exe >= (2 * memcycles - 1))
                  {
                    bonus_cycles += exe - (2 * memcycles) + 1;
@@ -1492,7 +1109,7 @@ sim_resume (sd, step, siggnal)
          cpu.asregs.exception = SIGILL;
          break;
        case 0x50:
-         util (inst & 0xFF); 
+         util (sd, inst & 0xFF);
          break;
        case 0x51: case 0x52: case 0x53:
        case 0x54: case 0x55: case 0x56: case 0x57:
@@ -1514,7 +1131,7 @@ sim_resume (sd, step, siggnal)
        case 0x7C: case 0x7D: case 0x7E:                /* lrw */
          cpu.gr[RX] =  rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
          if (tracing)
-           fprintf (stderr, "LRW of 0x%x from 0x%x to reg %d",
+           fprintf (stderr, "LRW of 0x%x from 0x%lx to reg %d",
                     rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC),
                     (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX);
          memops++;
@@ -1522,7 +1139,8 @@ sim_resume (sd, step, siggnal)
        case 0x7F:                                      /* jsri */
          cpu.gr[15] = pc;
          if (tracing)
-           fprintf (stderr, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
+           fprintf (stderr,
+                    "func call: r2 = %lx r3 = %lx r4 = %lx r5 = %lx r6 = %lx r7 = %lx\n",
                     cpu.gr[2], cpu.gr[3], cpu.gr[4], cpu.gr[5], cpu.gr[6], cpu.gr[7]);
        case 0x70:                                      /* jmpi */
          pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
@@ -1537,7 +1155,7 @@ sim_resume (sd, step, siggnal)
        case 0x8C: case 0x8D: case 0x8E: case 0x8F:     /* ld */
          cpu.gr[RX] = rlat (cpu.gr[RD] + ((inst >> 2) & 0x003C));
          if (tracing)
-           fprintf (stderr, "load reg %d from 0x%x with 0x%x",
+           fprintf (stderr, "load reg %d from 0x%lx with 0x%lx",
                     RX,
                     cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
          memops++;
@@ -1548,7 +1166,7 @@ sim_resume (sd, step, siggnal)
        case 0x9C: case 0x9D: case 0x9E: case 0x9F:     /* st */
          wlat (cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
          if (tracing)
-           fprintf (stderr, "store reg %d (containing 0x%x) to 0x%x",
+           fprintf (stderr, "store reg %d (containing 0x%lx) to 0x%lx",
                     RX, cpu.gr[RX],
                     cpu.gr[RD] + ((inst >> 2) & 0x003C));
          memops++;
@@ -1582,7 +1200,7 @@ sim_resume (sd, step, siggnal)
          memops++;
          break;
        case 0xE8: case 0xE9: case 0xEA: case 0xEB:
-       case 0xEC: case 0xED: case 0xEE: case 0xEF:     /* bf */        
+       case 0xEC: case 0xED: case 0xEE: case 0xEF:     /* bf */
          if (C_OFF())
            {
              int disp;
@@ -1609,7 +1227,7 @@ sim_resume (sd, step, siggnal)
          break;
 
        case 0xF8: case 0xF9: case 0xFA: case 0xFB:
-       case 0xFC: case 0xFD: case 0xFE: case 0xFF:     /* bsr */       
+       case 0xFC: case 0xFD: case 0xFE: case 0xFF:     /* bsr */
          cpu.gr[15] = pc;
        case 0xF0: case 0xF1: case 0xF2: case 0xF3:
        case 0xF4: case 0xF5: case 0xF6: case 0xF7:     /* br */
@@ -1629,82 +1247,31 @@ sim_resume (sd, step, siggnal)
       if (tracing)
        fprintf (stderr, "\n");
 
-      if (needfetch)   
+      if (needfetch)
        {
-         /* Do not let him fetch from a bad address! */
-         if (((uword)pc) >= cpu.asregs.msize)
-           {
-             if (issue_messages)
-               fprintf (stderr, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc, pc);
-             
-             cpu.asregs.exception = SIGSEGV;
-           }
-         else
-           {
-             ibuf = rlat (pc & 0xFFFFFFFC);
-             needfetch = 0;
-           }
+         ibuf = rlat (pc & 0xFFFFFFFC);
+         needfetch = 0;
        }
     }
   while (!cpu.asregs.exception);
 
   /* Hide away the things we've cached while executing.  */
-  cpu.asregs.pc = pc;
+  CPU_PC_SET (scpu, pc);
   cpu.asregs.insts += insts;           /* instructions done ... */
   cpu.asregs.cycles += insts;          /* and each takes a cycle */
   cpu.asregs.cycles += bonus_cycles;   /* and extra cycles for branches */
   cpu.asregs.cycles += memops * memcycles;     /* and memop cycle delays */
-  
-  signal (SIGINT, sigsave);
-}
-
-
-int
-sim_write (sd, addr, buffer, size)
-     SIM_DESC sd;
-     SIM_ADDR addr;
-     unsigned char * buffer;
-     int size;
-{
-  int i;
-  init_pointers ();
-  
-  memcpy (& cpu.mem[addr], buffer, size);
-  
-  return size;
 }
 
 int
-sim_read (sd, addr, buffer, size)
-     SIM_DESC sd;
-     SIM_ADDR addr;
-     unsigned char * buffer;
-     int size;
+sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 {
-  int i;
-  init_pointers ();
-  
-  memcpy (buffer, & cpu.mem[addr], size);
-  
-  return size;
-}
-
-
-int
-sim_store_register (sd, rn, memory, length)
-     SIM_DESC sd;
-     int rn;
-     unsigned char * memory;
-     int length;
-{
-  init_pointers ();
-
   if (rn < NUM_MCORE_REGS && rn >= 0)
     {
       if (length == 4)
        {
          long ival;
-         
+
          /* misalignment safe */
          ival = mcore_extract_unsigned_integer (memory, 4);
          cpu.asints[rn] = ival;
@@ -1717,14 +1284,8 @@ sim_store_register (sd, rn, memory, length)
 }
 
 int
-sim_fetch_register (sd, rn, memory, length)
-     SIM_DESC sd;
-     int rn;
-     unsigned char * memory;
-     int length;
+sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 {
-  init_pointers ();
-  
   if (rn < NUM_MCORE_REGS && rn >= 0)
     {
       if (length == 4)
@@ -1734,32 +1295,15 @@ sim_fetch_register (sd, rn, memory, length)
          /* misalignment-safe */
          mcore_store_unsigned_integer (memory, 4, ival);
        }
-      
+
       return 4;
     }
   else
     return 0;
 }
 
-
-int
-sim_trace (sd)
-     SIM_DESC sd;
-{
-  tracing = 1;
-  
-  sim_resume (sd, 0, 0);
-
-  tracing = 0;
-  
-  return 1;
-}
-
 void
-sim_stop_reason (sd, reason, sigrc)
-     SIM_DESC sd;
-     enum sim_stop * reason;
-     int * sigrc;
+sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
 {
   if (cpu.asregs.exception == SIGQUIT)
     {
@@ -1773,25 +1317,14 @@ sim_stop_reason (sd, reason, sigrc)
     }
 }
 
-
-int
-sim_stop (sd)
-     SIM_DESC sd;
-{
-  cpu.asregs.exception = SIGINT;
-  return 1;
-}
-
-
 void
-sim_info (sd, verbose)
-     SIM_DESC sd;
-     int verbose;
+sim_info (SIM_DESC sd, int verbose)
 {
 #ifdef WATCHFUNCTIONS
   int w, wcyc;
 #endif
   double virttime = cpu.asregs.cycles / 36.0e6;
+  host_callback *callback = STATE_CALLBACK (sd);
 
   callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
                             cpu.asregs.insts);
@@ -1807,156 +1340,122 @@ sim_info (sd, verbose)
                             ENDWL);
 
   wcyc = 0;
-  
+
   for (w = 1; w <= ENDWL; w++)
     {
       callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
       callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
                                 WLcnts[w],WLcyc[w]);
-      
+
       if (WLcnts[w] != 0)
        callback->printf_filtered (callback,
                                   "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
                                   WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
       wcyc += WLcyc[w];
     }
-  
+
   callback->printf_filtered (callback,
                             "Total cycles for watched functions: %d\n",wcyc);
 #endif
 }
 
-struct aout
+static sim_cia
+mcore_pc_get (sim_cpu *cpu)
 {
-  unsigned char  sa_machtype[2];
-  unsigned char  sa_magic[2];
-  unsigned char  sa_tsize[4];
-  unsigned char  sa_dsize[4];
-  unsigned char  sa_bsize[4];
-  unsigned char  sa_syms[4];
-  unsigned char  sa_entry[4];
-  unsigned char  sa_trelo[4];
-  unsigned char  sa_drelo[4];
-} aout;
-
-#define        LONG(x)         (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-#define        SHORT(x)        (((x)[0]<<8)|(x)[1])
+  return cpu->pc;
+}
 
-SIM_DESC
-sim_open (kind, cb, abfd, argv)
-     SIM_OPEN_KIND kind;
-     host_callback * cb;
-     struct _bfd * abfd;
-     char ** argv;
+static void
+mcore_pc_set (sim_cpu *cpu, sim_cia pc)
 {
-  int osize = sim_memory_size;
-  myname = argv[0];
-  callback = cb;
-  
-  if (kind == SIM_OPEN_STANDALONE)
-    issue_messages = 1;
-  
-  /* Discard and reacquire memory -- start with a clean slate.  */
-  sim_size (1);                /* small */
-  sim_size (osize);    /* and back again */
-
-  set_initial_gprs (); /* Reset the GPR registers.  */
-  
-  /* Fudge our descriptor for now.  */
-  return (SIM_DESC) 1;
+  cpu->pc = pc;
 }
 
-void
-sim_close (sd, quitting)
-     SIM_DESC sd;
-     int quitting;
+static void
+free_state (SIM_DESC sd)
 {
-  /* nothing to do */
+  if (STATE_MODULES (sd) != NULL)
+    sim_module_uninstall (sd);
+  sim_cpu_free_all (sd);
+  sim_state_free (sd);
 }
 
-SIM_RC
-sim_load (sd, prog, abfd, from_tty)
-     SIM_DESC sd;
-     char * prog;
-     bfd * abfd;
-     int from_tty;
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
 {
-  /* Do the right thing for ELF executables; this turns out to be
-     just about the right thing for any object format that:
-       - we crack using BFD routines
-       - follows the traditional UNIX text/data/bss layout
-       - calls the bss section ".bss".   */
-
-  extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
-  bfd * prog_bfd;
-
-  {
-    bfd * handle;
-    asection * s_bss;
-    handle = bfd_openr (prog, 0);      /* could be "mcore" */
-    
-    if (!handle)
-      {
-       printf("``%s'' could not be opened.\n", prog);
-       return SIM_RC_FAIL;
-      }
-    
-    /* Makes sure that we have an object file, also cleans gets the 
-       section headers in place.  */
-    if (!bfd_check_format (handle, bfd_object))
-      {
-       /* wasn't an object file */
-       bfd_close (handle);
-       printf ("``%s'' is not appropriate object file.\n", prog);
-       return SIM_RC_FAIL;
-      }
-
-    /* Look for that bss section.  */
-    s_bss = bfd_get_section_by_name (handle, ".bss");
-    
-    if (!s_bss)
-      {
-       printf("``%s'' has no bss section.\n", prog);
-       return SIM_RC_FAIL;
-      }
-
-    /* Appropriately paranoid would check that we have
-       a traditional text/data/bss ordering within memory.  */
-
-    /* figure the end of the bss section */
-#if 0
-    printf ("bss section at 0x%08x for 0x%08x bytes\n",
-       (unsigned long) s_bss->vma , (unsigned long) s_bss->_cooked_size);
-#endif
-    heap_ptr = (unsigned long) s_bss->vma + (unsigned long) s_bss->_cooked_size;
-
-    /* Clean up after ourselves.  */
-    bfd_close (handle);
-    
-    /* XXX: do we need to free the s_bss and handle structures? */
-  }
-
-  /* from sh -- dac */
-  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
-                            sim_kind == SIM_OPEN_DEBUG,
-                            0, sim_write);
-  if (prog_bfd == NULL)
-    return SIM_RC_FAIL;
-  
-    
-  if (abfd == NULL)
-    bfd_close (prog_bfd);
+  int i;
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
 
-  return SIM_RC_OK;
+  /* The cpu data is kept in a separately allocated chunk of memory.  */
+  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  /* getopt will print the error message so we just have to exit if this fails.
+     FIXME: Hmmm...  in the case of gdb we need getopt to call
+     print_filtered.  */
+  if (sim_parse_args (sd, argv) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  /* Check for/establish the a reference program image.  */
+  if (sim_analyze_program (sd,
+                          (STATE_PROG_ARGV (sd) != NULL
+                           ? *STATE_PROG_ARGV (sd)
+                           : NULL), abfd) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  /* Configure/verify the target byte order and other runtime
+     configuration options.  */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  if (sim_post_argv_init (sd) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* CPU specific initialization.  */
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    {
+      SIM_CPU *cpu = STATE_CPU (sd, i);
+
+      CPU_PC_FETCH (cpu) = mcore_pc_get;
+      CPU_PC_STORE (cpu) = mcore_pc_set;
+
+      set_initial_gprs (cpu);  /* Reset the GPR registers.  */
+    }
+
+  /* Default to a 8 Mbyte (== 2^23) memory space.  */
+  sim_do_commandf (sd, "memory-size %#x", DEFAULT_MEMORY_SIZE);
+
+  return sd;
 }
 
 SIM_RC
-sim_create_inferior (sd, prog_bfd, argv, env)
-     SIM_DESC sd;
-     struct _bfd * prog_bfd;
-     char ** argv;
-     char ** env;
+sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
 {
+  SIM_CPU *scpu = STATE_CPU (sd, 0);
   char ** avp;
   int nargs = 0;
   int nenv = 0;
@@ -1968,13 +1467,10 @@ sim_create_inferior (sd, prog_bfd, argv, env)
 
 
   /* Set the initial register set.  */
-  l = issue_messages;
-  issue_messages = 0;
-  set_initial_gprs ();
-  issue_messages = l;
-  
-  hi_stack = cpu.asregs.msize - 4;
-  cpu.asregs.pc = bfd_get_start_address (prog_bfd);
+  set_initial_gprs (scpu);
+
+  hi_stack = DEFAULT_MEMORY_SIZE - 4;
+  CPU_PC_SET (scpu, bfd_get_start_address (prog_bfd));
 
   /* Calculate the argument and environment strings.  */
   s_length = 0;
@@ -2025,14 +1521,14 @@ sim_create_inferior (sd, prog_bfd, argv, env)
 
          /* Copy the string.  */
          l = strlen (* avp) + 1;
-         strcpy ((char *)(cpu.mem + strings), *avp);
+         sim_core_write_buffer (sd, scpu, write_map, *avp, strings, l);
 
          /* Bump the pointers.  */
          avp++;
          pointers += 4;
          strings += l+1;
        }
-      
+
       /* A null to finish the list.  */
       wlat (pointers, 0);
       pointers += 4;
@@ -2048,7 +1544,7 @@ sim_create_inferior (sd, prog_bfd, argv, env)
     {
       cpu.gr[PARM3] = pointers;
       avp = env;
-      
+
       while (avp && *avp)
        {
          /* Save where we're putting it.  */
@@ -2056,103 +1552,18 @@ sim_create_inferior (sd, prog_bfd, argv, env)
 
          /* Copy the string.  */
          l = strlen (* avp) + 1;
-         strcpy ((char *)(cpu.mem + strings), *avp);
+         sim_core_write_buffer (sd, scpu, write_map, *avp, strings, l);
 
          /* Bump the pointers.  */
          avp++;
          pointers += 4;
          strings += l+1;
        }
-      
+
       /* A null to finish the list.  */
       wlat (pointers, 0);
       pointers += 4;
     }
-  
-  return SIM_RC_OK;
-}
-
-void
-sim_kill (sd)
-     SIM_DESC sd;
-{
-  /* nothing to do */
-}
-
-void
-sim_do_command (sd, cmd)
-     SIM_DESC sd;
-     char * cmd;
-{
-  /* Nothing there yet; it's all an error.  */
-  
-  if (cmd != NULL)
-    {
-      char ** simargv = buildargv (cmd);
-      
-      if (strcmp (simargv[0], "watch") == 0)
-       {
-         if ((simargv[1] == NULL) || (simargv[2] == NULL))
-           {
-             fprintf (stderr, "Error: missing argument to watch cmd.\n");
-             return;
-           }
-         
-         ENDWL++;
-         
-         WL[ENDWL] = strtol (simargv[2], NULL, 0);
-         WLstr[ENDWL] = strdup (simargv[1]);
-         fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
-                  WL[ENDWL], ENDWL);
-
-       }
-      else if (strcmp (simargv[0], "dumpmem") == 0)
-       {
-         unsigned char * p;
-         FILE * dumpfile;
-
-         if (simargv[1] == NULL)
-           fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
-
-         fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
-         
-         dumpfile = fopen (simargv[1], "w");
-         p = cpu.mem;
-         fwrite (p, cpu.asregs.msize-1, 1, dumpfile);
-         fclose (dumpfile);
-         
-         fprintf (stderr, "done.\n");
-       }
-      else if (strcmp (simargv[0], "clearstats") == 0)
-       {
-         cpu.asregs.cycles = 0;
-         cpu.asregs.insts = 0;
-         cpu.asregs.stalls = 0;
-         ENDWL = 0;
-       }
-      else if (strcmp (simargv[0], "verbose") == 0)
-       {
-         issue_messages = 2;
-       }
-      else
-       {
-         fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
-                  cmd);
-       }
-    }
-  else
-    {
-      fprintf (stderr, "M.CORE sim commands: \n");
-      fprintf (stderr, "  watch <funcname> <addr>\n");
-      fprintf (stderr, "  dumpmem <filename>\n");
-      fprintf (stderr, "  clearstats\n");
-      fprintf (stderr, "  verbose\n");
-    }
-}
 
-void
-sim_set_callbacks (ptr)
-     host_callback * ptr;
-{
-  callback = ptr; 
+  return SIM_RC_OK;
 }