OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [moxie/] [interp.c] - Diff between revs 835 and 841

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 835 Rev 841
/* Simulator for the moxie processor
/* Simulator for the moxie processor
   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
   Contributed by Anthony Green
   Contributed by Anthony Green
 
 
This file is part of GDB, the GNU debugger.
This file is part of GDB, the GNU debugger.
 
 
This program is free software; you can redistribute it and/or modify
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include <signal.h>
#include <signal.h>
#include <stdlib.h>
#include <stdlib.h>
#include "sysdep.h"
#include "sysdep.h"
#include <sys/times.h>
#include <sys/times.h>
#include <sys/param.h>
#include <sys/param.h>
#include <netinet/in.h> /* for byte ordering macros */
#include <netinet/in.h> /* for byte ordering macros */
#include "bfd.h"
#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/callback.h"
#include "libiberty.h"
#include "libiberty.h"
#include "gdb/remote-sim.h"
#include "gdb/remote-sim.h"
 
 
#include "sim-main.h"
#include "sim-main.h"
#include "sim-base.h"
#include "sim-base.h"
 
 
typedef int word;
typedef int word;
typedef unsigned int uword;
typedef unsigned int uword;
 
 
host_callback *       callback;
host_callback *       callback;
 
 
FILE *tracefile;
FILE *tracefile;
 
 
/* Extract the signed 10-bit offset from a 16-bit branch
/* Extract the signed 10-bit offset from a 16-bit branch
   instruction.  */
   instruction.  */
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
 
 
#define EXTRACT_WORD(addr) \
#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) << 24) \
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
   + (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+2) << 8) \
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
 
 
unsigned long
unsigned long
moxie_extract_unsigned_integer (addr, len)
moxie_extract_unsigned_integer (addr, len)
     unsigned char * addr;
     unsigned char * addr;
     int len;
     int len;
{
{
  unsigned long retval;
  unsigned long retval;
  unsigned char * p;
  unsigned char * p;
  unsigned char * startaddr = (unsigned char *)addr;
  unsigned char * startaddr = (unsigned char *)addr;
  unsigned char * endaddr = startaddr + len;
  unsigned char * endaddr = startaddr + len;
 
 
  if (len > (int) sizeof (unsigned long))
  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 %d bytes.",
            sizeof (unsigned long));
            sizeof (unsigned long));
 
 
  /* Start at the most significant end of the integer, and work towards
  /* Start at the most significant end of the integer, and work towards
     the least significant.  */
     the least significant.  */
  retval = 0;
  retval = 0;
 
 
  for (p = endaddr; p > startaddr;)
  for (p = endaddr; p > startaddr;)
    retval = (retval << 8) | * -- p;
    retval = (retval << 8) | * -- p;
 
 
  return retval;
  return retval;
}
}
 
 
void
void
moxie_store_unsigned_integer (addr, len, val)
moxie_store_unsigned_integer (addr, len, val)
     unsigned char * addr;
     unsigned char * addr;
     int len;
     int len;
     unsigned long val;
     unsigned long val;
{
{
  unsigned char * p;
  unsigned char * p;
  unsigned char * startaddr = (unsigned char *)addr;
  unsigned char * startaddr = (unsigned char *)addr;
  unsigned char * endaddr = startaddr + len;
  unsigned char * endaddr = startaddr + len;
 
 
  for (p = endaddr; p > startaddr;)
  for (p = endaddr; p > startaddr;)
    {
    {
      * -- p = val & 0xff;
      * -- p = val & 0xff;
      val >>= 8;
      val >>= 8;
    }
    }
}
}
 
 
/* moxie register names.  */
/* moxie register names.  */
static const char *reg_names[16] =
static const char *reg_names[16] =
  { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
  { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
    "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
    "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
 
 
/* The machine state.
/* The machine state.
 
 
   This state is maintained in host byte order.  The fetch/store
   This state is maintained in host byte order.  The fetch/store
   register functions must translate between host byte order and the
   register functions must translate between host byte order and the
   target processor byte order.  Keeping this data in target byte
   target processor byte order.  Keeping this data in target byte
   order simplifies the register read/write functions.  Keeping this
   order simplifies the register read/write functions.  Keeping this
   data in native order improves the performance of the simulator.
   data in native order improves the performance of the simulator.
   Simulation speed is deemed more important.  */
   Simulation speed is deemed more important.  */
 
 
#define NUM_MOXIE_REGS 17 /* Including PC */
#define NUM_MOXIE_REGS 17 /* Including PC */
#define NUM_MOXIE_SREGS 256 /* The special registers */
#define NUM_MOXIE_SREGS 256 /* The special registers */
#define PC_REGNO     16
#define PC_REGNO     16
 
 
/* The ordering of the moxie_regset structure is matched in the
/* The ordering of the moxie_regset structure is matched in the
   gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro.  */
   gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro.  */
struct moxie_regset
struct moxie_regset
{
{
  word            regs[NUM_MOXIE_REGS + 1]; /* primary registers */
  word            regs[NUM_MOXIE_REGS + 1]; /* primary registers */
  word            sregs[256];             /* special registers */
  word            sregs[256];             /* special registers */
  word            cc;                   /* the condition code reg */
  word            cc;                   /* the condition code reg */
  int             exception;
  int             exception;
  unsigned long long insts;                /* instruction counter */
  unsigned long long insts;                /* instruction counter */
};
};
 
 
#define CC_GT  1<<0
#define CC_GT  1<<0
#define CC_LT  1<<1
#define CC_LT  1<<1
#define CC_EQ  1<<2
#define CC_EQ  1<<2
#define CC_GTU 1<<3
#define CC_GTU 1<<3
#define CC_LTU 1<<4
#define CC_LTU 1<<4
 
 
union
union
{
{
  struct moxie_regset asregs;
  struct moxie_regset asregs;
  word asints [1];              /* but accessed larger... */
  word asints [1];              /* but accessed larger... */
} cpu;
} cpu;
 
 
static char *myname;
static char *myname;
static SIM_OPEN_KIND sim_kind;
static SIM_OPEN_KIND sim_kind;
static int issue_messages = 0;
static int issue_messages = 0;
 
 
void
void
sim_size (int s)
sim_size (int s)
{
{
}
}
 
 
static void
static void
set_initial_gprs ()
set_initial_gprs ()
{
{
  int i;
  int i;
  long space;
  long space;
 
 
  /* Set up machine just out of reset.  */
  /* Set up machine just out of reset.  */
  cpu.asregs.regs[PC_REGNO] = 0;
  cpu.asregs.regs[PC_REGNO] = 0;
 
 
  /* Clean out the register contents.  */
  /* Clean out the register contents.  */
  for (i = 0; i < NUM_MOXIE_REGS; i++)
  for (i = 0; i < NUM_MOXIE_REGS; i++)
    cpu.asregs.regs[i] = 0;
    cpu.asregs.regs[i] = 0;
  for (i = 0; i < NUM_MOXIE_SREGS; i++)
  for (i = 0; i < NUM_MOXIE_SREGS; i++)
    cpu.asregs.sregs[i] = 0;
    cpu.asregs.sregs[i] = 0;
}
}
 
 
static void
static void
interrupt ()
interrupt ()
{
{
  cpu.asregs.exception = SIGINT;
  cpu.asregs.exception = SIGINT;
}
}
 
 
/* Write a 1 byte value to memory.  */
/* Write a 1 byte value to memory.  */
 
 
static void INLINE
static void INLINE
wbat (sim_cpu *scpu, word pc, word x, word v)
wbat (sim_cpu *scpu, word pc, word x, word v)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
  sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
}
}
 
 
/* Write a 2 byte value to memory.  */
/* Write a 2 byte value to memory.  */
 
 
static void INLINE
static void INLINE
wsat (sim_cpu *scpu, word pc, word x, word v)
wsat (sim_cpu *scpu, word pc, word x, word v)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
  sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
}
}
 
 
/* Write a 4 byte value to memory.  */
/* Write a 4 byte value to memory.  */
 
 
static void INLINE
static void INLINE
wlat (sim_cpu *scpu, word pc, word x, word v)
wlat (sim_cpu *scpu, word pc, word x, word v)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
  sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
}
}
 
 
/* Read 2 bytes from memory.  */
/* Read 2 bytes from memory.  */
 
 
static int INLINE
static int INLINE
rsat (sim_cpu *scpu, word pc, word x)
rsat (sim_cpu *scpu, word pc, word x)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
  return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
}
}
 
 
/* Read 1 byte from memory.  */
/* Read 1 byte from memory.  */
 
 
static int INLINE
static int INLINE
rbat (sim_cpu *scpu, word pc, word x)
rbat (sim_cpu *scpu, word pc, word x)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
  return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
}
}
 
 
/* Read 4 bytes from memory.  */
/* Read 4 bytes from memory.  */
 
 
static int INLINE
static int INLINE
rlat (sim_cpu *scpu, word pc, word x)
rlat (sim_cpu *scpu, word pc, word x)
{
{
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
  return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
}
}
 
 
#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
 
 
unsigned int
unsigned int
convert_target_flags (unsigned int tflags)
convert_target_flags (unsigned int tflags)
{
{
  unsigned int hflags = 0x0;
  unsigned int hflags = 0x0;
 
 
  CHECK_FLAG(0x0001, O_WRONLY);
  CHECK_FLAG(0x0001, O_WRONLY);
  CHECK_FLAG(0x0002, O_RDWR);
  CHECK_FLAG(0x0002, O_RDWR);
  CHECK_FLAG(0x0008, O_APPEND);
  CHECK_FLAG(0x0008, O_APPEND);
  CHECK_FLAG(0x0200, O_CREAT);
  CHECK_FLAG(0x0200, O_CREAT);
  CHECK_FLAG(0x0400, O_TRUNC);
  CHECK_FLAG(0x0400, O_TRUNC);
  CHECK_FLAG(0x0800, O_EXCL);
  CHECK_FLAG(0x0800, O_EXCL);
  CHECK_FLAG(0x2000, O_SYNC);
  CHECK_FLAG(0x2000, O_SYNC);
 
 
  if (tflags != 0x0)
  if (tflags != 0x0)
    fprintf (stderr,
    fprintf (stderr,
             "Simulator Error: problem converting target open flags for host.  0x%x\n",
             "Simulator Error: problem converting target open flags for host.  0x%x\n",
             tflags);
             tflags);
 
 
  return hflags;
  return hflags;
}
}
 
 
#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]);
#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;
static int tracing = 0;
 
 
void
void
sim_resume (sd, step, siggnal)
sim_resume (sd, step, siggnal)
     SIM_DESC sd;
     SIM_DESC sd;
     int step, siggnal;
     int step, siggnal;
{
{
  word pc, opc;
  word pc, opc;
  unsigned long long insts;
  unsigned long long insts;
  unsigned short inst;
  unsigned short inst;
  void (* sigsave)();
  void (* sigsave)();
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  address_word cia = CIA_GET (scpu);
  address_word cia = CIA_GET (scpu);
 
 
  sigsave = signal (SIGINT, interrupt);
  sigsave = signal (SIGINT, interrupt);
  cpu.asregs.exception = step ? SIGTRAP: 0;
  cpu.asregs.exception = step ? SIGTRAP: 0;
  pc = cpu.asregs.regs[PC_REGNO];
  pc = cpu.asregs.regs[PC_REGNO];
  insts = cpu.asregs.insts;
  insts = cpu.asregs.insts;
 
 
  /* Run instructions here. */
  /* Run instructions here. */
  do
  do
    {
    {
      opc = pc;
      opc = pc;
 
 
      /* Fetch the instruction at pc.  */
      /* Fetch the instruction at pc.  */
      inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
      inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
        + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
        + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
 
 
      /* Decode instruction.  */
      /* Decode instruction.  */
      if (inst & (1 << 15))
      if (inst & (1 << 15))
        {
        {
          if (inst & (1 << 14))
          if (inst & (1 << 14))
            {
            {
              /* This is a Form 3 instruction.  */
              /* This is a Form 3 instruction.  */
              int opcode = (inst >> 10 & 0xf);
              int opcode = (inst >> 10 & 0xf);
 
 
              switch (opcode)
              switch (opcode)
                {
                {
                case 0x00: /* beq */
                case 0x00: /* beq */
                  {
                  {
                    TRACE("beq");
                    TRACE("beq");
                    if (cpu.asregs.cc & CC_EQ)
                    if (cpu.asregs.cc & CC_EQ)
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x01: /* bne */
                case 0x01: /* bne */
                  {
                  {
                    TRACE("bne");
                    TRACE("bne");
                    if (! (cpu.asregs.cc & CC_EQ))
                    if (! (cpu.asregs.cc & CC_EQ))
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x02: /* blt */
                case 0x02: /* blt */
                  {
                  {
                    TRACE("blt");
                    TRACE("blt");
                    if (cpu.asregs.cc & CC_LT)
                    if (cpu.asregs.cc & CC_LT)
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }               break;
                  }               break;
                case 0x03: /* bgt */
                case 0x03: /* bgt */
                  {
                  {
                    TRACE("bgt");
                    TRACE("bgt");
                    if (cpu.asregs.cc & CC_GT)
                    if (cpu.asregs.cc & CC_GT)
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x04: /* bltu */
                case 0x04: /* bltu */
                  {
                  {
                    TRACE("bltu");
                    TRACE("bltu");
                    if (cpu.asregs.cc & CC_LTU)
                    if (cpu.asregs.cc & CC_LTU)
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x05: /* bgtu */
                case 0x05: /* bgtu */
                  {
                  {
                    TRACE("bgtu");
                    TRACE("bgtu");
                    if (cpu.asregs.cc & CC_GTU)
                    if (cpu.asregs.cc & CC_GTU)
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x06: /* bge */
                case 0x06: /* bge */
                  {
                  {
                    TRACE("bge");
                    TRACE("bge");
                    if (cpu.asregs.cc & (CC_GT | CC_EQ))
                    if (cpu.asregs.cc & (CC_GT | CC_EQ))
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x07: /* ble */
                case 0x07: /* ble */
                  {
                  {
                    TRACE("ble");
                    TRACE("ble");
                    if (cpu.asregs.cc & (CC_LT | CC_EQ))
                    if (cpu.asregs.cc & (CC_LT | CC_EQ))
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x08: /* bgeu */
                case 0x08: /* bgeu */
                  {
                  {
                    TRACE("bgeu");
                    TRACE("bgeu");
                    if (cpu.asregs.cc & (CC_GTU | CC_EQ))
                    if (cpu.asregs.cc & (CC_GTU | CC_EQ))
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                case 0x09: /* bleu */
                case 0x09: /* bleu */
                  {
                  {
                    TRACE("bleu");
                    TRACE("bleu");
                    if (cpu.asregs.cc & (CC_LTU | CC_EQ))
                    if (cpu.asregs.cc & (CC_LTU | CC_EQ))
                      pc += INST2OFFSET(inst) - 2;
                      pc += INST2OFFSET(inst) - 2;
                  }
                  }
                  break;
                  break;
                default:
                default:
                  {
                  {
                    TRACE("SIGILL3");
                    TRACE("SIGILL3");
                    cpu.asregs.exception = SIGILL;
                    cpu.asregs.exception = SIGILL;
                    break;
                    break;
                  }
                  }
                }
                }
            }
            }
          else
          else
            {
            {
              /* This is a Form 2 instruction.  */
              /* This is a Form 2 instruction.  */
              int opcode = (inst >> 12 & 0x3);
              int opcode = (inst >> 12 & 0x3);
              switch (opcode)
              switch (opcode)
                {
                {
                case 0x00: /* inc */
                case 0x00: /* inc */
                  {
                  {
                    int a = (inst >> 8) & 0xf;
                    int a = (inst >> 8) & 0xf;
                    unsigned av = cpu.asregs.regs[a];
                    unsigned av = cpu.asregs.regs[a];
                    unsigned v = (inst & 0xff);
                    unsigned v = (inst & 0xff);
                    TRACE("inc");
                    TRACE("inc");
                    cpu.asregs.regs[a] = av + v;
                    cpu.asregs.regs[a] = av + v;
                  }
                  }
                  break;
                  break;
                case 0x01: /* dec */
                case 0x01: /* dec */
                  {
                  {
                    int a = (inst >> 8) & 0xf;
                    int a = (inst >> 8) & 0xf;
                    unsigned av = cpu.asregs.regs[a];
                    unsigned av = cpu.asregs.regs[a];
                    unsigned v = (inst & 0xff);
                    unsigned v = (inst & 0xff);
                    TRACE("dec");
                    TRACE("dec");
                    cpu.asregs.regs[a] = av - v;
                    cpu.asregs.regs[a] = av - v;
                  }
                  }
                  break;
                  break;
                case 0x02: /* gsr */
                case 0x02: /* gsr */
                  {
                  {
                    int a = (inst >> 8) & 0xf;
                    int a = (inst >> 8) & 0xf;
                    unsigned v = (inst & 0xff);
                    unsigned v = (inst & 0xff);
                    TRACE("gsr");
                    TRACE("gsr");
                    cpu.asregs.regs[a] = cpu.asregs.sregs[v];
                    cpu.asregs.regs[a] = cpu.asregs.sregs[v];
                  }
                  }
                  break;
                  break;
                case 0x03: /* ssr */
                case 0x03: /* ssr */
                  {
                  {
                    int a = (inst >> 8) & 0xf;
                    int a = (inst >> 8) & 0xf;
                    unsigned v = (inst & 0xff);
                    unsigned v = (inst & 0xff);
                    TRACE("ssr");
                    TRACE("ssr");
                    cpu.asregs.sregs[v] = cpu.asregs.regs[a];
                    cpu.asregs.sregs[v] = cpu.asregs.regs[a];
                  }
                  }
                  break;
                  break;
                default:
                default:
                  TRACE("SIGILL2");
                  TRACE("SIGILL2");
                  cpu.asregs.exception = SIGILL;
                  cpu.asregs.exception = SIGILL;
                  break;
                  break;
                }
                }
            }
            }
        }
        }
      else
      else
        {
        {
          /* This is a Form 1 instruction.  */
          /* This is a Form 1 instruction.  */
          int opcode = inst >> 8;
          int opcode = inst >> 8;
          switch (opcode)
          switch (opcode)
            {
            {
            case 0x00: /* bad */
            case 0x00: /* bad */
              opc = opcode;
              opc = opcode;
              TRACE("SIGILL0");
              TRACE("SIGILL0");
              cpu.asregs.exception = SIGILL;
              cpu.asregs.exception = SIGILL;
              break;
              break;
            case 0x01: /* ldi.l (immediate) */
            case 0x01: /* ldi.l (immediate) */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                TRACE("ldi.l");
                TRACE("ldi.l");
                unsigned int val = EXTRACT_WORD(pc+2);
                unsigned int val = EXTRACT_WORD(pc+2);
                cpu.asregs.regs[reg] = val;
                cpu.asregs.regs[reg] = val;
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x02: /* mov (register-to-register) */
            case 0x02: /* mov (register-to-register) */
              {
              {
                int dest  = (inst >> 4) & 0xf;
                int dest  = (inst >> 4) & 0xf;
                int src = (inst ) & 0xf;
                int src = (inst ) & 0xf;
                TRACE("mov");
                TRACE("mov");
                cpu.asregs.regs[dest] = cpu.asregs.regs[src];
                cpu.asregs.regs[dest] = cpu.asregs.regs[src];
              }
              }
              break;
              break;
            case 0x03: /* jsra */
            case 0x03: /* jsra */
              {
              {
                unsigned int fn = EXTRACT_WORD(pc+2);
                unsigned int fn = EXTRACT_WORD(pc+2);
                unsigned int sp = cpu.asregs.regs[1];
                unsigned int sp = cpu.asregs.regs[1];
                TRACE("jsra");
                TRACE("jsra");
                /* Save a slot for the static chain.  */
                /* Save a slot for the static chain.  */
                sp -= 4;
                sp -= 4;
 
 
                /* Push the return address.  */
                /* Push the return address.  */
                sp -= 4;
                sp -= 4;
                wlat (scpu, opc, sp, pc + 6);
                wlat (scpu, opc, sp, pc + 6);
 
 
                /* Push the current frame pointer.  */
                /* Push the current frame pointer.  */
                sp -= 4;
                sp -= 4;
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
 
 
                /* Uncache the stack pointer and set the pc and $fp.  */
                /* Uncache the stack pointer and set the pc and $fp.  */
                cpu.asregs.regs[1] = sp;
                cpu.asregs.regs[1] = sp;
                cpu.asregs.regs[0] = sp;
                cpu.asregs.regs[0] = sp;
                pc = fn - 2;
                pc = fn - 2;
              }
              }
              break;
              break;
            case 0x04: /* ret */
            case 0x04: /* ret */
              {
              {
                unsigned int sp = cpu.asregs.regs[0];
                unsigned int sp = cpu.asregs.regs[0];
 
 
                TRACE("ret");
                TRACE("ret");
 
 
                /* Pop the frame pointer.  */
                /* Pop the frame pointer.  */
                cpu.asregs.regs[0] = rlat (scpu, opc, sp);
                cpu.asregs.regs[0] = rlat (scpu, opc, sp);
                sp += 4;
                sp += 4;
 
 
                /* Pop the return address.  */
                /* Pop the return address.  */
                pc = rlat (scpu, opc, sp) - 2;
                pc = rlat (scpu, opc, sp) - 2;
                sp += 4;
                sp += 4;
 
 
                /* Skip over the static chain slot.  */
                /* Skip over the static chain slot.  */
                sp += 4;
                sp += 4;
 
 
                /* Uncache the stack pointer.  */
                /* Uncache the stack pointer.  */
                cpu.asregs.regs[1] = sp;
                cpu.asregs.regs[1] = sp;
              }
              }
              break;
              break;
            case 0x05: /* add.l */
            case 0x05: /* add.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
                unsigned bv = cpu.asregs.regs[b];
                TRACE("add.l");
                TRACE("add.l");
                cpu.asregs.regs[a] = av + bv;
                cpu.asregs.regs[a] = av + bv;
              }
              }
              break;
              break;
            case 0x06: /* push */
            case 0x06: /* push */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int sp = cpu.asregs.regs[a] - 4;
                int sp = cpu.asregs.regs[a] - 4;
                TRACE("push");
                TRACE("push");
                wlat (scpu, opc, sp, cpu.asregs.regs[b]);
                wlat (scpu, opc, sp, cpu.asregs.regs[b]);
                cpu.asregs.regs[a] = sp;
                cpu.asregs.regs[a] = sp;
              }
              }
              break;
              break;
            case 0x07: /* pop */
            case 0x07: /* pop */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int sp = cpu.asregs.regs[a];
                int sp = cpu.asregs.regs[a];
                TRACE("pop");
                TRACE("pop");
                cpu.asregs.regs[b] = rlat (scpu, opc, sp);
                cpu.asregs.regs[b] = rlat (scpu, opc, sp);
                cpu.asregs.regs[a] = sp + 4;
                cpu.asregs.regs[a] = sp + 4;
              }
              }
              break;
              break;
            case 0x08: /* lda.l */
            case 0x08: /* lda.l */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("lda.l");
                TRACE("lda.l");
                cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
                cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x09: /* sta.l */
            case 0x09: /* sta.l */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("sta.l");
                TRACE("sta.l");
                wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
                wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x0a: /* ld.l (register indirect) */
            case 0x0a: /* ld.l (register indirect) */
              {
              {
                int src  = inst & 0xf;
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
                int xv;
                TRACE("ld.l");
                TRACE("ld.l");
                xv = cpu.asregs.regs[src];
                xv = cpu.asregs.regs[src];
                cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
                cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
              }
              }
              break;
              break;
            case 0x0b: /* st.l */
            case 0x0b: /* st.l */
              {
              {
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
                int val  = inst & 0xf;
                TRACE("st.l");
                TRACE("st.l");
                wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
                wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              }
              break;
              break;
            case 0x0c: /* ldo.l */
            case 0x0c: /* ldo.l */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("ldo.l");
                TRACE("ldo.l");
                addr += cpu.asregs.regs[b];
                addr += cpu.asregs.regs[b];
                cpu.asregs.regs[a] = rlat (scpu, opc, addr);
                cpu.asregs.regs[a] = rlat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x0d: /* sto.l */
            case 0x0d: /* sto.l */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("sto.l");
                TRACE("sto.l");
                addr += cpu.asregs.regs[a];
                addr += cpu.asregs.regs[a];
                wlat (scpu, opc, addr, cpu.asregs.regs[b]);
                wlat (scpu, opc, addr, cpu.asregs.regs[b]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x0e: /* cmp */
            case 0x0e: /* cmp */
              {
              {
                int a  = (inst >> 4) & 0xf;
                int a  = (inst >> 4) & 0xf;
                int b  = inst & 0xf;
                int b  = inst & 0xf;
                int cc = 0;
                int cc = 0;
                int va = cpu.asregs.regs[a];
                int va = cpu.asregs.regs[a];
                int vb = cpu.asregs.regs[b];
                int vb = cpu.asregs.regs[b];
 
 
                TRACE("cmp");
                TRACE("cmp");
 
 
                if (va == vb)
                if (va == vb)
                  cc = CC_EQ;
                  cc = CC_EQ;
                else
                else
                  {
                  {
                    cc |= (va < vb ? CC_LT : 0);
                    cc |= (va < vb ? CC_LT : 0);
                    cc |= (va > vb ? CC_GT : 0);
                    cc |= (va > vb ? CC_GT : 0);
                    cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
                    cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
                    cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
                    cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
                  }
                  }
 
 
                cpu.asregs.cc = cc;
                cpu.asregs.cc = cc;
              }
              }
              break;
              break;
            case 0x0f: /* nop */
            case 0x0f: /* nop */
              break;
              break;
            case 0x10: /* bad */
            case 0x10: /* bad */
            case 0x11: /* bad */
            case 0x11: /* bad */
            case 0x12: /* bad */
            case 0x12: /* bad */
            case 0x13: /* bad */
            case 0x13: /* bad */
            case 0x14: /* bad */
            case 0x14: /* bad */
            case 0x15: /* bad */
            case 0x15: /* bad */
            case 0x16: /* bad */
            case 0x16: /* bad */
            case 0x17: /* bad */
            case 0x17: /* bad */
            case 0x18: /* bad */
            case 0x18: /* bad */
              {
              {
                opc = opcode;
                opc = opcode;
                TRACE("SIGILL0");
                TRACE("SIGILL0");
                cpu.asregs.exception = SIGILL;
                cpu.asregs.exception = SIGILL;
                break;
                break;
              }
              }
            case 0x19: /* jsr */
            case 0x19: /* jsr */
              {
              {
                unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
                unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
                unsigned int sp = cpu.asregs.regs[1];
                unsigned int sp = cpu.asregs.regs[1];
 
 
                TRACE("jsr");
                TRACE("jsr");
 
 
                /* Save a slot for the static chain.  */
                /* Save a slot for the static chain.  */
                sp -= 4;
                sp -= 4;
 
 
                /* Push the return address.  */
                /* Push the return address.  */
                sp -= 4;
                sp -= 4;
                wlat (scpu, opc, sp, pc + 2);
                wlat (scpu, opc, sp, pc + 2);
 
 
                /* Push the current frame pointer.  */
                /* Push the current frame pointer.  */
                sp -= 4;
                sp -= 4;
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
 
 
                /* Uncache the stack pointer and set the fp & pc.  */
                /* Uncache the stack pointer and set the fp & pc.  */
                cpu.asregs.regs[1] = sp;
                cpu.asregs.regs[1] = sp;
                cpu.asregs.regs[0] = sp;
                cpu.asregs.regs[0] = sp;
                pc = fn - 2;
                pc = fn - 2;
              }
              }
              break;
              break;
            case 0x1a: /* jmpa */
            case 0x1a: /* jmpa */
              {
              {
                unsigned int tgt = EXTRACT_WORD(pc+2);
                unsigned int tgt = EXTRACT_WORD(pc+2);
                TRACE("jmpa");
                TRACE("jmpa");
                pc = tgt - 2;
                pc = tgt - 2;
              }
              }
              break;
              break;
            case 0x1b: /* ldi.b (immediate) */
            case 0x1b: /* ldi.b (immediate) */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
 
 
                unsigned int val = EXTRACT_WORD(pc+2);
                unsigned int val = EXTRACT_WORD(pc+2);
                TRACE("ldi.b");
                TRACE("ldi.b");
                cpu.asregs.regs[reg] = val;
                cpu.asregs.regs[reg] = val;
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x1c: /* ld.b (register indirect) */
            case 0x1c: /* ld.b (register indirect) */
              {
              {
                int src  = inst & 0xf;
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
                int xv;
                TRACE("ld.b");
                TRACE("ld.b");
                xv = cpu.asregs.regs[src];
                xv = cpu.asregs.regs[src];
                cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
                cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
              }
              }
              break;
              break;
            case 0x1d: /* lda.b */
            case 0x1d: /* lda.b */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("lda.b");
                TRACE("lda.b");
                cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
                cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x1e: /* st.b */
            case 0x1e: /* st.b */
              {
              {
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
                int val  = inst & 0xf;
                TRACE("st.b");
                TRACE("st.b");
                wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
                wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              }
              break;
              break;
            case 0x1f: /* sta.b */
            case 0x1f: /* sta.b */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("sta.b");
                TRACE("sta.b");
                wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
                wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x20: /* ldi.s (immediate) */
            case 0x20: /* ldi.s (immediate) */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
 
 
                unsigned int val = EXTRACT_WORD(pc+2);
                unsigned int val = EXTRACT_WORD(pc+2);
                TRACE("ldi.s");
                TRACE("ldi.s");
                cpu.asregs.regs[reg] = val;
                cpu.asregs.regs[reg] = val;
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x21: /* ld.s (register indirect) */
            case 0x21: /* ld.s (register indirect) */
              {
              {
                int src  = inst & 0xf;
                int src  = inst & 0xf;
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int xv;
                int xv;
                TRACE("ld.s");
                TRACE("ld.s");
                xv = cpu.asregs.regs[src];
                xv = cpu.asregs.regs[src];
                cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
                cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
              }
              }
              break;
              break;
            case 0x22: /* lda.s */
            case 0x22: /* lda.s */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("lda.s");
                TRACE("lda.s");
                cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
                cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x23: /* st.s */
            case 0x23: /* st.s */
              {
              {
                int dest = (inst >> 4) & 0xf;
                int dest = (inst >> 4) & 0xf;
                int val  = inst & 0xf;
                int val  = inst & 0xf;
                TRACE("st.s");
                TRACE("st.s");
                wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
                wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
              }
              }
              break;
              break;
            case 0x24: /* sta.s */
            case 0x24: /* sta.s */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                TRACE("sta.s");
                TRACE("sta.s");
                wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
                wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x25: /* jmp */
            case 0x25: /* jmp */
              {
              {
                int reg = (inst >> 4) & 0xf;
                int reg = (inst >> 4) & 0xf;
                TRACE("jmp");
                TRACE("jmp");
                pc = cpu.asregs.regs[reg] - 2;
                pc = cpu.asregs.regs[reg] - 2;
              }
              }
              break;
              break;
            case 0x26: /* and */
            case 0x26: /* and */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av, bv;
                int av, bv;
                TRACE("and");
                TRACE("and");
                av = cpu.asregs.regs[a];
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
                bv = cpu.asregs.regs[b];
                cpu.asregs.regs[a] = av & bv;
                cpu.asregs.regs[a] = av & bv;
              }
              }
              break;
              break;
            case 0x27: /* lshr */
            case 0x27: /* lshr */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("lshr");
                TRACE("lshr");
                cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
                cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
              }
              }
              break;
              break;
            case 0x28: /* ashl */
            case 0x28: /* ashl */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("ashl");
                TRACE("ashl");
                cpu.asregs.regs[a] = av << bv;
                cpu.asregs.regs[a] = av << bv;
              }
              }
              break;
              break;
            case 0x29: /* sub.l */
            case 0x29: /* sub.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
                unsigned bv = cpu.asregs.regs[b];
                TRACE("sub.l");
                TRACE("sub.l");
                cpu.asregs.regs[a] = av - bv;
                cpu.asregs.regs[a] = av - bv;
              }
              }
              break;
              break;
            case 0x2a: /* neg */
            case 0x2a: /* neg */
              {
              {
                int a  = (inst >> 4) & 0xf;
                int a  = (inst >> 4) & 0xf;
                int b  = inst & 0xf;
                int b  = inst & 0xf;
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("neg");
                TRACE("neg");
                cpu.asregs.regs[a] = - bv;
                cpu.asregs.regs[a] = - bv;
              }
              }
              break;
              break;
            case 0x2b: /* or */
            case 0x2b: /* or */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av, bv;
                int av, bv;
                TRACE("or");
                TRACE("or");
                av = cpu.asregs.regs[a];
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
                bv = cpu.asregs.regs[b];
                cpu.asregs.regs[a] = av | bv;
                cpu.asregs.regs[a] = av | bv;
              }
              }
              break;
              break;
            case 0x2c: /* not */
            case 0x2c: /* not */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("not");
                TRACE("not");
                cpu.asregs.regs[a] = 0xffffffff ^ bv;
                cpu.asregs.regs[a] = 0xffffffff ^ bv;
              }
              }
              break;
              break;
            case 0x2d: /* ashr */
            case 0x2d: /* ashr */
              {
              {
                int a  = (inst >> 4) & 0xf;
                int a  = (inst >> 4) & 0xf;
                int b  = inst & 0xf;
                int b  = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("ashr");
                TRACE("ashr");
                cpu.asregs.regs[a] = av >> bv;
                cpu.asregs.regs[a] = av >> bv;
              }
              }
              break;
              break;
            case 0x2e: /* xor */
            case 0x2e: /* xor */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av, bv;
                int av, bv;
                TRACE("xor");
                TRACE("xor");
                av = cpu.asregs.regs[a];
                av = cpu.asregs.regs[a];
                bv = cpu.asregs.regs[b];
                bv = cpu.asregs.regs[b];
                cpu.asregs.regs[a] = av ^ bv;
                cpu.asregs.regs[a] = av ^ bv;
              }
              }
              break;
              break;
            case 0x2f: /* mul.l */
            case 0x2f: /* mul.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                unsigned av = cpu.asregs.regs[a];
                unsigned av = cpu.asregs.regs[a];
                unsigned bv = cpu.asregs.regs[b];
                unsigned bv = cpu.asregs.regs[b];
                TRACE("mul.l");
                TRACE("mul.l");
                cpu.asregs.regs[a] = av * bv;
                cpu.asregs.regs[a] = av * bv;
              }
              }
              break;
              break;
            case 0x30: /* swi */
            case 0x30: /* swi */
              {
              {
                unsigned int inum = EXTRACT_WORD(pc+2);
                unsigned int inum = EXTRACT_WORD(pc+2);
                TRACE("swi");
                TRACE("swi");
                /* Set the special registers appropriately.  */
                /* Set the special registers appropriately.  */
                cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
                cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
                cpu.asregs.sregs[3] = inum;
                cpu.asregs.sregs[3] = inum;
                switch (inum)
                switch (inum)
                  {
                  {
                  case 0x1: /* SYS_exit */
                  case 0x1: /* SYS_exit */
                    {
                    {
                      cpu.asregs.exception = SIGQUIT;
                      cpu.asregs.exception = SIGQUIT;
                      break;
                      break;
                    }
                    }
                  case 0x2: /* SYS_open */
                  case 0x2: /* SYS_open */
                    {
                    {
                      char fname[1024];
                      char fname[1024];
                      int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
                      int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
                      int perm = (int) cpu.asregs.regs[4];
                      int perm = (int) cpu.asregs.regs[4];
                      int fd = open (fname, mode, perm);
                      int fd = open (fname, mode, perm);
                      sim_core_read_buffer (sd, scpu, read_map, fname,
                      sim_core_read_buffer (sd, scpu, read_map, fname,
                                            cpu.asregs.regs[2], 1024);
                                            cpu.asregs.regs[2], 1024);
                      /* FIXME - set errno */
                      /* FIXME - set errno */
                      cpu.asregs.regs[2] = fd;
                      cpu.asregs.regs[2] = fd;
                      break;
                      break;
                    }
                    }
                  case 0x4: /* SYS_read */
                  case 0x4: /* SYS_read */
                    {
                    {
                      int fd = cpu.asregs.regs[2];
                      int fd = cpu.asregs.regs[2];
                      unsigned len = (unsigned) cpu.asregs.regs[4];
                      unsigned len = (unsigned) cpu.asregs.regs[4];
                      char *buf = malloc (len);
                      char *buf = malloc (len);
                      cpu.asregs.regs[2] = read (fd, buf, len);
                      cpu.asregs.regs[2] = read (fd, buf, len);
                      sim_core_write_buffer (sd, scpu, write_map, buf,
                      sim_core_write_buffer (sd, scpu, write_map, buf,
                                             cpu.asregs.regs[3], len);
                                             cpu.asregs.regs[3], len);
                      free (buf);
                      free (buf);
                      break;
                      break;
                    }
                    }
                  case 0x5: /* SYS_write */
                  case 0x5: /* SYS_write */
                    {
                    {
                      char *str;
                      char *str;
                      /* String length is at 0x12($fp) */
                      /* String length is at 0x12($fp) */
                      unsigned count, len = (unsigned) cpu.asregs.regs[4];
                      unsigned count, len = (unsigned) cpu.asregs.regs[4];
                      str = malloc (len);
                      str = malloc (len);
                      sim_core_read_buffer (sd, scpu, read_map, str,
                      sim_core_read_buffer (sd, scpu, read_map, str,
                                            cpu.asregs.regs[3], len);
                                            cpu.asregs.regs[3], len);
                      count = write (cpu.asregs.regs[2], str, len);
                      count = write (cpu.asregs.regs[2], str, len);
                      free (str);
                      free (str);
                      cpu.asregs.regs[2] = count;
                      cpu.asregs.regs[2] = count;
                      break;
                      break;
                    }
                    }
                  case 0xffffffff: /* Linux System Call */
                  case 0xffffffff: /* Linux System Call */
                    {
                    {
                      unsigned int handler = cpu.asregs.sregs[1];
                      unsigned int handler = cpu.asregs.sregs[1];
                      unsigned int sp = cpu.asregs.regs[1];
                      unsigned int sp = cpu.asregs.regs[1];
 
 
                      /* Save a slot for the static chain.  */
                      /* Save a slot for the static chain.  */
                      sp -= 4;
                      sp -= 4;
 
 
                      /* Push the return address.  */
                      /* Push the return address.  */
                      sp -= 4;
                      sp -= 4;
                      wlat (scpu, opc, sp, pc + 6);
                      wlat (scpu, opc, sp, pc + 6);
 
 
                      /* Push the current frame pointer.  */
                      /* Push the current frame pointer.  */
                      sp -= 4;
                      sp -= 4;
                      wlat (scpu, opc, sp, cpu.asregs.regs[0]);
                      wlat (scpu, opc, sp, cpu.asregs.regs[0]);
 
 
                      /* Uncache the stack pointer and set the fp & pc.  */
                      /* Uncache the stack pointer and set the fp & pc.  */
                      cpu.asregs.regs[1] = sp;
                      cpu.asregs.regs[1] = sp;
                      cpu.asregs.regs[0] = sp;
                      cpu.asregs.regs[0] = sp;
                      pc = handler - 6;
                      pc = handler - 6;
                    }
                    }
                  default:
                  default:
                    break;
                    break;
                  }
                  }
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x31: /* div.l */
            case 0x31: /* div.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("div.l");
                TRACE("div.l");
                cpu.asregs.regs[a] = av / bv;
                cpu.asregs.regs[a] = av / bv;
              }
              }
              break;
              break;
            case 0x32: /* udiv.l */
            case 0x32: /* udiv.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                unsigned int av = cpu.asregs.regs[a];
                unsigned int av = cpu.asregs.regs[a];
                unsigned int bv = cpu.asregs.regs[b];
                unsigned int bv = cpu.asregs.regs[b];
                TRACE("udiv.l");
                TRACE("udiv.l");
                cpu.asregs.regs[a] = (av / bv);
                cpu.asregs.regs[a] = (av / bv);
              }
              }
              break;
              break;
            case 0x33: /* mod.l */
            case 0x33: /* mod.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                int av = cpu.asregs.regs[a];
                int av = cpu.asregs.regs[a];
                int bv = cpu.asregs.regs[b];
                int bv = cpu.asregs.regs[b];
                TRACE("mod.l");
                TRACE("mod.l");
                cpu.asregs.regs[a] = av % bv;
                cpu.asregs.regs[a] = av % bv;
              }
              }
              break;
              break;
            case 0x34: /* umod.l */
            case 0x34: /* umod.l */
              {
              {
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                unsigned int av = cpu.asregs.regs[a];
                unsigned int av = cpu.asregs.regs[a];
                unsigned int bv = cpu.asregs.regs[b];
                unsigned int bv = cpu.asregs.regs[b];
                TRACE("umod.l");
                TRACE("umod.l");
                cpu.asregs.regs[a] = (av % bv);
                cpu.asregs.regs[a] = (av % bv);
              }
              }
              break;
              break;
            case 0x35: /* brk */
            case 0x35: /* brk */
              TRACE("brk");
              TRACE("brk");
              cpu.asregs.exception = SIGTRAP;
              cpu.asregs.exception = SIGTRAP;
              pc -= 2; /* Adjust pc */
              pc -= 2; /* Adjust pc */
              break;
              break;
            case 0x36: /* ldo.b */
            case 0x36: /* ldo.b */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("ldo.b");
                TRACE("ldo.b");
                addr += cpu.asregs.regs[b];
                addr += cpu.asregs.regs[b];
                cpu.asregs.regs[a] = rbat (scpu, opc, addr);
                cpu.asregs.regs[a] = rbat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x37: /* sto.b */
            case 0x37: /* sto.b */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("sto.b");
                TRACE("sto.b");
                addr += cpu.asregs.regs[a];
                addr += cpu.asregs.regs[a];
                wbat (scpu, opc, addr, cpu.asregs.regs[b]);
                wbat (scpu, opc, addr, cpu.asregs.regs[b]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x38: /* ldo.s */
            case 0x38: /* ldo.s */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("ldo.s");
                TRACE("ldo.s");
                addr += cpu.asregs.regs[b];
                addr += cpu.asregs.regs[b];
                cpu.asregs.regs[a] = rsat (scpu, opc, addr);
                cpu.asregs.regs[a] = rsat (scpu, opc, addr);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            case 0x39: /* sto.s */
            case 0x39: /* sto.s */
              {
              {
                unsigned int addr = EXTRACT_WORD(pc+2);
                unsigned int addr = EXTRACT_WORD(pc+2);
                int a = (inst >> 4) & 0xf;
                int a = (inst >> 4) & 0xf;
                int b = inst & 0xf;
                int b = inst & 0xf;
                TRACE("sto.s");
                TRACE("sto.s");
                addr += cpu.asregs.regs[a];
                addr += cpu.asregs.regs[a];
                wsat (scpu, opc, addr, cpu.asregs.regs[b]);
                wsat (scpu, opc, addr, cpu.asregs.regs[b]);
                pc += 4;
                pc += 4;
              }
              }
              break;
              break;
            default:
            default:
              opc = opcode;
              opc = opcode;
              TRACE("SIGILL1");
              TRACE("SIGILL1");
              cpu.asregs.exception = SIGILL;
              cpu.asregs.exception = SIGILL;
              break;
              break;
            }
            }
        }
        }
 
 
      insts++;
      insts++;
      pc += 2;
      pc += 2;
 
 
    } while (!cpu.asregs.exception);
    } while (!cpu.asregs.exception);
 
 
  /* Hide away the things we've cached while executing.  */
  /* Hide away the things we've cached while executing.  */
  cpu.asregs.regs[PC_REGNO] = pc;
  cpu.asregs.regs[PC_REGNO] = pc;
  cpu.asregs.insts += insts;            /* instructions done ... */
  cpu.asregs.insts += insts;            /* instructions done ... */
 
 
  signal (SIGINT, sigsave);
  signal (SIGINT, sigsave);
}
}
 
 
int
int
sim_write (sd, addr, buffer, size)
sim_write (sd, addr, buffer, size)
     SIM_DESC sd;
     SIM_DESC sd;
     SIM_ADDR addr;
     SIM_ADDR addr;
     const unsigned char * buffer;
     const unsigned char * buffer;
     int size;
     int size;
{
{
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
 
 
  sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
  sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
 
 
  return size;
  return size;
}
}
 
 
int
int
sim_read (sd, addr, buffer, size)
sim_read (sd, addr, buffer, size)
     SIM_DESC sd;
     SIM_DESC sd;
     SIM_ADDR addr;
     SIM_ADDR addr;
     unsigned char * buffer;
     unsigned char * buffer;
     int size;
     int size;
{
{
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
 
 
  sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
  sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
 
 
  return size;
  return size;
}
}
 
 
 
 
int
int
sim_store_register (sd, rn, memory, length)
sim_store_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char * memory;
     unsigned char * memory;
     int length;
     int length;
{
{
  if (rn < NUM_MOXIE_REGS && rn >= 0)
  if (rn < NUM_MOXIE_REGS && rn >= 0)
    {
    {
      if (length == 4)
      if (length == 4)
        {
        {
          long ival;
          long ival;
 
 
          /* misalignment safe */
          /* misalignment safe */
          ival = moxie_extract_unsigned_integer (memory, 4);
          ival = moxie_extract_unsigned_integer (memory, 4);
          cpu.asints[rn] = ival;
          cpu.asints[rn] = ival;
        }
        }
 
 
      return 4;
      return 4;
    }
    }
  else
  else
    return 0;
    return 0;
}
}
 
 
int
int
sim_fetch_register (sd, rn, memory, length)
sim_fetch_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char * memory;
     unsigned char * memory;
     int length;
     int length;
{
{
  if (rn < NUM_MOXIE_REGS && rn >= 0)
  if (rn < NUM_MOXIE_REGS && rn >= 0)
    {
    {
      if (length == 4)
      if (length == 4)
        {
        {
          long ival = cpu.asints[rn];
          long ival = cpu.asints[rn];
 
 
          /* misalignment-safe */
          /* misalignment-safe */
          moxie_store_unsigned_integer (memory, 4, ival);
          moxie_store_unsigned_integer (memory, 4, ival);
        }
        }
 
 
      return 4;
      return 4;
    }
    }
  else
  else
    return 0;
    return 0;
}
}
 
 
 
 
int
int
sim_trace (sd)
sim_trace (sd)
     SIM_DESC sd;
     SIM_DESC sd;
{
{
  if (tracefile == 0)
  if (tracefile == 0)
    tracefile = fopen("trace.csv", "wb");
    tracefile = fopen("trace.csv", "wb");
 
 
  tracing = 1;
  tracing = 1;
 
 
  sim_resume (sd, 0, 0);
  sim_resume (sd, 0, 0);
 
 
  tracing = 0;
  tracing = 0;
 
 
  return 1;
  return 1;
}
}
 
 
void
void
sim_stop_reason (sd, reason, sigrc)
sim_stop_reason (sd, reason, sigrc)
     SIM_DESC sd;
     SIM_DESC sd;
     enum sim_stop * reason;
     enum sim_stop * reason;
     int * sigrc;
     int * sigrc;
{
{
  if (cpu.asregs.exception == SIGQUIT)
  if (cpu.asregs.exception == SIGQUIT)
    {
    {
      * reason = sim_exited;
      * reason = sim_exited;
      * sigrc = cpu.asregs.regs[2];
      * sigrc = cpu.asregs.regs[2];
    }
    }
  else
  else
    {
    {
      * reason = sim_stopped;
      * reason = sim_stopped;
      * sigrc = cpu.asregs.exception;
      * sigrc = cpu.asregs.exception;
    }
    }
}
}
 
 
 
 
int
int
sim_stop (sd)
sim_stop (sd)
     SIM_DESC sd;
     SIM_DESC sd;
{
{
  cpu.asregs.exception = SIGINT;
  cpu.asregs.exception = SIGINT;
  return 1;
  return 1;
}
}
 
 
 
 
void
void
sim_info (sd, verbose)
sim_info (sd, verbose)
     SIM_DESC sd;
     SIM_DESC sd;
     int verbose;
     int verbose;
{
{
  callback->printf_filtered (callback, "\n\n# instructions executed  %llu\n",
  callback->printf_filtered (callback, "\n\n# instructions executed  %llu\n",
                             cpu.asregs.insts);
                             cpu.asregs.insts);
}
}
 
 
 
 
SIM_DESC
SIM_DESC
sim_open (kind, cb, abfd, argv)
sim_open (kind, cb, abfd, argv)
     SIM_OPEN_KIND kind;
     SIM_OPEN_KIND kind;
     host_callback * cb;
     host_callback * cb;
     struct bfd * abfd;
     struct bfd * abfd;
     char ** argv;
     char ** argv;
{
{
  SIM_DESC sd = sim_state_alloc (kind, cb);
  SIM_DESC sd = sim_state_alloc (kind, cb);
  printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
  printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
 
 
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    return 0;
    return 0;
 
 
  sim_do_command(sd," memory region 0x00000000,0x4000000") ;
  sim_do_command(sd," memory region 0x00000000,0x4000000") ;
  sim_do_command(sd," memory region 0xE0000000,0x10000") ;
  sim_do_command(sd," memory region 0xE0000000,0x10000") ;
 
 
  myname = argv[0];
  myname = argv[0];
  callback = cb;
  callback = cb;
 
 
  if (kind == SIM_OPEN_STANDALONE)
  if (kind == SIM_OPEN_STANDALONE)
    issue_messages = 1;
    issue_messages = 1;
 
 
  set_initial_gprs ();  /* Reset the GPR registers.  */
  set_initial_gprs ();  /* Reset the GPR registers.  */
 
 
  /* Configure/verify the target byte order and other runtime
  /* Configure/verify the target byte order and other runtime
     configuration options.  */
     configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
  if (sim_config (sd) != SIM_RC_OK)
    {
    {
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
  if (sim_post_argv_init (sd) != SIM_RC_OK)
  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
    {
      /* Uninstall the modules to avoid memory leaks,
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
         file descriptor leaks, etc.  */
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
  return sd;
  return sd;
}
}
 
 
void
void
sim_close (sd, quitting)
sim_close (sd, quitting)
     SIM_DESC sd;
     SIM_DESC sd;
     int quitting;
     int quitting;
{
{
  /* nothing to do */
  /* nothing to do */
}
}
 
 
 
 
/* Load the device tree blob.  */
/* Load the device tree blob.  */
 
 
static void
static void
load_dtb (SIM_DESC sd, const char *filename)
load_dtb (SIM_DESC sd, const char *filename)
{
{
  int size = 0;
  int size = 0;
  FILE *f = fopen (filename, "rb");
  FILE *f = fopen (filename, "rb");
  char *buf;
  char *buf;
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
 if (f == NULL)
 if (f == NULL)
    {
    {
      printf ("WARNING: ``%s'' could not be opened.\n", filename);
      printf ("WARNING: ``%s'' could not be opened.\n", filename);
      return;
      return;
    }
    }
  fseek (f, 0, SEEK_END);
  fseek (f, 0, SEEK_END);
  size = ftell(f);
  size = ftell(f);
  fseek (f, 0, SEEK_SET);
  fseek (f, 0, SEEK_SET);
  buf = alloca (size);
  buf = alloca (size);
  if (size != fread (buf, 1, size, f))
  if (size != fread (buf, 1, size, f))
    {
    {
      printf ("ERROR: error reading ``%s''.\n", filename);
      printf ("ERROR: error reading ``%s''.\n", filename);
      return;
      return;
    }
    }
  sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
  sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
  cpu.asregs.sregs[9] = 0xE0000000;
  cpu.asregs.sregs[9] = 0xE0000000;
  fclose (f);
  fclose (f);
}
}
 
 
SIM_RC
SIM_RC
sim_load (sd, prog, abfd, from_tty)
sim_load (sd, prog, abfd, from_tty)
     SIM_DESC sd;
     SIM_DESC sd;
     char * prog;
     char * prog;
     bfd * abfd;
     bfd * abfd;
     int from_tty;
     int from_tty;
{
{
 
 
  /* Do the right thing for ELF executables; this turns out to be
  /* Do the right thing for ELF executables; this turns out to be
     just about the right thing for any object format that:
     just about the right thing for any object format that:
       - we crack using BFD routines
       - we crack using BFD routines
       - follows the traditional UNIX text/data/bss layout
       - follows the traditional UNIX text/data/bss layout
       - calls the bss section ".bss".   */
       - calls the bss section ".bss".   */
 
 
  extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
  extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
  bfd * prog_bfd;
  bfd * prog_bfd;
 
 
  {
  {
    bfd * handle;
    bfd * handle;
    handle = bfd_openr (prog, 0);        /* could be "moxie" */
    handle = bfd_openr (prog, 0);        /* could be "moxie" */
 
 
    if (!handle)
    if (!handle)
      {
      {
        printf("``%s'' could not be opened.\n", prog);
        printf("``%s'' could not be opened.\n", prog);
        return SIM_RC_FAIL;
        return SIM_RC_FAIL;
      }
      }
 
 
    /* Makes sure that we have an object file, also cleans gets the
    /* Makes sure that we have an object file, also cleans gets the
       section headers in place.  */
       section headers in place.  */
    if (!bfd_check_format (handle, bfd_object))
    if (!bfd_check_format (handle, bfd_object))
      {
      {
        /* wasn't an object file */
        /* wasn't an object file */
        bfd_close (handle);
        bfd_close (handle);
        printf ("``%s'' is not appropriate object file.\n", prog);
        printf ("``%s'' is not appropriate object file.\n", prog);
        return SIM_RC_FAIL;
        return SIM_RC_FAIL;
      }
      }
 
 
    /* Clean up after ourselves.  */
    /* Clean up after ourselves.  */
    bfd_close (handle);
    bfd_close (handle);
  }
  }
 
 
  /* from sh -- dac */
  /* from sh -- dac */
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
                            sim_kind == SIM_OPEN_DEBUG,
                            sim_kind == SIM_OPEN_DEBUG,
                            0, sim_write);
                            0, sim_write);
  if (prog_bfd == NULL)
  if (prog_bfd == NULL)
    return SIM_RC_FAIL;
    return SIM_RC_FAIL;
 
 
  if (abfd == NULL)
  if (abfd == NULL)
    bfd_close (prog_bfd);
    bfd_close (prog_bfd);
 
 
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
SIM_RC
SIM_RC
sim_create_inferior (sd, prog_bfd, argv, env)
sim_create_inferior (sd, prog_bfd, argv, env)
     SIM_DESC sd;
     SIM_DESC sd;
     struct bfd * prog_bfd;
     struct bfd * prog_bfd;
     char ** argv;
     char ** argv;
     char ** env;
     char ** env;
{
{
  char ** avp;
  char ** avp;
  int l, argc, i, tp;
  int l, argc, i, tp;
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
 
 
  /* Set the initial register set.  */
  /* Set the initial register set.  */
  l = issue_messages;
  l = issue_messages;
  issue_messages = 0;
  issue_messages = 0;
  set_initial_gprs ();
  set_initial_gprs ();
  issue_messages = l;
  issue_messages = l;
 
 
  if (prog_bfd != NULL)
  if (prog_bfd != NULL)
    cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
    cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
 
 
  /* Copy args into target memory.  */
  /* Copy args into target memory.  */
  avp = argv;
  avp = argv;
  for (argc = 0; avp && *avp; avp++)
  for (argc = 0; avp && *avp; avp++)
    argc++;
    argc++;
 
 
  /* Target memory looks like this:
  /* Target memory looks like this:
     0x00000000 zero word
     0x00000000 zero word
     0x00000004 argc word
     0x00000004 argc word
     0x00000008 start of argv
     0x00000008 start of argv
     .
     .
     0x0000???? end of argv
     0x0000???? end of argv
     0x0000???? zero word
     0x0000???? zero word
     0x0000???? start of data pointed to by argv  */
     0x0000???? start of data pointed to by argv  */
 
 
  wlat (scpu, 0, 0, 0);
  wlat (scpu, 0, 0, 0);
  wlat (scpu, 0, 4, argc);
  wlat (scpu, 0, 4, argc);
 
 
  /* tp is the offset of our first argv data.  */
  /* tp is the offset of our first argv data.  */
  tp = 4 + 4 + argc * 4 + 4;
  tp = 4 + 4 + argc * 4 + 4;
 
 
  for (i = 0; i < argc; i++)
  for (i = 0; i < argc; i++)
    {
    {
      /* Set the argv value.  */
      /* Set the argv value.  */
      wlat (scpu, 0, 4 + 4 + i * 4, tp);
      wlat (scpu, 0, 4 + 4 + i * 4, tp);
 
 
      /* Store the string.  */
      /* Store the string.  */
      sim_core_write_buffer (sd, scpu, write_map, argv[i],
      sim_core_write_buffer (sd, scpu, write_map, argv[i],
                             tp, strlen(argv[i])+1);
                             tp, strlen(argv[i])+1);
      tp += strlen (argv[i]) + 1;
      tp += strlen (argv[i]) + 1;
    }
    }
 
 
  wlat (scpu, 0, 4 + 4 + i * 4, 0);
  wlat (scpu, 0, 4 + 4 + i * 4, 0);
 
 
  load_dtb (sd, DTB);
  load_dtb (sd, DTB);
 
 
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
void
void
sim_kill (sd)
sim_kill (sd)
     SIM_DESC sd;
     SIM_DESC sd;
{
{
  if (tracefile)
  if (tracefile)
    fclose(tracefile);
    fclose(tracefile);
}
}
 
 
void
void
sim_do_command (sd, cmd)
sim_do_command (sd, cmd)
     SIM_DESC sd;
     SIM_DESC sd;
     char * cmd;
     char * cmd;
{
{
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
    sim_io_printf (sd,
    sim_io_printf (sd,
                   "Error: \"%s\" is not a valid moxie simulator command.\n",
                   "Error: \"%s\" is not a valid moxie simulator command.\n",
                   cmd);
                   cmd);
}
}
 
 
void
void
sim_set_callbacks (ptr)
sim_set_callbacks (ptr)
     host_callback * ptr;
     host_callback * ptr;
{
{
  callback = ptr;
  callback = ptr;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.