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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [microblaze/] [interp.c] - Diff between revs 227 and 816

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

Rev 227 Rev 816
/* Simulator for Xilinx MicroBlaze processor
/* Simulator for Xilinx MicroBlaze processor
   Copyright 2009, 2010 Free Software Foundation, Inc.
   Copyright 2009, 2010 Free Software Foundation, Inc.
 
 
   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 2 of the License, or
   the Free Software Foundation; either version 2 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, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */
   02110-1301, USA.  */
 
 
#include <signal.h>
#include <signal.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-utils.h"
#include "sim-utils.h"
#include "microblaze-dis.h"
#include "microblaze-dis.h"
 
 
 
 
#ifndef NUM_ELEM
#ifndef NUM_ELEM
#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
#endif
#endif
 
 
static int target_big_endian = 1;
static int target_big_endian = 1;
static unsigned long heap_ptr = 0;
static unsigned long heap_ptr = 0;
static unsigned long stack_ptr = 0;
static unsigned long stack_ptr = 0;
host_callback *callback;
host_callback *callback;
 
 
unsigned long
unsigned long
microblaze_extract_unsigned_integer (unsigned char *addr, int len)
microblaze_extract_unsigned_integer (unsigned char *addr, 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 "
    printf ("That operation is not available on integers of more than "
            "%d bytes.", sizeof (unsigned long));
            "%d bytes.", 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;
 
 
  if (!target_big_endian)
  if (!target_big_endian)
    {
    {
      for (p = endaddr; p > startaddr;)
      for (p = endaddr; p > startaddr;)
        retval = (retval << 8) | * -- p;
        retval = (retval << 8) | * -- p;
    }
    }
  else
  else
    {
    {
      for (p = startaddr; p < endaddr;)
      for (p = startaddr; p < endaddr;)
        retval = (retval << 8) | * p ++;
        retval = (retval << 8) | * p ++;
    }
    }
 
 
  return retval;
  return retval;
}
}
 
 
void
void
microblaze_store_unsigned_integer (unsigned char *addr, int len,
microblaze_store_unsigned_integer (unsigned char *addr, 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;
 
 
  if (!target_big_endian)
  if (!target_big_endian)
    {
    {
      for (p = startaddr; p < endaddr;)
      for (p = startaddr; p < endaddr;)
        {
        {
          *p++ = val & 0xff;
          *p++ = val & 0xff;
          val >>= 8;
          val >>= 8;
        }
        }
    }
    }
  else
  else
    {
    {
      for (p = endaddr; p > startaddr;)
      for (p = endaddr; p > startaddr;)
        {
        {
          *--p = val & 0xff;
          *--p = val & 0xff;
          val >>= 8;
          val >>= 8;
        }
        }
    }
    }
}
}
 
 
struct sim_state microblaze_state;
struct sim_state microblaze_state;
 
 
int memcycles = 1;
int memcycles = 1;
 
 
static SIM_OPEN_KIND sim_kind;
static SIM_OPEN_KIND sim_kind;
static char *myname;
static char *myname;
 
 
static int issue_messages = 0;
static int issue_messages = 0;
 
 
long
long
int_sbrk (int inc_bytes)
int_sbrk (int inc_bytes)
{
{
  long addr;
  long addr;
 
 
  addr = heap_ptr;
  addr = heap_ptr;
 
 
  heap_ptr += inc_bytes;
  heap_ptr += inc_bytes;
 
 
  if (issue_messages && heap_ptr > SP)
  if (issue_messages && heap_ptr > SP)
    fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
    fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
 
 
  return addr;
  return addr;
}
}
 
 
static void /* INLINE */
static void /* INLINE */
wbat (word x, word v)
wbat (word x, word v)
{
{
  if (((uword)x) >= CPU.msize)
  if (((uword)x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
        fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
    }
    }
  else
  else
    {
    {
      unsigned char *p = CPU.memory + x;
      unsigned char *p = CPU.memory + x;
      p[0] = v;
      p[0] = v;
    }
    }
}
}
 
 
static void /* INLINE */
static void /* INLINE */
wlat (word x, word v)
wlat (word x, word v)
{
{
  if (((uword)x) >= CPU.msize)
  if (((uword)x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "word write to 0x%x outside memory range\n", x);
        fprintf (stderr, "word write to 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
    }
    }
  else
  else
    {
    {
      if ((x & 3) != 0)
      if ((x & 3) != 0)
        {
        {
          if (issue_messages)
          if (issue_messages)
            fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
            fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
 
 
          CPU.exception = SIGBUS;
          CPU.exception = SIGBUS;
        }
        }
      else if (!target_big_endian)
      else if (!target_big_endian)
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          p[3] = v >> 24;
          p[3] = v >> 24;
          p[2] = v >> 16;
          p[2] = v >> 16;
          p[1] = v >> 8;
          p[1] = v >> 8;
          p[0] = v;
          p[0] = v;
        }
        }
      else
      else
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          p[0] = v >> 24;
          p[0] = v >> 24;
          p[1] = v >> 16;
          p[1] = v >> 16;
          p[2] = v >> 8;
          p[2] = v >> 8;
          p[3] = v;
          p[3] = v;
        }
        }
    }
    }
}
}
 
 
static void /* INLINE */
static void /* INLINE */
what (word x, word v)
what (word x, word v)
{
{
  if (((uword)x) >= CPU.msize)
  if (((uword)x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "short write to 0x%x outside memory range\n", x);
        fprintf (stderr, "short write to 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
    }
    }
  else
  else
    {
    {
      if ((x & 1) != 0)
      if ((x & 1) != 0)
        {
        {
          if (issue_messages)
          if (issue_messages)
            fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
            fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
                     x);
                     x);
 
 
          CPU.exception = SIGBUS;
          CPU.exception = SIGBUS;
        }
        }
      else if (!target_big_endian)
      else if (!target_big_endian)
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          p[1] = v >> 8;
          p[1] = v >> 8;
          p[0] = v;
          p[0] = v;
        }
        }
      else
      else
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          p[0] = v >> 8;
          p[0] = v >> 8;
          p[1] = v;
          p[1] = v;
        }
        }
    }
    }
}
}
 
 
/* Read functions.  */
/* Read functions.  */
static int /* INLINE */
static int /* INLINE */
rbat (word x)
rbat (word x)
{
{
  if (((uword)x) >= CPU.msize)
  if (((uword)x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
        fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
      return 0;
      return 0;
    }
    }
  else
  else
    {
    {
      unsigned char *p = CPU.memory + x;
      unsigned char *p = CPU.memory + x;
      return p[0];
      return p[0];
    }
    }
}
}
 
 
static int /* INLINE */
static int /* INLINE */
rlat (word x)
rlat (word x)
{
{
  if (((uword) x) >= CPU.msize)
  if (((uword) x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "word read from 0x%x outside memory range\n", x);
        fprintf (stderr, "word read from 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
      return 0;
      return 0;
    }
    }
  else
  else
    {
    {
      if ((x & 3) != 0)
      if ((x & 3) != 0)
        {
        {
          if (issue_messages)
          if (issue_messages)
            fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
            fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
 
 
          CPU.exception = SIGBUS;
          CPU.exception = SIGBUS;
          return 0;
          return 0;
        }
        }
      else if (! target_big_endian)
      else if (! target_big_endian)
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
          return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
        }
        }
      else
      else
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
          return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
        }
        }
    }
    }
}
}
 
 
static int /* INLINE */
static int /* INLINE */
rhat (word x)
rhat (word x)
{
{
  if (((uword)x) >= CPU.msize)
  if (((uword)x) >= CPU.msize)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "short read from 0x%x outside memory range\n", x);
        fprintf (stderr, "short read from 0x%x outside memory range\n", x);
 
 
      CPU.exception = SIGSEGV;
      CPU.exception = SIGSEGV;
      return 0;
      return 0;
    }
    }
  else
  else
    {
    {
      if ((x & 1) != 0)
      if ((x & 1) != 0)
        {
        {
          if (issue_messages)
          if (issue_messages)
            fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
            fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
 
 
          CPU.exception = SIGBUS;
          CPU.exception = SIGBUS;
          return 0;
          return 0;
        }
        }
      else if (!target_big_endian)
      else if (!target_big_endian)
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          return (p[1] << 8) | p[0];
          return (p[1] << 8) | p[0];
        }
        }
      else
      else
        {
        {
          unsigned char *p = CPU.memory + x;
          unsigned char *p = CPU.memory + x;
          return (p[0] << 8) | p[1];
          return (p[0] << 8) | p[1];
        }
        }
    }
    }
}
}
 
 
 
 
#define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
#define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
#define SEXTW(y) ((int)((short)y))
#define SEXTW(y) ((int)((short)y))
 
 
static int
static int
IOMEM (int addr, int write, int value)
IOMEM (int addr, int write, int value)
{
{
}
}
 
 
/* Default to a 8 Mbyte (== 2^23) memory space.  */
/* Default to a 8 Mbyte (== 2^23) memory space.  */
static int sim_memory_size = 1 << 23;
static int sim_memory_size = 1 << 23;
 
 
#define MEM_SIZE_FLOOR  64
#define MEM_SIZE_FLOOR  64
void
void
sim_size (int size)
sim_size (int size)
{
{
  sim_memory_size = size;
  sim_memory_size = size;
  CPU.msize = sim_memory_size;
  CPU.msize = sim_memory_size;
 
 
  if (CPU.memory)
  if (CPU.memory)
    free (CPU.memory);
    free (CPU.memory);
 
 
  CPU.memory = (unsigned char *) calloc (1, CPU.msize);
  CPU.memory = (unsigned char *) calloc (1, CPU.msize);
 
 
  if (!CPU.memory)
  if (!CPU.memory)
    {
    {
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr,
        fprintf (stderr,
                 "Not enough VM for simulation of %d bytes of RAM\n",
                 "Not enough VM for simulation of %d bytes of RAM\n",
                 CPU.msize);
                 CPU.msize);
 
 
      CPU.msize = 1;
      CPU.msize = 1;
      CPU.memory = (unsigned char *) calloc (1, 1);
      CPU.memory = (unsigned char *) calloc (1, 1);
    }
    }
}
}
 
 
static void
static void
init_pointers ()
init_pointers ()
{
{
  if (CPU.msize != (sim_memory_size))
  if (CPU.msize != (sim_memory_size))
    sim_size (sim_memory_size);
    sim_size (sim_memory_size);
}
}
 
 
static void
static void
set_initial_gprs ()
set_initial_gprs ()
{
{
  int i;
  int i;
  long space;
  long space;
  unsigned long memsize;
  unsigned long memsize;
 
 
  init_pointers ();
  init_pointers ();
 
 
  /* Set up machine just out of reset.  */
  /* Set up machine just out of reset.  */
  PC = 0;
  PC = 0;
  MSR = 0;
  MSR = 0;
 
 
  memsize = CPU.msize / (1024 * 1024);
  memsize = CPU.msize / (1024 * 1024);
 
 
  if (issue_messages > 1)
  if (issue_messages > 1)
    fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
    fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
             memsize, CPU.msize - 1);
             memsize, CPU.msize - 1);
 
 
  /* Clean out the GPRs */
  /* Clean out the GPRs */
  for (i = 0; i < 32; i++)
  for (i = 0; i < 32; i++)
    CPU.regs[i] = 0;
    CPU.regs[i] = 0;
  CPU.insts = 0;
  CPU.insts = 0;
  CPU.cycles = 0;
  CPU.cycles = 0;
  CPU.imm_enable = 0;
  CPU.imm_enable = 0;
 
 
}
}
 
 
static void
static void
interrupt ()
interrupt ()
{
{
  CPU.exception = SIGINT;
  CPU.exception = SIGINT;
}
}
 
 
/* Functions so that trapped open/close don't interfere with the
/* Functions so that trapped open/close don't interfere with the
   parent's functions.  We say that we can't close the descriptors
   parent's functions.  We say that we can't close the descriptors
   that we didn't open.  exit() and cleanup() get in trouble here,
   that we didn't open.  exit() and cleanup() get in trouble here,
   to some extent.  That's the price of emulation.  */
   to some extent.  That's the price of emulation.  */
 
 
unsigned char opened[100];
unsigned char opened[100];
 
 
static void
static void
log_open (int fd)
log_open (int fd)
{
{
  if (fd < 0 || fd > NUM_ELEM (opened))
  if (fd < 0 || fd > NUM_ELEM (opened))
    return;
    return;
 
 
  opened[fd] = 1;
  opened[fd] = 1;
}
}
 
 
static void
static void
log_close (int fd)
log_close (int fd)
{
{
  if (fd < 0 || fd > NUM_ELEM (opened))
  if (fd < 0 || fd > NUM_ELEM (opened))
    return;
    return;
 
 
  opened[fd] = 0;
  opened[fd] = 0;
}
}
 
 
static int
static int
is_opened (int fd)
is_opened (int fd)
{
{
  if (fd < 0 || fd > NUM_ELEM (opened))
  if (fd < 0 || fd > NUM_ELEM (opened))
    return 0;
    return 0;
 
 
  return opened[fd];
  return opened[fd];
}
}
 
 
static void
static void
handle_trap1 ()
handle_trap1 ()
{
{
}
}
 
 
static void
static void
process_stub (int what)
process_stub (int what)
{
{
  /* These values should match those in libgloss/microblaze/syscalls.s.  */
  /* These values should match those in libgloss/microblaze/syscalls.s.  */
  switch (what)
  switch (what)
    {
    {
    case 3:  /* _read */
    case 3:  /* _read */
    case 4:  /* _write */
    case 4:  /* _write */
    case 5:  /* _open */
    case 5:  /* _open */
    case 6:  /* _close */
    case 6:  /* _close */
    case 10: /* _unlink */
    case 10: /* _unlink */
    case 19: /* _lseek */
    case 19: /* _lseek */
    case 43: /* _times */
    case 43: /* _times */
      handle_trap1 ();
      handle_trap1 ();
      break;
      break;
 
 
    default:
    default:
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "Unhandled stub opcode: %d\n", what);
        fprintf (stderr, "Unhandled stub opcode: %d\n", what);
      break;
      break;
    }
    }
}
}
 
 
static void
static void
util (unsigned what)
util (unsigned what)
{
{
  switch (what)
  switch (what)
    {
    {
    case 0:      /* exit */
    case 0:      /* exit */
      CPU.exception = SIGQUIT;
      CPU.exception = SIGQUIT;
      break;
      break;
 
 
    case 1:     /* printf */
    case 1:     /* printf */
      {
      {
        unsigned long a[6];
        unsigned long a[6];
        unsigned char *s;
        unsigned char *s;
        int i;
        int i;
 
 
        for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
        for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
          if (*s == '%')
          if (*s == '%')
            i++;
            i++;
      }
      }
      break;
      break;
 
 
    case 2:     /* scanf */
    case 2:     /* scanf */
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "WARNING: scanf unimplemented\n");
        fprintf (stderr, "WARNING: scanf unimplemented\n");
      break;
      break;
 
 
    case 3:     /* utime */
    case 3:     /* utime */
      break;
      break;
 
 
    case 0xFF:
    case 0xFF:
      process_stub (CPU.regs[1]);
      process_stub (CPU.regs[1]);
      break;
      break;
 
 
    default:
    default:
      if (issue_messages)
      if (issue_messages)
        fprintf (stderr, "Unhandled util code: %x\n", what);
        fprintf (stderr, "Unhandled util code: %x\n", what);
      break;
      break;
    }
    }
}
}
 
 
/* For figuring out whether we carried; addc/subc use this. */
/* For figuring out whether we carried; addc/subc use this. */
static int
static int
iu_carry (unsigned long a, unsigned long b, int cin)
iu_carry (unsigned long a, unsigned long b, int cin)
{
{
  unsigned long x;
  unsigned long x;
 
 
  x = (a & 0xffff) + (b & 0xffff) + cin;
  x = (a & 0xffff) + (b & 0xffff) + cin;
  x = (x >> 16) + (a >> 16) + (b >> 16);
  x = (x >> 16) + (a >> 16) + (b >> 16);
  x >>= 16;
  x >>= 16;
 
 
  return (x != 0);
  return (x != 0);
}
}
 
 
#define WATCHFUNCTIONS 1
#define WATCHFUNCTIONS 1
#ifdef WATCHFUNCTIONS
#ifdef WATCHFUNCTIONS
 
 
#define MAXWL 80
#define MAXWL 80
word WL[MAXWL];
word WL[MAXWL];
char *WLstr[MAXWL];
char *WLstr[MAXWL];
 
 
int ENDWL=0;
int ENDWL=0;
int WLincyc;
int WLincyc;
int WLcyc[MAXWL];
int WLcyc[MAXWL];
int WLcnts[MAXWL];
int WLcnts[MAXWL];
int WLmax[MAXWL];
int WLmax[MAXWL];
int WLmin[MAXWL];
int WLmin[MAXWL];
word WLendpc;
word WLendpc;
int WLbcyc;
int WLbcyc;
int WLW;
int WLW;
#endif
#endif
 
 
static int tracing = 0;
static int tracing = 0;
 
 
void
void
sim_resume (SIM_DESC sd, int step, int siggnal)
sim_resume (SIM_DESC sd, int step, int siggnal)
{
{
  int needfetch;
  int needfetch;
  word inst;
  word inst;
  enum microblaze_instr op;
  enum microblaze_instr op;
  void (*sigsave)();
  void (*sigsave)();
  int memops;
  int memops;
  int bonus_cycles;
  int bonus_cycles;
  int insts;
  int insts;
  int w;
  int w;
  int cycs;
  int cycs;
  word WLhash;
  word WLhash;
  ubyte carry;
  ubyte carry;
  int imm_unsigned;
  int imm_unsigned;
  short ra, rb, rd;
  short ra, rb, rd;
  long immword;
  long immword;
  uword oldpc, newpc;
  uword oldpc, newpc;
  short delay_slot_enable;
  short delay_slot_enable;
  short branch_taken;
  short branch_taken;
  short num_delay_slot; /* UNUSED except as reqd parameter */
  short num_delay_slot; /* UNUSED except as reqd parameter */
  enum microblaze_instr_type insn_type;
  enum microblaze_instr_type insn_type;
 
 
  sigsave = signal (SIGINT, interrupt);
  sigsave = signal (SIGINT, interrupt);
  CPU.exception = step ? SIGTRAP : 0;
  CPU.exception = step ? SIGTRAP : 0;
 
 
  memops = 0;
  memops = 0;
  bonus_cycles = 0;
  bonus_cycles = 0;
  insts = 0;
  insts = 0;
 
 
  do
  do
    {
    {
      /* Fetch the initial instructions that we'll decode. */
      /* Fetch the initial instructions that we'll decode. */
      inst = rlat (PC & 0xFFFFFFFC);
      inst = rlat (PC & 0xFFFFFFFC);
 
 
      op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
      op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
                                &num_delay_slot);
                                &num_delay_slot);
 
 
      if (op == invalid_inst)
      if (op == invalid_inst)
        fprintf (stderr, "Unknown instruction 0x%04x", inst);
        fprintf (stderr, "Unknown instruction 0x%04x", inst);
 
 
      if (tracing)
      if (tracing)
        fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
        fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
 
 
      rd = GET_RD;
      rd = GET_RD;
      rb = GET_RB;
      rb = GET_RB;
      ra = GET_RA;
      ra = GET_RA;
      /*      immword = IMM_W; */
      /*      immword = IMM_W; */
 
 
      oldpc = PC;
      oldpc = PC;
      delay_slot_enable = 0;
      delay_slot_enable = 0;
      branch_taken = 0;
      branch_taken = 0;
      if (op == microblaze_brk)
      if (op == microblaze_brk)
        CPU.exception = SIGTRAP;
        CPU.exception = SIGTRAP;
      else if (inst == MICROBLAZE_HALT_INST)
      else if (inst == MICROBLAZE_HALT_INST)
        {
        {
          CPU.exception = SIGQUIT;
          CPU.exception = SIGQUIT;
          insts += 1;
          insts += 1;
          bonus_cycles++;
          bonus_cycles++;
        }
        }
      else
      else
        {
        {
          switch(op)
          switch(op)
            {
            {
#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION)         \
#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION)         \
            case NAME:                                  \
            case NAME:                                  \
              ACTION;                                   \
              ACTION;                                   \
              break;
              break;
#include "microblaze.isa"
#include "microblaze.isa"
#undef INSTRUCTION
#undef INSTRUCTION
 
 
            default:
            default:
              CPU.exception = SIGILL;
              CPU.exception = SIGILL;
              fprintf (stderr, "ERROR: Unknown opcode\n");
              fprintf (stderr, "ERROR: Unknown opcode\n");
            }
            }
          /* Make R0 consistent */
          /* Make R0 consistent */
          CPU.regs[0] = 0;
          CPU.regs[0] = 0;
 
 
          /* Check for imm instr */
          /* Check for imm instr */
          if (op == imm)
          if (op == imm)
            IMM_ENABLE = 1;
            IMM_ENABLE = 1;
          else
          else
            IMM_ENABLE = 0;
            IMM_ENABLE = 0;
 
 
          /* Update cycle counts */
          /* Update cycle counts */
          insts ++;
          insts ++;
          if (insn_type == memory_store_inst || insn_type == memory_load_inst)
          if (insn_type == memory_store_inst || insn_type == memory_load_inst)
            memops++;
            memops++;
          if (insn_type == mult_inst)
          if (insn_type == mult_inst)
            bonus_cycles++;
            bonus_cycles++;
          if (insn_type == barrel_shift_inst)
          if (insn_type == barrel_shift_inst)
            bonus_cycles++;
            bonus_cycles++;
          if (insn_type == anyware_inst)
          if (insn_type == anyware_inst)
            bonus_cycles++;
            bonus_cycles++;
          if (insn_type == div_inst)
          if (insn_type == div_inst)
            bonus_cycles += 33;
            bonus_cycles += 33;
 
 
          if ((insn_type == branch_inst || insn_type == return_inst)
          if ((insn_type == branch_inst || insn_type == return_inst)
              && branch_taken)
              && branch_taken)
            {
            {
              /* Add an extra cycle for taken branches */
              /* Add an extra cycle for taken branches */
              bonus_cycles++;
              bonus_cycles++;
              /* For branch instructions handle the instruction in the delay slot */
              /* For branch instructions handle the instruction in the delay slot */
              if (delay_slot_enable)
              if (delay_slot_enable)
                {
                {
                  newpc = PC;
                  newpc = PC;
                  PC = oldpc + INST_SIZE;
                  PC = oldpc + INST_SIZE;
                  inst = rlat (PC & 0xFFFFFFFC);
                  inst = rlat (PC & 0xFFFFFFFC);
                  op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
                  op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
                                            &num_delay_slot);
                                            &num_delay_slot);
                  if (op == invalid_inst)
                  if (op == invalid_inst)
                    fprintf (stderr, "Unknown instruction 0x%04x", inst);
                    fprintf (stderr, "Unknown instruction 0x%04x", inst);
                  if (tracing)
                  if (tracing)
                    fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
                    fprintf (stderr, "%.4x: inst = %.4x ", PC, inst);
                  rd = GET_RD;
                  rd = GET_RD;
                  rb = GET_RB;
                  rb = GET_RB;
                  ra = GET_RA;
                  ra = GET_RA;
                  /*          immword = IMM_W; */
                  /*          immword = IMM_W; */
                  if (op == microblaze_brk)
                  if (op == microblaze_brk)
                    {
                    {
                      if (issue_messages)
                      if (issue_messages)
                        fprintf (stderr, "Breakpoint set in delay slot "
                        fprintf (stderr, "Breakpoint set in delay slot "
                                 "(at address 0x%x) will not be honored\n", PC);
                                 "(at address 0x%x) will not be honored\n", PC);
                      /* ignore the breakpoint */
                      /* ignore the breakpoint */
                    }
                    }
                  else if (insn_type == branch_inst || insn_type == return_inst)
                  else if (insn_type == branch_inst || insn_type == return_inst)
                    {
                    {
                      if (issue_messages)
                      if (issue_messages)
                        fprintf (stderr, "Cannot have branch or return instructions "
                        fprintf (stderr, "Cannot have branch or return instructions "
                                 "in delay slot (at address 0x%x)\n", PC);
                                 "in delay slot (at address 0x%x)\n", PC);
                      CPU.exception = SIGILL;
                      CPU.exception = SIGILL;
                    }
                    }
                  else
                  else
                    {
                    {
                      switch(op)
                      switch(op)
                        {
                        {
#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION)         \
#define INSTRUCTION(NAME, OPCODE, TYPE, ACTION)         \
                        case NAME:                      \
                        case NAME:                      \
                          ACTION;                       \
                          ACTION;                       \
                          break;
                          break;
#include "microblaze.isa"
#include "microblaze.isa"
#undef INSTRUCTION
#undef INSTRUCTION
 
 
                        default:
                        default:
                          CPU.exception = SIGILL;
                          CPU.exception = SIGILL;
                          fprintf (stderr, "ERROR: Unknown opcode at 0x%x\n", PC);
                          fprintf (stderr, "ERROR: Unknown opcode at 0x%x\n", PC);
                        }
                        }
                      /* Update cycle counts */
                      /* Update cycle counts */
                      insts++;
                      insts++;
                      if (insn_type == memory_store_inst
                      if (insn_type == memory_store_inst
                          || insn_type == memory_load_inst)
                          || insn_type == memory_load_inst)
                        memops++;
                        memops++;
                      if (insn_type == mult_inst)
                      if (insn_type == mult_inst)
                        bonus_cycles++;
                        bonus_cycles++;
                      if (insn_type == barrel_shift_inst)
                      if (insn_type == barrel_shift_inst)
                        bonus_cycles++;
                        bonus_cycles++;
                      if (insn_type == anyware_inst)
                      if (insn_type == anyware_inst)
                        bonus_cycles++;
                        bonus_cycles++;
                      if (insn_type == div_inst)
                      if (insn_type == div_inst)
                        bonus_cycles += 33;
                        bonus_cycles += 33;
                    }
                    }
                  /* Restore the PC */
                  /* Restore the PC */
                  PC = newpc;
                  PC = newpc;
                  /* Make R0 consistent */
                  /* Make R0 consistent */
                  CPU.regs[0] = 0;
                  CPU.regs[0] = 0;
                  /* Check for imm instr */
                  /* Check for imm instr */
                  if (op == imm)
                  if (op == imm)
                    IMM_ENABLE = 1;
                    IMM_ENABLE = 1;
                  else
                  else
                    IMM_ENABLE = 0;
                    IMM_ENABLE = 0;
                }
                }
              else
              else
                /* no delay slot: increment cycle count */
                /* no delay slot: increment cycle count */
                bonus_cycles++;
                bonus_cycles++;
            }
            }
        }
        }
 
 
      if (tracing)
      if (tracing)
        fprintf (stderr, "\n");
        fprintf (stderr, "\n");
    }
    }
  while (!CPU.exception);
  while (!CPU.exception);
 
 
  /* Hide away the things we've cached while executing.  */
  /* Hide away the things we've cached while executing.  */
  /*  CPU.pc = pc; */
  /*  CPU.pc = pc; */
  CPU.insts += insts;           /* instructions done ... */
  CPU.insts += insts;           /* instructions done ... */
  CPU.cycles += insts;          /* and each takes a cycle */
  CPU.cycles += insts;          /* and each takes a cycle */
  CPU.cycles += bonus_cycles;   /* and extra cycles for branches */
  CPU.cycles += bonus_cycles;   /* and extra cycles for branches */
  CPU.cycles += memops;         /* and memop cycle delays */
  CPU.cycles += memops;         /* and memop cycle delays */
 
 
  signal (SIGINT, sigsave);
  signal (SIGINT, sigsave);
}
}
 
 
 
 
int
int
sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
{
{
  int i;
  int i;
  init_pointers ();
  init_pointers ();
 
 
  memcpy (&CPU.memory[addr], buffer, size);
  memcpy (&CPU.memory[addr], buffer, size);
 
 
  return size;
  return size;
}
}
 
 
int
int
sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
{
{
  int i;
  int i;
  init_pointers ();
  init_pointers ();
 
 
  memcpy (buffer, &CPU.memory[addr], size);
  memcpy (buffer, &CPU.memory[addr], size);
 
 
  return size;
  return size;
}
}
 
 
 
 
int
int
sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
{
{
  init_pointers ();
  init_pointers ();
 
 
  if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
  if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
    {
    {
      if (length == 4)
      if (length == 4)
        {
        {
          /* misalignment safe */
          /* misalignment safe */
          long ival = microblaze_extract_unsigned_integer (memory, 4);
          long ival = microblaze_extract_unsigned_integer (memory, 4);
          if (rn < NUM_REGS)
          if (rn < NUM_REGS)
            CPU.regs[rn] = ival;
            CPU.regs[rn] = ival;
          else
          else
            CPU.spregs[rn-NUM_REGS] = ival;
            CPU.spregs[rn-NUM_REGS] = ival;
          return 4;
          return 4;
        }
        }
      else
      else
        return 0;
        return 0;
    }
    }
  else
  else
    return 0;
    return 0;
}
}
 
 
int
int
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
{
{
  long ival;
  long ival;
  init_pointers ();
  init_pointers ();
 
 
  if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
  if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
    {
    {
      if (length == 4)
      if (length == 4)
        {
        {
          if (rn < NUM_REGS)
          if (rn < NUM_REGS)
            ival = CPU.regs[rn];
            ival = CPU.regs[rn];
          else
          else
            ival = CPU.spregs[rn-NUM_REGS];
            ival = CPU.spregs[rn-NUM_REGS];
 
 
          /* misalignment-safe */
          /* misalignment-safe */
          microblaze_store_unsigned_integer (memory, 4, ival);
          microblaze_store_unsigned_integer (memory, 4, ival);
          return 4;
          return 4;
        }
        }
      else
      else
        return 0;
        return 0;
    }
    }
  else
  else
    return 0;
    return 0;
}
}
 
 
 
 
int
int
sim_trace (SIM_DESC sd)
sim_trace (SIM_DESC sd)
{
{
  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 (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
{
{
  if (CPU.exception == SIGQUIT)
  if (CPU.exception == SIGQUIT)
    {
    {
      *reason = sim_exited;
      *reason = sim_exited;
      *sigrc = RETREG;
      *sigrc = RETREG;
    }
    }
  else
  else
    {
    {
      *reason = sim_stopped;
      *reason = sim_stopped;
      *sigrc = CPU.exception;
      *sigrc = CPU.exception;
    }
    }
}
}
 
 
 
 
int
int
sim_stop (SIM_DESC sd)
sim_stop (SIM_DESC sd)
{
{
  CPU.exception = SIGINT;
  CPU.exception = SIGINT;
  return 1;
  return 1;
}
}
 
 
 
 
void
void
sim_info (SIM_DESC sd, int verbose)
sim_info (SIM_DESC sd, int verbose)
{
{
#ifdef WATCHFUNCTIONS
#ifdef WATCHFUNCTIONS
  int w, wcyc;
  int w, wcyc;
#endif
#endif
 
 
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
                             CPU.insts);
                             CPU.insts);
  callback->printf_filtered (callback, "# cycles                 %10d\n",
  callback->printf_filtered (callback, "# cycles                 %10d\n",
                             (CPU.cycles) ? CPU.cycles+2 : 0);
                             (CPU.cycles) ? CPU.cycles+2 : 0);
 
 
#ifdef WATCHFUNCTIONS
#ifdef WATCHFUNCTIONS
  callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
  callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
                             ENDWL);
                             ENDWL);
 
 
  wcyc = 0;
  wcyc = 0;
 
 
  for (w = 1; w <= ENDWL; w++)
  for (w = 1; w <= ENDWL; w++)
    {
    {
      callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
      callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
      callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
      callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
                                 WLcnts[w],WLcyc[w]);
                                 WLcnts[w],WLcyc[w]);
 
 
      if (WLcnts[w] != 0)
      if (WLcnts[w] != 0)
        callback->printf_filtered (callback,
        callback->printf_filtered (callback,
                                   "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
                                   "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
                                   WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
                                   WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
      wcyc += WLcyc[w];
      wcyc += WLcyc[w];
    }
    }
 
 
  callback->printf_filtered (callback,
  callback->printf_filtered (callback,
                             "Total cycles for watched functions: %d\n",wcyc);
                             "Total cycles for watched functions: %d\n",wcyc);
#endif
#endif
}
}
 
 
struct  aout
struct  aout
{
{
  unsigned char  sa_machtype[2];
  unsigned char  sa_machtype[2];
  unsigned char  sa_magic[2];
  unsigned char  sa_magic[2];
  unsigned char  sa_tsize[4];
  unsigned char  sa_tsize[4];
  unsigned char  sa_dsize[4];
  unsigned char  sa_dsize[4];
  unsigned char  sa_bsize[4];
  unsigned char  sa_bsize[4];
  unsigned char  sa_syms[4];
  unsigned char  sa_syms[4];
  unsigned char  sa_entry[4];
  unsigned char  sa_entry[4];
  unsigned char  sa_trelo[4];
  unsigned char  sa_trelo[4];
  unsigned char  sa_drelo[4];
  unsigned char  sa_drelo[4];
} aout;
} aout;
 
 
#define LONG(x)         (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
#define LONG(x)         (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
#define SHORT(x)        (((x)[0]<<8)|(x)[1])
#define SHORT(x)        (((x)[0]<<8)|(x)[1])
 
 
SIM_DESC
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
{
{
  /*  SIM_DESC sd = sim_state_alloc(kind, alloc);*/
  /*  SIM_DESC sd = sim_state_alloc(kind, alloc);*/
 
 
  int osize = sim_memory_size;
  int osize = sim_memory_size;
  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;
 
 
  /* Discard and reacquire memory -- start with a clean slate.  */
  /* Discard and reacquire memory -- start with a clean slate.  */
  sim_size (1);         /* small */
  sim_size (1);         /* small */
  sim_size (osize);     /* and back again */
  sim_size (osize);     /* and back again */
 
 
  set_initial_gprs ();  /* Reset the GPR registers.  */
  set_initial_gprs ();  /* Reset the GPR registers.  */
 
 
  return ((SIM_DESC) 1);
  return ((SIM_DESC) 1);
}
}
 
 
void
void
sim_close (SIM_DESC sd, int quitting)
sim_close (SIM_DESC sd, int quitting)
{
{
  if (CPU.memory)
  if (CPU.memory)
    {
    {
      free(CPU.memory);
      free(CPU.memory);
      CPU.memory = NULL;
      CPU.memory = NULL;
      CPU.msize = 0;
      CPU.msize = 0;
    }
    }
}
}
 
 
SIM_RC
SIM_RC
sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
sim_load (SIM_DESC sd, char *prog, bfd *abfd, 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;
    asection *s;
    asection *s;
    int found_loadable_section = 0;
    int found_loadable_section = 0;
    bfd_vma max_addr = 0;
    bfd_vma max_addr = 0;
    handle = bfd_openr (prog, 0);
    handle = bfd_openr (prog, 0);
 
 
    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;
      }
      }
 
 
    for (s = handle->sections; s; s = s->next)
    for (s = handle->sections; s; s = s->next)
      {
      {
        if (s->flags & SEC_ALLOC)
        if (s->flags & SEC_ALLOC)
          {
          {
            bfd_vma vma = 0;
            bfd_vma vma = 0;
            int size = bfd_get_section_size (s);
            int size = bfd_get_section_size (s);
            if (size > 0)
            if (size > 0)
              {
              {
                vma = bfd_section_vma (handle, s);
                vma = bfd_section_vma (handle, s);
                if (vma >= max_addr)
                if (vma >= max_addr)
                  {
                  {
                    max_addr = vma + size;
                    max_addr = vma + size;
                  }
                  }
              }
              }
            if (s->flags & SEC_LOAD)
            if (s->flags & SEC_LOAD)
              found_loadable_section = 1;
              found_loadable_section = 1;
          }
          }
      }
      }
 
 
    if (!found_loadable_section)
    if (!found_loadable_section)
      {
      {
        /* No loadable sections */
        /* No loadable sections */
        bfd_close(handle);
        bfd_close(handle);
        printf("No loadable sections in file %s\n", prog);
        printf("No loadable sections in file %s\n", prog);
        return SIM_RC_FAIL;
        return SIM_RC_FAIL;
      }
      }
 
 
    sim_memory_size = (unsigned long) max_addr;
    sim_memory_size = (unsigned long) max_addr;
 
 
    /* 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, */
                            1,
                            1,
                            0, sim_write);
                            0, sim_write);
  if (prog_bfd == NULL)
  if (prog_bfd == NULL)
    return SIM_RC_FAIL;
    return SIM_RC_FAIL;
 
 
  target_big_endian = bfd_big_endian (prog_bfd);
  target_big_endian = bfd_big_endian (prog_bfd);
  PC = bfd_get_start_address (prog_bfd);
  PC = bfd_get_start_address (prog_bfd);
 
 
  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 (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env)
{
{
  char **avp;
  char **avp;
  int nargs = 0;
  int nargs = 0;
  int nenv = 0;
  int nenv = 0;
  int s_length;
  int s_length;
  int l;
  int l;
  unsigned long strings;
  unsigned long strings;
  unsigned long pointers;
  unsigned long pointers;
  unsigned long hi_stack;
  unsigned long hi_stack;
 
 
 
 
  /* 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;
 
 
  hi_stack = CPU.msize - 4;
  hi_stack = CPU.msize - 4;
  PC = bfd_get_start_address (prog_bfd);
  PC = bfd_get_start_address (prog_bfd);
 
 
  /* For now ignore all parameters to the program */
  /* For now ignore all parameters to the program */
 
 
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
void
void
sim_kill (SIM_DESC sd)
sim_kill (SIM_DESC sd)
{
{
  /* nothing to do */
  /* nothing to do */
}
}
 
 
void
void
sim_do_command (SIM_DESC sd, char * cmd)
sim_do_command (SIM_DESC sd, char * cmd)
{
{
  /* Nothing there yet; it's all an error.  */
  /* Nothing there yet; it's all an error.  */
 
 
  if (cmd != NULL)
  if (cmd != NULL)
    {
    {
      char ** simargv = buildargv (cmd);
      char ** simargv = buildargv (cmd);
 
 
      if (strcmp (simargv[0], "watch") == 0)
      if (strcmp (simargv[0], "watch") == 0)
        {
        {
          if ((simargv[1] == NULL) || (simargv[2] == NULL))
          if ((simargv[1] == NULL) || (simargv[2] == NULL))
            {
            {
              fprintf (stderr, "Error: missing argument to watch cmd.\n");
              fprintf (stderr, "Error: missing argument to watch cmd.\n");
              return;
              return;
            }
            }
 
 
          ENDWL++;
          ENDWL++;
 
 
          WL[ENDWL] = strtol (simargv[2], NULL, 0);
          WL[ENDWL] = strtol (simargv[2], NULL, 0);
          WLstr[ENDWL] = strdup (simargv[1]);
          WLstr[ENDWL] = strdup (simargv[1]);
          fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
          fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
                   WL[ENDWL], ENDWL);
                   WL[ENDWL], ENDWL);
 
 
        }
        }
      else if (strcmp (simargv[0], "dumpmem") == 0)
      else if (strcmp (simargv[0], "dumpmem") == 0)
        {
        {
          unsigned char * p;
          unsigned char * p;
          FILE * dumpfile;
          FILE * dumpfile;
 
 
          if (simargv[1] == NULL)
          if (simargv[1] == NULL)
            fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
            fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
 
 
          fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
          fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
 
 
          dumpfile = fopen (simargv[1], "w");
          dumpfile = fopen (simargv[1], "w");
          p = CPU.memory;
          p = CPU.memory;
          fwrite (p, CPU.msize-1, 1, dumpfile);
          fwrite (p, CPU.msize-1, 1, dumpfile);
          fclose (dumpfile);
          fclose (dumpfile);
 
 
          fprintf (stderr, "done.\n");
          fprintf (stderr, "done.\n");
        }
        }
      else if (strcmp (simargv[0], "clearstats") == 0)
      else if (strcmp (simargv[0], "clearstats") == 0)
        {
        {
          CPU.cycles = 0;
          CPU.cycles = 0;
          CPU.insts = 0;
          CPU.insts = 0;
          ENDWL = 0;
          ENDWL = 0;
        }
        }
      else if (strcmp (simargv[0], "verbose") == 0)
      else if (strcmp (simargv[0], "verbose") == 0)
        {
        {
          issue_messages = 2;
          issue_messages = 2;
        }
        }
      else
      else
        {
        {
          fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
          fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
                   cmd);
                   cmd);
        }
        }
    }
    }
  else
  else
    {
    {
      fprintf (stderr, "M.CORE sim commands: \n");
      fprintf (stderr, "M.CORE sim commands: \n");
      fprintf (stderr, "  watch <funcname> <addr>\n");
      fprintf (stderr, "  watch <funcname> <addr>\n");
      fprintf (stderr, "  dumpmem <filename>\n");
      fprintf (stderr, "  dumpmem <filename>\n");
      fprintf (stderr, "  clearstats\n");
      fprintf (stderr, "  clearstats\n");
      fprintf (stderr, "  verbose\n");
      fprintf (stderr, "  verbose\n");
    }
    }
}
}
 
 
void
void
sim_set_callbacks (host_callback *ptr)
sim_set_callbacks (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.