]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/moxie/interp.c
sim: moxie: convert to nrun.o
[thirdparty/binutils-gdb.git] / sim / moxie / interp.c
index 2be561ce33cc56456d113f0dd44648f9fc219464..128fb4860cb3bc62a646aba87189f0ffe3164d50 100644 (file)
@@ -1,5 +1,5 @@
 /* Simulator for the moxie processor
-   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2008-2015 Free Software Foundation, Inc.
    Contributed by Anthony Green
 
 This file is part of GDB, the GNU debugger.
@@ -17,28 +17,40 @@ 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, see <http://www.gnu.org/licenses/>.  */
 
+#include "config.h"
+#include <fcntl.h>
 #include <signal.h>
 #include <stdlib.h>
-#include "sysdep.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 "gdb/callback.h"
 #include "libiberty.h"
 #include "gdb/remote-sim.h"
 
+#include "sim-main.h"
+#include "sim-base.h"
+#include "sim-options.h"
+
 typedef int word;
 typedef unsigned int uword;
 
-host_callback *       callback;
+/* Extract the signed 10-bit offset from a 16-bit branch
+   instruction.  */
+#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
 
-FILE *tracefile;
+#define EXTRACT_WORD(addr) \
+  ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
+   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
+   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
+   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
 
-#define EXTRACT_WORD(addr) (((addr)[0] << 24) \
-                           + ((addr)[1] << 16) \
-                           + ((addr)[2] << 8) \
-                           + ((addr)[3]))
+#define EXTRACT_OFFSET(addr)                                           \
+  (unsigned int)                                                       \
+  (((signed short)                                                     \
+    ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8)                \
+     + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
 
 unsigned long
 moxie_extract_unsigned_integer (addr, len)
@@ -101,14 +113,13 @@ static const char *reg_names[16] =
 
 /* The ordering of the moxie_regset structure is matched in the
    gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro.  */
+/* TODO: This should be moved to sim-main.h:_sim_cpu.  */
 struct moxie_regset
 {
   word           regs[NUM_MOXIE_REGS + 1]; /* primary registers */
   word           sregs[256];             /* special registers */
   word            cc;                   /* the condition code reg */
   int            exception;
-  unsigned long   msize;
-  unsigned char * memory;
   unsigned long long insts;                /* instruction counter */
 };
 
@@ -118,75 +129,22 @@ struct moxie_regset
 #define CC_GTU 1<<3
 #define CC_LTU 1<<4
 
+/* TODO: This should be moved to sim-main.h:_sim_cpu.  */
 union
 {
   struct moxie_regset asregs;
   word asints [1];             /* but accessed larger... */
 } cpu;
 
-static char *myname;
-static SIM_OPEN_KIND sim_kind;
-static int issue_messages = 0;
-
-/* 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.asregs.memory)
-    free (cpu.asregs.memory);
-
-  /* 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.asregs.memory = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
-  else
-    cpu.asregs.memory = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
-
-  if (!cpu.asregs.memory)
-    {
-      if (issue_messages)
-       fprintf (stderr,
-                "Not enough VM for simulation of %d bytes of RAM\n",
-                cpu.asregs.msize);
-
-      cpu.asregs.msize = 1;
-      cpu.asregs.memory = (unsigned char *) calloc (1, 1);
-    }
-}
-
 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 (void)
 {
   int i;
   long space;
-  unsigned long memsize;
   
-  init_pointers ();
-
   /* Set up machine just out of reset.  */
   cpu.asregs.regs[PC_REGNO] = 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 register contents.  */
   for (i = 0; i < NUM_MOXIE_REGS; i++)
     cpu.asregs.regs[i] = 0;
@@ -194,177 +152,64 @@ set_initial_gprs ()
     cpu.asregs.sregs[i] = 0;
 }
 
-static void
-interrupt ()
-{
-  cpu.asregs.exception = SIGINT;
-}
-
 /* Write a 1 byte value to memory.  */
 
 static void INLINE 
-wbat (pc, x, v)
-     word pc, x, v;
+wbat (sim_cpu *scpu, word pc, word x, word 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.asregs.memory + x;
-       *p = v;
-      }
-    }
+  address_word cia = CIA_GET (scpu);
+  
+  sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
 }
 
 /* Write a 2 byte value to memory.  */
 
 static void INLINE 
-wsat (pc, x, v)
-     word pc, x, v;
+wsat (sim_cpu *scpu, word pc, word x, word v)
 {
-  if (((uword)x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short word write to 0x%x outside memory range\n", x);
-      
-      cpu.asregs.exception = SIGSEGV;
-    }
-  else
-    {
-      if ((x & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "short word write to unaligned memory address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-       }
-      {
-       unsigned char * p = cpu.asregs.memory + x;
-       p[0] = v >> 8;
-       p[1] = v;
-      }
-    }
+  address_word cia = CIA_GET (scpu);
+  
+  sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
 }
 
 /* Write a 4 byte value to memory.  */
 
 static void INLINE 
-wlat (pc, x, v)
-     word pc, x, v;
+wlat (sim_cpu *scpu, word pc, word x, word 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 & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-       }
-      {
-       unsigned char * p = cpu.asregs.memory + x;
-       p[0] = v >> 24;
-       p[1] = v >> 16;
-       p[2] = v >> 8;
-       p[3] = v;
-      }
-    }
+  address_word cia = CIA_GET (scpu);
+       
+  sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
 }
 
 /* Read 2 bytes from memory.  */
 
 static int INLINE 
-rsat (pc, x)
-     word pc, x;
+rsat (sim_cpu *scpu, word pc, word x)
 {
-  if (((uword) x) >= cpu.asregs.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short word 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 word read from unaligned address: 0x%x\n", x);
-      
-         cpu.asregs.exception = SIGBUS;
-         return 0;
-       }
-      {
-       unsigned char * p = cpu.asregs.memory + x;
-       return (p[0] << 8) | p[1];
-      }
-    }
+  address_word cia = CIA_GET (scpu);
+  
+  return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
 }
 
 /* Read 1 byte from memory.  */
 
 static int INLINE 
-rbat (pc, x)
-     word pc, x;
+rbat (sim_cpu *scpu, word pc, 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.asregs.memory + x;
-      return *p;
-    }
+  address_word cia = CIA_GET (scpu);
+  
+  return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
 }
 
 /* Read 4 bytes from memory.  */
 
 static int INLINE 
-rlat (pc, x)
-     word pc, x;
+rlat (sim_cpu *scpu, word pc, 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;
-       }
-      {
-       unsigned char * p = cpu.asregs.memory + x;
-       return (EXTRACT_WORD(p));
-      }
-    }
+  address_word cia = CIA_GET (scpu);
+  
+  return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
 }
 
 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
@@ -390,10 +235,11 @@ convert_target_flags (unsigned int tflags)
   return hflags;
 }
 
+/* TODO: Move to sim-trace.h.  */
+static FILE *tracefile;
+static const int tracing = 0;
 #define TRACE(str) if (tracing) fprintf(tracefile,"0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], cpu.asregs.regs[14], cpu.asregs.regs[15]);
 
-static int tracing = 0;
-
 void
 sim_resume (sd, step, siggnal)
      SIM_DESC sd;
@@ -402,13 +248,12 @@ sim_resume (sd, step, siggnal)
   word pc, opc;
   unsigned long long insts;
   unsigned short inst;
-  void (* sigsave)();
+  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+  address_word cia = CIA_GET (scpu);
 
-  sigsave = signal (SIGINT, interrupt);
   cpu.asregs.exception = step ? SIGTRAP: 0;
   pc = cpu.asregs.regs[PC_REGNO];
   insts = cpu.asregs.insts;
-  unsigned char *memory = cpu.asregs.memory;
 
   /* Run instructions here. */
   do 
@@ -416,7 +261,8 @@ sim_resume (sd, step, siggnal)
       opc = pc;
 
       /* Fetch the instruction at pc.  */
-      inst = (memory[pc] << 8) + memory[pc + 1];
+      inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
+       + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
 
       /* Decode instruction.  */
       if (inst & (1 << 15))
@@ -424,10 +270,86 @@ sim_resume (sd, step, siggnal)
          if (inst & (1 << 14))
            {
              /* This is a Form 3 instruction.  */
-             /* We haven't implemented any yet, so just SIGILL for now.  */
-             TRACE("SIGILL3");
-             cpu.asregs.exception = SIGILL;
-             break;
+             int opcode = (inst >> 10 & 0xf);
+
+             switch (opcode)
+               {
+               case 0x00: /* beq */
+                 {
+                   TRACE("beq");
+                   if (cpu.asregs.cc & CC_EQ)
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x01: /* bne */
+                 {
+                   TRACE("bne");
+                   if (! (cpu.asregs.cc & CC_EQ))
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x02: /* blt */
+                 {
+                   TRACE("blt");
+                   if (cpu.asregs.cc & CC_LT)
+                     pc += INST2OFFSET(inst);
+                 }               break;
+               case 0x03: /* bgt */
+                 {
+                   TRACE("bgt");
+                   if (cpu.asregs.cc & CC_GT)
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x04: /* bltu */
+                 {
+                   TRACE("bltu");
+                   if (cpu.asregs.cc & CC_LTU)
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x05: /* bgtu */
+                 {
+                   TRACE("bgtu");
+                   if (cpu.asregs.cc & CC_GTU)
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x06: /* bge */
+                 {
+                   TRACE("bge");
+                   if (cpu.asregs.cc & (CC_GT | CC_EQ))
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x07: /* ble */
+                 {
+                   TRACE("ble");
+                   if (cpu.asregs.cc & (CC_LT | CC_EQ))
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x08: /* bgeu */
+                 {
+                   TRACE("bgeu");
+                   if (cpu.asregs.cc & (CC_GTU | CC_EQ))
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               case 0x09: /* bleu */
+                 {
+                   TRACE("bleu");
+                   if (cpu.asregs.cc & (CC_LTU | CC_EQ))
+                     pc += INST2OFFSET(inst);
+                 }
+                 break;
+               default:
+                 {
+                   TRACE("SIGILL3");
+                   cpu.asregs.exception = SIGILL;
+                   break;
+                 }
+               }
            }
          else
            {
@@ -440,6 +362,7 @@ sim_resume (sd, step, siggnal)
                    int a = (inst >> 8) & 0xf;
                    unsigned av = cpu.asregs.regs[a];
                    unsigned v = (inst & 0xff);
+
                    TRACE("inc");
                    cpu.asregs.regs[a] = av + v;
                  }
@@ -449,6 +372,7 @@ sim_resume (sd, step, siggnal)
                    int a = (inst >> 8) & 0xf;
                    unsigned av = cpu.asregs.regs[a];
                    unsigned v = (inst & 0xff);
+
                    TRACE("dec");
                    cpu.asregs.regs[a] = av - v;
                  }
@@ -457,16 +381,20 @@ sim_resume (sd, step, siggnal)
                  {
                    int a = (inst >> 8) & 0xf;
                    unsigned v = (inst & 0xff);
+
                    TRACE("gsr");
                    cpu.asregs.regs[a] = cpu.asregs.sregs[v];
                  }
+                 break;
                case 0x03: /* ssr */
                  {
                    int a = (inst >> 8) & 0xf;
                    unsigned v = (inst & 0xff);
+
                    TRACE("ssr");
                    cpu.asregs.sregs[v] = cpu.asregs.regs[a];
                  }
+                 break;
                default:
                  TRACE("SIGILL2");
                  cpu.asregs.exception = SIGILL;
@@ -480,13 +408,17 @@ sim_resume (sd, step, siggnal)
          int opcode = inst >> 8;
          switch (opcode)
            {
-           case 0x00: /* nop */
+           case 0x00: /* bad */
+             opc = opcode;
+             TRACE("SIGILL0");
+             cpu.asregs.exception = SIGILL;
              break;
            case 0x01: /* ldi.l (immediate) */
              {
                int reg = (inst >> 4) & 0xf;
+
                TRACE("ldi.l");
-               unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+               unsigned int val = EXTRACT_WORD(pc+2);
                cpu.asregs.regs[reg] = val;
                pc += 4;
              }
@@ -495,25 +427,27 @@ sim_resume (sd, step, siggnal)
              {
                int dest  = (inst >> 4) & 0xf;
                int src = (inst ) & 0xf;
+
                TRACE("mov");
                cpu.asregs.regs[dest] = cpu.asregs.regs[src];
              }
              break;
            case 0x03: /* jsra */
              {
-               unsigned int fn = EXTRACT_WORD(&(memory[pc + 2]));
+               unsigned int fn = EXTRACT_WORD(pc+2);
                unsigned int sp = cpu.asregs.regs[1];
+
                TRACE("jsra");
                /* Save a slot for the static chain.  */
                sp -= 4;
 
                /* Push the return address.  */
                sp -= 4;
-               wlat (opc, sp, pc + 6);
+               wlat (scpu, opc, sp, pc + 6);
                
                /* Push the current frame pointer.  */
                sp -= 4;
-               wlat (opc, sp, cpu.asregs.regs[0]);
+               wlat (scpu, opc, sp, cpu.asregs.regs[0]);
  
                /* Uncache the stack pointer and set the pc and $fp.  */
                cpu.asregs.regs[1] = sp;
@@ -528,11 +462,11 @@ sim_resume (sd, step, siggnal)
                TRACE("ret");
  
                /* Pop the frame pointer.  */
-               cpu.asregs.regs[0] = rlat (opc, sp);
+               cpu.asregs.regs[0] = rlat (scpu, opc, sp);
                sp += 4;
                
                /* Pop the return address.  */
-               pc = rlat (opc, sp) - 2;
+               pc = rlat (scpu, opc, sp) - 2;
                sp += 4;
 
                /* Skip over the static chain slot.  */
@@ -548,6 +482,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
+
                TRACE("add.l");
                cpu.asregs.regs[a] = av + bv;
              }
@@ -557,8 +492,9 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int sp = cpu.asregs.regs[a] - 4;
+
                TRACE("push");
-               wlat (opc, sp, cpu.asregs.regs[b]);
+               wlat (scpu, opc, sp, cpu.asregs.regs[b]);
                cpu.asregs.regs[a] = sp;
              }
              break;
@@ -567,26 +503,29 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int sp = cpu.asregs.regs[a];
+
                TRACE("pop");
-               cpu.asregs.regs[b] = rlat (opc, sp);
+               cpu.asregs.regs[b] = rlat (scpu, opc, sp);
                cpu.asregs.regs[a] = sp + 4;
              }
              break;
            case 0x08: /* lda.l */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("lda.l");
-               cpu.asregs.regs[reg] = rlat (opc, addr);
+               cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
                pc += 4;
              }
              break;
            case 0x09: /* sta.l */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("sta.l");
-               wlat (opc, addr, cpu.asregs.regs[reg]);
+               wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
              }
              break;
@@ -595,39 +534,43 @@ sim_resume (sd, step, siggnal)
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
+
                TRACE("ld.l");
                xv = cpu.asregs.regs[src];
-               cpu.asregs.regs[dest] = rlat (opc, xv);
+               cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
              }
              break;
            case 0x0b: /* st.l */
              {
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
+
                TRACE("st.l");
-               wlat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+               wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              break;
            case 0x0c: /* ldo.l */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("ldo.l");
                addr += cpu.asregs.regs[b];
-               cpu.asregs.regs[a] = rlat(opc, addr);
-               pc += 4;
+               cpu.asregs.regs[a] = rlat (scpu, opc, addr);
+               pc += 2;
              }
              break;
            case 0x0d: /* sto.l */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("sto.l");
                addr += cpu.asregs.regs[a];
-               wlat(opc, addr, cpu.asregs.regs[b]);
-               pc += 4;
+               wlat (scpu, opc, addr, cpu.asregs.regs[b]);
+               pc += 2;
              }
              break;
            case 0x0e: /* cmp */
@@ -639,7 +582,6 @@ sim_resume (sd, step, siggnal)
                int vb = cpu.asregs.regs[b]; 
 
                TRACE("cmp");
-
                if (va == vb)
                  cc = CC_EQ;
                else
@@ -653,126 +595,83 @@ sim_resume (sd, step, siggnal)
                cpu.asregs.cc = cc;
              }
              break;
-           case 0x0f: /* beq */
-             {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("beq");
-               if (cpu.asregs.cc & CC_EQ)
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
-             }
-             break;
-           case 0x10: /* bne */
-             {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bne");
-               if (! (cpu.asregs.cc & CC_EQ))
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
-             }
-             break;
-           case 0x11: /* blt */
-             {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("blt");
-               if (cpu.asregs.cc & CC_LT)
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
-             }
+           case 0x0f: /* nop */
              break;
-           case 0x12: /* bgt */
+           case 0x10: /* sex.b */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bgt");
-               if (cpu.asregs.cc & CC_GT)
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               signed char bv = cpu.asregs.regs[b];
+
+               TRACE("sex.b");
+               cpu.asregs.regs[a] = (int) bv;
              }
              break;
-           case 0x13: /* bltu */
+           case 0x11: /* sex.s */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bltu");
-               if (cpu.asregs.cc & CC_LTU)
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               signed short bv = cpu.asregs.regs[b];
+
+               TRACE("sex.s");
+               cpu.asregs.regs[a] = (int) bv;
              }
              break;
-           case 0x14: /* bgtu */
+           case 0x12: /* zex.b */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bgtu");
-               if (cpu.asregs.cc & CC_GTU)
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               signed char bv = cpu.asregs.regs[b];
+
+               TRACE("zex.b");
+               cpu.asregs.regs[a] = (int) bv & 0xff;
              }
              break;
-           case 0x15: /* bge */
+           case 0x13: /* zex.s */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bge");
-               if ((cpu.asregs.cc & CC_GT) || (cpu.asregs.cc & CC_EQ))            
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               signed short bv = cpu.asregs.regs[b];
+
+               TRACE("zex.s");
+               cpu.asregs.regs[a] = (int) bv & 0xffff;
              }
              break;
-           case 0x16: /* ble */
+           case 0x14: /* umul.x */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("ble");
-               if ((cpu.asregs.cc & CC_LT) || (cpu.asregs.cc & CC_EQ))
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               unsigned av = cpu.asregs.regs[a];
+               unsigned bv = cpu.asregs.regs[b];
+               unsigned long long r = 
+                 (unsigned long long) av * (unsigned long long) bv;
+
+               TRACE("umul.x");
+               cpu.asregs.regs[a] = r >> 32;
              }
              break;
-           case 0x17: /* bgeu */
+           case 0x15: /* mul.x */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bgeu");
-               if ((cpu.asregs.cc & CC_GTU) || (cpu.asregs.cc & CC_EQ))
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               int a = (inst >> 4) & 0xf;
+               int b = inst & 0xf;
+               unsigned av = cpu.asregs.regs[a];
+               unsigned bv = cpu.asregs.regs[b];
+               signed long long r = 
+                 (signed long long) av * (signed long long) bv;
+
+               TRACE("mul.x");
+               cpu.asregs.regs[a] = r >> 32;
              }
              break;
-           case 0x18: /* bleu */
+           case 0x16: /* bad */
+           case 0x17: /* bad */
+           case 0x18: /* bad */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
-               TRACE("bleu");
-               if ((cpu.asregs.cc & CC_LTU) || (cpu.asregs.cc & CC_EQ))
-                 {
-                   pc = tgt - 2;
-                 }
-               else
-                 pc += 4;
+               opc = opcode;
+               TRACE("SIGILL0");
+               cpu.asregs.exception = SIGILL;
+               break;
              }
-             break;
            case 0x19: /* jsr */
              {
                unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
@@ -785,11 +684,11 @@ sim_resume (sd, step, siggnal)
 
                /* Push the return address.  */
                sp -= 4;
-               wlat (opc, sp, pc + 2);
+               wlat (scpu, opc, sp, pc + 2);
                
                /* Push the current frame pointer.  */
                sp -= 4;
-               wlat (opc, sp, cpu.asregs.regs[0]);
+               wlat (scpu, opc, sp, cpu.asregs.regs[0]);
 
                /* Uncache the stack pointer and set the fp & pc.  */
                cpu.asregs.regs[1] = sp;
@@ -799,7 +698,8 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x1a: /* jmpa */
              {
-               unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int tgt = EXTRACT_WORD(pc+2);
+
                TRACE("jmpa");
                pc = tgt - 2;
              }
@@ -807,8 +707,8 @@ sim_resume (sd, step, siggnal)
            case 0x1b: /* ldi.b (immediate) */
              {
                int reg = (inst >> 4) & 0xf;
+               unsigned int val = EXTRACT_WORD(pc+2);
 
-               unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
                TRACE("ldi.b");
                cpu.asregs.regs[reg] = val;
                pc += 4;
@@ -819,17 +719,19 @@ sim_resume (sd, step, siggnal)
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
+
                TRACE("ld.b");
                xv = cpu.asregs.regs[src];
-               cpu.asregs.regs[dest] = rbat (opc, xv);
+               cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
              }
              break;
            case 0x1d: /* lda.b */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("lda.b");
-               cpu.asregs.regs[reg] = rbat (opc, addr);
+               cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
                pc += 4;
              }
              break;
@@ -837,16 +739,18 @@ sim_resume (sd, step, siggnal)
              {
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
+
                TRACE("st.b");
-               wbat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+               wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              break;
            case 0x1f: /* sta.b */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("sta.b");
-               wbat (opc, addr, cpu.asregs.regs[reg]);
+               wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
              }
              break;
@@ -854,7 +758,8 @@ sim_resume (sd, step, siggnal)
              {
                int reg = (inst >> 4) & 0xf;
 
-               unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+               unsigned int val = EXTRACT_WORD(pc+2);
+
                TRACE("ldi.s");
                cpu.asregs.regs[reg] = val;
                pc += 4;
@@ -865,17 +770,19 @@ sim_resume (sd, step, siggnal)
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
+
                TRACE("ld.s");
                xv = cpu.asregs.regs[src];
-               cpu.asregs.regs[dest] = rsat (opc, xv);
+               cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
              }
              break;
            case 0x22: /* lda.s */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("lda.s");
-               cpu.asregs.regs[reg] = rsat (opc, addr);
+               cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
                pc += 4;
              }
              break;
@@ -883,22 +790,25 @@ sim_resume (sd, step, siggnal)
              {
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
+
                TRACE("st.s");
-               wsat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+               wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              break;
            case 0x24: /* sta.s */
              {
                int reg = (inst >> 4) & 0xf;
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_WORD(pc+2);
+
                TRACE("sta.s");
-               wsat (opc, addr, cpu.asregs.regs[reg]);
+               wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
              }
              break;
            case 0x25: /* jmp */
              {
                int reg = (inst >> 4) & 0xf;
+
                TRACE("jmp");
                pc = cpu.asregs.regs[reg] - 2;
              }
@@ -908,6 +818,7 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int av, bv;
+
                TRACE("and");
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
@@ -920,6 +831,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
+
                TRACE("lshr");
                cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
              }
@@ -930,6 +842,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
+
                TRACE("ashl");
                cpu.asregs.regs[a] = av << bv;
              }
@@ -940,6 +853,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
+
                TRACE("sub.l");
                cpu.asregs.regs[a] = av - bv;
              }
@@ -949,6 +863,7 @@ sim_resume (sd, step, siggnal)
                int a  = (inst >> 4) & 0xf;
                int b  = inst & 0xf;
                int bv = cpu.asregs.regs[b];
+
                TRACE("neg");
                cpu.asregs.regs[a] = - bv;
              }
@@ -958,6 +873,7 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int av, bv;
+
                TRACE("or");
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
@@ -969,6 +885,7 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int bv = cpu.asregs.regs[b];
+
                TRACE("not");
                cpu.asregs.regs[a] = 0xffffffff ^ bv;
              }
@@ -979,6 +896,7 @@ sim_resume (sd, step, siggnal)
                int b  = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
+
                TRACE("ashr");
                cpu.asregs.regs[a] = av >> bv;
              }
@@ -988,6 +906,7 @@ sim_resume (sd, step, siggnal)
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int av, bv;
+
                TRACE("xor");
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
@@ -1000,14 +919,19 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
+
                TRACE("mul.l");
                cpu.asregs.regs[a] = av * bv;
              }
              break;
            case 0x30: /* swi */
              {
-               unsigned int inum = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int inum = EXTRACT_WORD(pc+2);
+
                TRACE("swi");
+               /* Set the special registers appropriately.  */
+               cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
+               cpu.asregs.sregs[3] = inum;
                switch (inum)
                  {
                  case 0x1: /* SYS_exit */
@@ -1017,14 +941,12 @@ sim_resume (sd, step, siggnal)
                    }
                  case 0x2: /* SYS_open */
                    {
-                     char *fname = &memory[cpu.asregs.regs[2]];
+                     char fname[1024];
                      int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
-                     /* Permission bits are at 0x12($fp) */
-                     int perm = (int) EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
+                     int perm = (int) cpu.asregs.regs[4];
                      int fd = open (fname, mode, perm);
-#if 0
-                     fprintf(stderr, "open(\"%s\", 0x%x, 0x%x) = %d\n", fname, mode, perm, fd);
-#endif
+                     sim_core_read_buffer (sd, scpu, read_map, fname,
+                                           cpu.asregs.regs[2], 1024);
                      /* FIXME - set errno */
                      cpu.asregs.regs[2] = fd;
                      break;
@@ -1032,21 +954,48 @@ sim_resume (sd, step, siggnal)
                  case 0x4: /* SYS_read */
                    {
                      int fd = cpu.asregs.regs[2];
-                     char *buf = &memory[cpu.asregs.regs[3]];
-                     /* String length is at 0x12($fp) */
-                     unsigned len = EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
+                     unsigned len = (unsigned) cpu.asregs.regs[4];
+                     char *buf = malloc (len);
                      cpu.asregs.regs[2] = read (fd, buf, len);
+                     sim_core_write_buffer (sd, scpu, write_map, buf,
+                                            cpu.asregs.regs[3], len);
+                     free (buf);
                      break;
                    }
                  case 0x5: /* SYS_write */
                    {
-                     char *str = &memory[cpu.asregs.regs[3]];
+                     char *str;
                      /* String length is at 0x12($fp) */
-                     unsigned count, len = EXTRACT_WORD(&memory[cpu.asregs.regs[0] + 20]);
+                     unsigned count, len = (unsigned) cpu.asregs.regs[4];
+                     str = malloc (len);
+                     sim_core_read_buffer (sd, scpu, read_map, str,
+                                           cpu.asregs.regs[3], len);
                      count = write (cpu.asregs.regs[2], str, len);
+                     free (str);
                      cpu.asregs.regs[2] = count;
                      break;
                    }
+                 case 0xffffffff: /* Linux System Call */
+                   {
+                     unsigned int handler = cpu.asregs.sregs[1];
+                     unsigned int sp = cpu.asregs.regs[1];
+
+                     /* Save a slot for the static chain.  */
+                     sp -= 4;
+
+                     /* Push the return address.  */
+                     sp -= 4;
+                     wlat (scpu, opc, sp, pc + 6);
+               
+                     /* Push the current frame pointer.  */
+                     sp -= 4;
+                     wlat (scpu, opc, sp, cpu.asregs.regs[0]);
+
+                     /* Uncache the stack pointer and set the fp & pc.  */
+                     cpu.asregs.regs[1] = sp;
+                     cpu.asregs.regs[0] = sp;
+                     pc = handler - 6;
+                   }
                  default:
                    break;
                  }
@@ -1059,6 +1008,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
+
                TRACE("div.l");
                cpu.asregs.regs[a] = av / bv;
              }
@@ -1069,6 +1019,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                unsigned int av = cpu.asregs.regs[a];
                unsigned int bv = cpu.asregs.regs[b];
+
                TRACE("udiv.l");
                cpu.asregs.regs[a] = (av / bv);
              }
@@ -1079,6 +1030,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
+
                TRACE("mod.l");
                cpu.asregs.regs[a] = av % bv;
              }
@@ -1089,6 +1041,7 @@ sim_resume (sd, step, siggnal)
                int b = inst & 0xf;
                unsigned int av = cpu.asregs.regs[a];
                unsigned int bv = cpu.asregs.regs[b];
+
                TRACE("umod.l");
                cpu.asregs.regs[a] = (av % bv);
              }
@@ -1100,46 +1053,50 @@ sim_resume (sd, step, siggnal)
              break;
            case 0x36: /* ldo.b */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("ldo.b");
                addr += cpu.asregs.regs[b];
-               cpu.asregs.regs[a] = rbat(opc, addr);
-               pc += 4;
+               cpu.asregs.regs[a] = rbat (scpu, opc, addr);
+               pc += 2;
              }
              break;
            case 0x37: /* sto.b */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("sto.b");
                addr += cpu.asregs.regs[a];
-               wbat(opc, addr, cpu.asregs.regs[b]);
-               pc += 4;
+               wbat (scpu, opc, addr, cpu.asregs.regs[b]);
+               pc += 2;
              }
              break;
            case 0x38: /* ldo.s */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("ldo.s");
                addr += cpu.asregs.regs[b];
-               cpu.asregs.regs[a] = rsat(opc, addr);
-               pc += 4;
+               cpu.asregs.regs[a] = rsat (scpu, opc, addr);
+               pc += 2;
              }
              break;
            case 0x39: /* sto.s */
              {
-               unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+               unsigned int addr = EXTRACT_OFFSET(pc+2);
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
+
                TRACE("sto.s");
                addr += cpu.asregs.regs[a];
-               wsat(opc, addr, cpu.asregs.regs[b]);
-               pc += 4;
+               wsat (scpu, opc, addr, cpu.asregs.regs[b]);
+               pc += 2;
              }
              break;
            default:
@@ -1158,41 +1115,8 @@ sim_resume (sd, step, siggnal)
   /* Hide away the things we've cached while executing.  */
   cpu.asregs.regs[PC_REGNO] = pc;
   cpu.asregs.insts += insts;           /* instructions done ... */
-
-  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.asregs.memory[addr], buffer, size);
-  
-  return size;
-}
-
-int
-sim_read (sd, addr, buffer, size)
-     SIM_DESC sd;
-     SIM_ADDR addr;
-     unsigned char * buffer;
-     int size;
-{
-  int i;
-  init_pointers ();
-  
-  memcpy (buffer, & cpu.asregs.memory[addr], size);
-  
-  return size;
-}
-
-
 int
 sim_store_register (sd, rn, memory, length)
      SIM_DESC sd;
@@ -1200,8 +1124,6 @@ sim_store_register (sd, rn, memory, length)
      unsigned char * memory;
      int length;
 {
-  init_pointers ();
-
   if (rn < NUM_MOXIE_REGS && rn >= 0)
     {
       if (length == 4)
@@ -1226,8 +1148,6 @@ sim_fetch_register (sd, rn, memory, length)
      unsigned char * memory;
      int length;
 {
-  init_pointers ();
-  
   if (rn < NUM_MOXIE_REGS && rn >= 0)
     {
       if (length == 4)
@@ -1244,83 +1164,83 @@ sim_fetch_register (sd, rn, memory, length)
     return 0;
 }
 
-
-int
-sim_trace (sd)
-     SIM_DESC sd;
+static void
+free_state (SIM_DESC sd)
 {
-  if (tracefile == 0)
-    tracefile = fopen("trace.csv", "wb");
-
-  tracing = 1;
-  
-  sim_resume (sd, 0, 0);
-
-  tracing = 0;
-  
-  return 1;
+  if (STATE_MODULES (sd) != NULL)
+    sim_module_uninstall (sd);
+  sim_cpu_free_all (sd);
+  sim_state_free (sd);
 }
 
-void
-sim_stop_reason (sd, reason, sigrc)
-     SIM_DESC sd;
-     enum sim_stop * reason;
-     int * sigrc;
+SIM_DESC
+sim_open (kind, cb, abfd, argv)
+     SIM_OPEN_KIND kind;
+     host_callback * cb;
+     struct bfd * abfd;
+     char ** argv;
 {
-  if (cpu.asregs.exception == SIGQUIT)
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+  /* 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)
     {
-      * reason = sim_exited;
-      * sigrc = cpu.asregs.regs[2];
+      free_state (sd);
+      return 0;
     }
-  else
+
+  STATE_WATCHPOINTS (sd)->pc = &cpu.asregs.regs[PC_REGNO];
+  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (word);
+
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
     {
-      * reason = sim_stopped;
-      * sigrc = cpu.asregs.exception;
+      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;
+    }
 
-int
-sim_stop (sd)
-     SIM_DESC sd;
-{
-  cpu.asregs.exception = SIGINT;
-  return 1;
-}
+  sim_do_command(sd," memory region 0x00000000,0x4000000") ; 
+  sim_do_command(sd," memory region 0xE0000000,0x10000") ; 
 
+  /* 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;
+    }
 
-void
-sim_info (sd, verbose)
-     SIM_DESC sd;
-     int verbose;
-{
-  callback->printf_filtered (callback, "\n\n# instructions executed  %llu\n",
-                            cpu.asregs.insts);
-}
+  /* 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;
+    }
 
-SIM_DESC
-sim_open (kind, cb, abfd, argv)
-     SIM_OPEN_KIND kind;
-     host_callback * cb;
-     struct bfd * abfd;
-     char ** argv;
-{
-  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 */
+  /* CPU specific initialization.  */
+  set_initial_gprs ();
 
-  set_initial_gprs (); /* Reset the GPR registers.  */
-  
-  /* Fudge our descriptor for now.  */
-  return (SIM_DESC) 1;
+  return sd;
 }
 
 void
@@ -1331,58 +1251,33 @@ sim_close (sd, quitting)
   /* nothing to do */
 }
 
-SIM_RC
-sim_load (sd, prog, abfd, from_tty)
-     SIM_DESC sd;
-     char * prog;
-     bfd * abfd;
-     int from_tty;
-{
 
-  /* 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;
-    handle = bfd_openr (prog, 0);      /* could be "moxie" */
-    
-    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;
-      }
-
-    /* Clean up after ourselves.  */
-    bfd_close (handle);
-  }
-
-  /* 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);
+/* Load the device tree blob.  */
 
-  return SIM_RC_OK;
+static void
+load_dtb (SIM_DESC sd, const char *filename)
+{
+  int size = 0;
+  FILE *f = fopen (filename, "rb");
+  char *buf;
+  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 
+ if (f == NULL)
+    {
+      printf ("WARNING: ``%s'' could not be opened.\n", filename);
+      return;
+    }
+  fseek (f, 0, SEEK_END);
+  size = ftell(f);
+  fseek (f, 0, SEEK_SET);
+  buf = alloca (size);
+  if (size != fread (buf, 1, size, f))
+    {
+      printf ("ERROR: error reading ``%s''.\n", filename);
+      return;
+    }
+  sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
+  cpu.asregs.sregs[9] = 0xE0000000;
+  fclose (f);
 }
 
 SIM_RC
@@ -1394,18 +1289,14 @@ sim_create_inferior (sd, prog_bfd, argv, env)
 {
   char ** avp;
   int l, argc, i, tp;
+  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
 
-  /* Set the initial register set.  */
-  l = issue_messages;
-  issue_messages = 0;
-  set_initial_gprs ();
-  issue_messages = l;
-  
-  cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
+  if (prog_bfd != NULL)
+    cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
 
   /* Copy args into target memory.  */
   avp = argv;
-  for (argc = 0; *avp; avp++)
+  for (argc = 0; avp && *avp; avp++)
     argc++;
 
   /* Target memory looks like this:
@@ -1417,8 +1308,8 @@ sim_create_inferior (sd, prog_bfd, argv, env)
      0x0000???? zero word 
      0x0000???? start of data pointed to by argv  */
 
-  wlat (0, 0, 0);
-  wlat (0, 4, argc);
+  wlat (scpu, 0, 0, 0);
+  wlat (scpu, 0, 4, argc);
 
   /* tp is the offset of our first argv data.  */
   tp = 4 + 4 + argc * 4 + 4;
@@ -1426,56 +1317,17 @@ sim_create_inferior (sd, prog_bfd, argv, env)
   for (i = 0; i < argc; i++)
     {
       /* Set the argv value.  */
-      wlat (0, 4 + 4 + i * 4, tp);
+      wlat (scpu, 0, 4 + 4 + i * 4, tp);
 
       /* Store the string.  */
-      strcpy (&cpu.asregs.memory[tp], argv[i]);
+      sim_core_write_buffer (sd, scpu, write_map, argv[i],
+                            tp, strlen(argv[i])+1);
       tp += strlen (argv[i]) + 1;
     }
 
-  wlat (0, 4 + 4 + i * 4, 0);
-
-  return SIM_RC_OK;
-}
-
-void
-sim_kill (sd)
-     SIM_DESC sd;
-{
-  if (tracefile)
-    fclose(tracefile);
-}
+  wlat (scpu, 0, 4 + 4 + i * 4, 0);
 
-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], "verbose") == 0)
-       {
-         issue_messages = 2;
-       }
-      else
-       {
-         fprintf (stderr,"Error: \"%s\" is not a valid moxie simulator command.\n",
-                  cmd);
-       }
-    }
-  else
-    {
-      fprintf (stderr, "moxie sim commands: \n");
-      fprintf (stderr, "  verbose\n");
-    }
-}
+  load_dtb (sd, DTB);
 
-void
-sim_set_callbacks (ptr)
-     host_callback * ptr;
-{
-  callback = ptr; 
+  return SIM_RC_OK;
 }