ubsan: tilepro: signed integer overflow
[deliverable/binutils-gdb.git] / sim / microblaze / interp.c
index c2476018f6cbb8f529bc559aa8c3ce93c3834c67..be541347495622ec45c857452034278086383bc7 100644 (file)
@@ -1,11 +1,11 @@
 /* Simulator for Xilinx MicroBlaze processor
-   Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright 2009-2020 Free Software Foundation, Inc.
 
    This file is part of GDB, the GNU debugger.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
+#include "config.h"
 #include <signal.h>
-#include "sysdep.h"
-#include <sys/times.h>
-#include <sys/param.h>
-#include <netinet/in.h>        /* for byte ordering macros */
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include "bfd.h"
 #include "gdb/callback.h"
 #include "libiberty.h"
 #include "gdb/remote-sim.h"
-#include "sim-main.h"
-#include "sim-utils.h"
-#include "microblaze-dis.h"
 
+#include "sim-main.h"
+#include "sim-options.h"
 
-#ifndef NUM_ELEM
-#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
-#endif
+#include "microblaze-dis.h"
 
-static int target_big_endian = 1;
-static unsigned long heap_ptr = 0;
-static unsigned long stack_ptr = 0;
-host_callback *callback;
+#define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 
-unsigned long
+static unsigned long
 microblaze_extract_unsigned_integer (unsigned char *addr, int len)
 {
   unsigned long retval;
@@ -51,7 +43,7 @@ microblaze_extract_unsigned_integer (unsigned char *addr, int len)
 
   if (len > (int) sizeof (unsigned long))
     printf ("That operation is not available on integers of more than "
-           "%d bytes.", sizeof (unsigned long));
+           "%zu bytes.", sizeof (unsigned long));
 
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
@@ -71,7 +63,7 @@ microblaze_extract_unsigned_integer (unsigned char *addr, int len)
   return retval;
 }
 
-void
+static void
 microblaze_store_unsigned_integer (unsigned char *addr, int len,
                                   unsigned long val)
 {
@@ -97,426 +89,36 @@ microblaze_store_unsigned_integer (unsigned char *addr, int len,
     }
 }
 
-struct sim_state microblaze_state;
-
-int memcycles = 1;
-
-static SIM_OPEN_KIND sim_kind;
-static char *myname;
-
-static int issue_messages = 0;
-
-long
-int_sbrk (int inc_bytes)
-{
-  long addr;
-
-  addr = heap_ptr;
-
-  heap_ptr += inc_bytes;
-
-  if (issue_messages && heap_ptr > SP)
-    fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
-
-  return addr;
-}
-
-static void /* INLINE */
-wbat (word x, word v)
-{
-  if (((uword)x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-    }
-  else
-    {
-      unsigned char *p = CPU.memory + x;
-      p[0] = v;
-    }
-}
-
-static void /* INLINE */
-wlat (word x, word v)
-{
-  if (((uword)x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "word write to 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-    }
-  else
-    {
-      if ((x & 3) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
-
-         CPU.exception = SIGBUS;
-       }
-      else if (!target_big_endian)
-       {
-         unsigned char *p = CPU.memory + x;
-         p[3] = v >> 24;
-         p[2] = v >> 16;
-         p[1] = v >> 8;
-         p[0] = v;
-       }
-      else
-       {
-         unsigned char *p = CPU.memory + x;
-         p[0] = v >> 24;
-         p[1] = v >> 16;
-         p[2] = v >> 8;
-         p[3] = v;
-       }
-    }
-}
-
-static void /* INLINE */
-what (word x, word v)
-{
-  if (((uword)x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short write to 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-    }
-  else
-    {
-      if ((x & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
-                    x);
-
-         CPU.exception = SIGBUS;
-       }
-      else if (!target_big_endian)
-       {
-         unsigned char *p = CPU.memory + x;
-         p[1] = v >> 8;
-         p[0] = v;
-       }
-      else
-       {
-         unsigned char *p = CPU.memory + x;
-         p[0] = v >> 8;
-         p[1] = v;
-       }
-    }
-}
-
-/* Read functions.  */
-static int /* INLINE */
-rbat (word x)
-{
-  if (((uword)x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      unsigned char *p = CPU.memory + x;
-      return p[0];
-    }
-}
-
-static int /* INLINE */
-rlat (word x)
-{
-  if (((uword) x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "word read from 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      if ((x & 3) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
-
-         CPU.exception = SIGBUS;
-         return 0;
-       }
-      else if (! target_big_endian)
-       {
-         unsigned char *p = CPU.memory + x;
-         return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
-       }
-      else
-       {
-         unsigned char *p = CPU.memory + x;
-         return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-       }
-    }
-}
-
-static int /* INLINE */
-rhat (word x)
-{
-  if (((uword)x) >= CPU.msize)
-    {
-      if (issue_messages)
-       fprintf (stderr, "short read from 0x%x outside memory range\n", x);
-
-      CPU.exception = SIGSEGV;
-      return 0;
-    }
-  else
-    {
-      if ((x & 1) != 0)
-       {
-         if (issue_messages)
-           fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
-
-         CPU.exception = SIGBUS;
-         return 0;
-       }
-      else if (!target_big_endian)
-       {
-         unsigned char *p = CPU.memory + x;
-         return (p[1] << 8) | p[0];
-       }
-      else
-       {
-         unsigned char *p = CPU.memory + x;
-         return (p[0] << 8) | p[1];
-       }
-    }
-}
-
-
-#define SEXTB(x) (((x & 0xff) ^ (~ 0x7f)) + 0x80)
-#define SEXTW(y) ((int)((short)y))
-
-static int
-IOMEM (int addr, int write, int value)
-{
-}
-
-/* Default to a 8 Mbyte (== 2^23) memory space.  */
-static int sim_memory_size = 1 << 23;
-
-#define        MEM_SIZE_FLOOR  64
-void
-sim_size (int size)
-{
-  sim_memory_size = size;
-  CPU.msize = sim_memory_size;
-
-  if (CPU.memory)
-    free (CPU.memory);
-
-  CPU.memory = (unsigned char *) calloc (1, CPU.msize);
-
-  if (!CPU.memory)
-    {
-      if (issue_messages)
-       fprintf (stderr,
-                "Not enough VM for simulation of %d bytes of RAM\n",
-                CPU.msize);
-
-      CPU.msize = 1;
-      CPU.memory = (unsigned char *) calloc (1, 1);
-    }
-}
-
-static void
-init_pointers ()
-{
-  if (CPU.msize != (sim_memory_size))
-    sim_size (sim_memory_size);
-}
-
 static void
-set_initial_gprs ()
+set_initial_gprs (SIM_CPU *cpu)
 {
   int i;
   long space;
-  unsigned long memsize;
-
-  init_pointers ();
 
   /* Set up machine just out of reset.  */
   PC = 0;
   MSR = 0;
 
-  memsize = CPU.msize / (1024 * 1024);
-
-  if (issue_messages > 1)
-    fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
-            memsize, CPU.msize - 1);
-
   /* Clean out the GPRs */
   for (i = 0; i < 32; i++)
     CPU.regs[i] = 0;
   CPU.insts = 0;
   CPU.cycles = 0;
   CPU.imm_enable = 0;
-
-}
-
-static void
-interrupt ()
-{
-  CPU.exception = SIGINT;
-}
-
-/* Functions so that trapped open/close don't interfere with the
-   parent's functions.  We say that we can't close the descriptors
-   that we didn't open.  exit() and cleanup() get in trouble here,
-   to some extent.  That's the price of emulation.  */
-
-unsigned char opened[100];
-
-static void
-log_open (int fd)
-{
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return;
-
-  opened[fd] = 1;
-}
-
-static void
-log_close (int fd)
-{
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return;
-
-  opened[fd] = 0;
-}
-
-static int
-is_opened (int fd)
-{
-  if (fd < 0 || fd > NUM_ELEM (opened))
-    return 0;
-
-  return opened[fd];
-}
-
-static void
-handle_trap1 ()
-{
-}
-
-static void
-process_stub (int what)
-{
-  /* These values should match those in libgloss/microblaze/syscalls.s.  */
-  switch (what)
-    {
-    case 3:  /* _read */
-    case 4:  /* _write */
-    case 5:  /* _open */
-    case 6:  /* _close */
-    case 10: /* _unlink */
-    case 19: /* _lseek */
-    case 43: /* _times */
-      handle_trap1 ();
-      break;
-
-    default:
-      if (issue_messages)
-       fprintf (stderr, "Unhandled stub opcode: %d\n", what);
-      break;
-    }
-}
-
-static void
-util (unsigned what)
-{
-  switch (what)
-    {
-    case 0:    /* exit */
-      CPU.exception = SIGQUIT;
-      break;
-
-    case 1:    /* printf */
-      {
-       unsigned long a[6];
-       unsigned char *s;
-       int i;
-
-       for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
-         if (*s == '%')
-           i++;
-      }
-      break;
-
-    case 2:    /* scanf */
-      if (issue_messages)
-       fprintf (stderr, "WARNING: scanf unimplemented\n");
-      break;
-
-    case 3:    /* utime */
-      break;
-
-    case 0xFF:
-      process_stub (CPU.regs[1]);
-      break;
-
-    default:
-      if (issue_messages)
-       fprintf (stderr, "Unhandled util code: %x\n", what);
-      break;
-    }
-}
-
-/* For figuring out whether we carried; addc/subc use this. */
-static int
-iu_carry (unsigned long a, unsigned long b, int cin)
-{
-  unsigned long        x;
-
-  x = (a & 0xffff) + (b & 0xffff) + cin;
-  x = (x >> 16) + (a >> 16) + (b >> 16);
-  x >>= 16;
-
-  return (x != 0);
 }
 
-#define WATCHFUNCTIONS 1
-#ifdef WATCHFUNCTIONS
-
-#define MAXWL 80
-word WL[MAXWL];
-char *WLstr[MAXWL];
-
-int ENDWL=0;
-int WLincyc;
-int WLcyc[MAXWL];
-int WLcnts[MAXWL];
-int WLmax[MAXWL];
-int WLmin[MAXWL];
-word WLendpc;
-int WLbcyc;
-int WLW;
-#endif
-
 static int tracing = 0;
 
 void
-sim_resume (SIM_DESC sd, int step, int siggnal)
+sim_engine_run (SIM_DESC sd,
+               int next_cpu_nr, /* ignore  */
+               int nr_cpus, /* ignore  */
+               int siggnal) /* ignore  */
 {
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
   int needfetch;
   word inst;
   enum microblaze_instr op;
-  void (*sigsave)();
   int memops;
   int bonus_cycles;
   int insts;
@@ -533,19 +135,16 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
   short num_delay_slot; /* UNUSED except as reqd parameter */
   enum microblaze_instr_type insn_type;
 
-  sigsave = signal (SIGINT, interrupt);
-  CPU.exception = step ? SIGTRAP : 0;
-
   memops = 0;
   bonus_cycles = 0;
   insts = 0;
-  
-  do
+
+  while (1)
     {
       /* Fetch the initial instructions that we'll decode. */
-      inst = rlat (PC & 0xFFFFFFFC);
+      inst = MEM_RD_WORD (PC & 0xFFFFFFFC);
 
-      op = get_insn_microblaze (inst, &imm_unsigned, &insn_type, 
+      op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
                                &num_delay_slot);
 
       if (op == invalid_inst)
@@ -563,12 +162,12 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
       delay_slot_enable = 0;
       branch_taken = 0;
       if (op == microblaze_brk)
-       CPU.exception = SIGTRAP;
+       sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
       else if (inst == MICROBLAZE_HALT_INST)
        {
-         CPU.exception = SIGQUIT;
          insts += 1;
          bonus_cycles++;
+         sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_exited, RETREG);
        }
       else
        {
@@ -582,7 +181,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 #undef INSTRUCTION
 
            default:
-             CPU.exception = SIGILL;
+             sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_signalled,
+                              SIM_SIGILL);
              fprintf (stderr, "ERROR: Unknown opcode\n");
            }
          /* Make R0 consistent */
@@ -608,16 +208,16 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            bonus_cycles += 33;
 
          if ((insn_type == branch_inst || insn_type == return_inst)
-             && branch_taken) 
+             && branch_taken)
            {
              /* Add an extra cycle for taken branches */
              bonus_cycles++;
              /* For branch instructions handle the instruction in the delay slot */
-             if (delay_slot_enable) 
+             if (delay_slot_enable)
                {
                  newpc = PC;
                  PC = oldpc + INST_SIZE;
-                 inst = rlat (PC & 0xFFFFFFFC);
+                 inst = MEM_RD_WORD (PC & 0xFFFFFFFC);
                  op = get_insn_microblaze (inst, &imm_unsigned, &insn_type,
                                            &num_delay_slot);
                  if (op == invalid_inst)
@@ -630,17 +230,18 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
                  /*          immword = IMM_W; */
                  if (op == microblaze_brk)
                    {
-                     if (issue_messages)
+                     if (STATE_VERBOSE_P (sd))
                        fprintf (stderr, "Breakpoint set in delay slot "
                                 "(at address 0x%x) will not be honored\n", PC);
                      /* ignore the breakpoint */
                    }
                  else if (insn_type == branch_inst || insn_type == return_inst)
                    {
-                     if (issue_messages)
+                     if (STATE_VERBOSE_P (sd))
                        fprintf (stderr, "Cannot have branch or return instructions "
                                 "in delay slot (at address 0x%x)\n", PC);
-                     CPU.exception = SIGILL;
+                     sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_signalled,
+                                      SIM_SIGILL);
                    }
                  else
                    {
@@ -654,13 +255,14 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 #undef INSTRUCTION
 
                        default:
-                         CPU.exception = SIGILL;
+                         sim_engine_halt (sd, NULL, NULL, NULL_CIA,
+                                          sim_signalled, SIM_SIGILL);
                          fprintf (stderr, "ERROR: Unknown opcode at 0x%x\n", PC);
                        }
                      /* Update cycle counts */
                      insts++;
                      if (insn_type == memory_store_inst
-                         || insn_type == memory_load_inst) 
+                         || insn_type == memory_load_inst)
                        memops++;
                      if (insn_type == mult_inst)
                        bonus_cycles++;
@@ -689,8 +291,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
       if (tracing)
        fprintf (stderr, "\n");
+
+      if (sim_events_tick (sd))
+       sim_events_process (sd);
     }
-  while (!CPU.exception);
 
   /* Hide away the things we've cached while executing.  */
   /*  CPU.pc = pc; */
@@ -698,39 +302,11 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
   CPU.cycles += insts;         /* and each takes a cycle */
   CPU.cycles += bonus_cycles;  /* and extra cycles for branches */
   CPU.cycles += memops;        /* and memop cycle delays */
-
-  signal (SIGINT, sigsave);
-}
-
-
-int
-sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
-{
-  int i;
-  init_pointers ();
-
-  memcpy (&CPU.memory[addr], buffer, size);
-
-  return size;
 }
 
-int
-sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
-{
-  int i;
-  init_pointers ();
-
-  memcpy (buffer, &CPU.memory[addr], size);
-
-  return size;
-}
-
-
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+microblaze_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
 {
-  init_pointers ();
-
   if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
     {
       if (length == 4)
@@ -750,11 +326,10 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
     return 0;
 }
 
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+microblaze_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
 {
   long ival;
-  init_pointers ();
 
   if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0)
     {
@@ -776,316 +351,119 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
     return 0;
 }
 
-
-int
-sim_trace (SIM_DESC sd)
-{
-  tracing = 1;
-
-  sim_resume (sd, 0, 0);
-
-  tracing = 0;
-
-  return 1;
-}
-
-void
-sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
-{
-  if (CPU.exception == SIGQUIT)
-    {
-      *reason = sim_exited;
-      *sigrc = RETREG;
-    }
-  else
-    {
-      *reason = sim_stopped;
-      *sigrc = CPU.exception;
-    }
-}
-
-
-int
-sim_stop (SIM_DESC sd)
-{
-  CPU.exception = SIGINT;
-  return 1;
-}
-
-
 void
 sim_info (SIM_DESC sd, int verbose)
 {
-#ifdef WATCHFUNCTIONS
-  int w, wcyc;
-#endif
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
+  host_callback *callback = STATE_CALLBACK (sd);
 
   callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
                             CPU.insts);
   callback->printf_filtered (callback, "# cycles                 %10d\n",
                             (CPU.cycles) ? CPU.cycles+2 : 0);
-
-#ifdef WATCHFUNCTIONS
-  callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
-                            ENDWL);
-
-  wcyc = 0;
-
-  for (w = 1; w <= ENDWL; w++)
-    {
-      callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
-      callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
-                                WLcnts[w],WLcyc[w]);
-
-      if (WLcnts[w] != 0)
-       callback->printf_filtered (callback,
-                                  "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
-                                  WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
-      wcyc += WLcyc[w];
-    }
-
-  callback->printf_filtered (callback,
-                            "Total cycles for watched functions: %d\n",wcyc);
-#endif
 }
 
-struct aout
+static sim_cia
+microblaze_pc_get (sim_cpu *cpu)
 {
-  unsigned char  sa_machtype[2];
-  unsigned char  sa_magic[2];
-  unsigned char  sa_tsize[4];
-  unsigned char  sa_dsize[4];
-  unsigned char  sa_bsize[4];
-  unsigned char  sa_syms[4];
-  unsigned char  sa_entry[4];
-  unsigned char  sa_trelo[4];
-  unsigned char  sa_drelo[4];
-} aout;
-
-#define        LONG(x)         (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-#define        SHORT(x)        (((x)[0]<<8)|(x)[1])
+  return cpu->microblaze_cpu.spregs[0];
+}
 
-SIM_DESC
-sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
+static void
+microblaze_pc_set (sim_cpu *cpu, sim_cia pc)
 {
-  /*  SIM_DESC sd = sim_state_alloc(kind, alloc);*/
-
-  int osize = sim_memory_size;
-  myname = argv[0];
-  callback = cb;
-
-  if (kind == SIM_OPEN_STANDALONE)
-    issue_messages = 1;
-
-  /* Discard and reacquire memory -- start with a clean slate.  */
-  sim_size (1);                /* small */
-  sim_size (osize);    /* and back again */
-
-  set_initial_gprs (); /* Reset the GPR registers.  */
-
-  return ((SIM_DESC) 1);
+  cpu->microblaze_cpu.spregs[0] = pc;
 }
 
-void
-sim_close (SIM_DESC sd, int quitting)
+static void
+free_state (SIM_DESC sd)
 {
-  if (CPU.memory)
-    {
-      free(CPU.memory);
-      CPU.memory = NULL;
-      CPU.msize = 0;
-    }
+  if (STATE_MODULES (sd) != NULL)
+    sim_module_uninstall (sd);
+  sim_cpu_free_all (sd);
+  sim_state_free (sd);
 }
 
-SIM_RC
-sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *cb,
+         struct bfd *abfd, char * const *argv)
 {
-  /* Do the right thing for ELF executables; this turns out to be
-     just about the right thing for any object format that:
-       - we crack using BFD routines
-       - follows the traditional UNIX text/data/bss layout
-       - calls the bss section ".bss".   */
-
-  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
-  bfd *prog_bfd;
-
-  {
-    bfd *handle;
-    asection *s;
-    int found_loadable_section = 0;
-    bfd_vma max_addr = 0;
-    handle = bfd_openr (prog, 0);
+  int i;
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
 
-    if (!handle)
-      {
-       printf("``%s'' could not be opened.\n", prog);
-       return SIM_RC_FAIL;
-      }
+  /* The cpu data is kept in a separately allocated chunk of memory.  */
+  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
 
-    /* Makes sure that we have an object file, also cleans gets the
-       section headers in place.  */
-    if (!bfd_check_format (handle, bfd_object))
-      {
-       /* wasn't an object file */
-       bfd_close (handle);
-       printf ("``%s'' is not appropriate object file.\n", prog);
-       return SIM_RC_FAIL;
-      }
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
 
-    for (s = handle->sections; s; s = s->next)
-      {
-       if (s->flags & SEC_ALLOC)
-         {
-           bfd_vma vma = 0;
-           int size = bfd_get_section_size (s);
-           if (size > 0)
-             {
-               vma = bfd_section_vma (handle, s);
-               if (vma >= max_addr)
-                 {
-                   max_addr = vma + size;
-                 }
-             }
-           if (s->flags & SEC_LOAD)
-             found_loadable_section = 1;
-         }
-      }
+  /* The parser will print an error message for us, so we silently return.  */
+  if (sim_parse_args (sd, argv) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
 
-    if (!found_loadable_section)
-      {
-       /* No loadable sections */
-       bfd_close(handle);
-       printf("No loadable sections in file %s\n", prog);
-       return SIM_RC_FAIL;
-      }
+  /* Check for/establish the a reference program image.  */
+  if (sim_analyze_program (sd,
+                          (STATE_PROG_ARGV (sd) != NULL
+                           ? *STATE_PROG_ARGV (sd)
+                           : NULL), abfd) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
 
-    sim_memory_size = (unsigned long) max_addr;
+  /* Configure/verify the target byte order and other runtime
+     configuration options.  */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
 
-    /* Clean up after ourselves.  */
-    bfd_close (handle);
+  if (sim_post_argv_init (sd) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
 
-  }
+  /* CPU specific initialization.  */
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    {
+      SIM_CPU *cpu = STATE_CPU (sd, i);
 
-  /* from sh -- dac */
-  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
-                           /* sim_kind == SIM_OPEN_DEBUG, */
-                           1,
-                           0, sim_write);
-  if (prog_bfd == NULL)
-    return SIM_RC_FAIL;
+      CPU_REG_FETCH (cpu) = microblaze_reg_fetch;
+      CPU_REG_STORE (cpu) = microblaze_reg_store;
+      CPU_PC_FETCH (cpu) = microblaze_pc_get;
+      CPU_PC_STORE (cpu) = microblaze_pc_set;
 
-  target_big_endian = bfd_big_endian (prog_bfd);
-  PC = bfd_get_start_address (prog_bfd);
+      set_initial_gprs (cpu);
+    }
 
-  if (abfd == NULL)
-    bfd_close (prog_bfd);
+  /* Default to a 8 Mbyte (== 2^23) memory space.  */
+  sim_do_commandf (sd, "memory-size 0x800000");
 
-  return SIM_RC_OK;
+  return sd;
 }
 
 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 * const *argv, char * const *env)
 {
-  char **avp;
-  int nargs = 0;
-  int nenv = 0;
-  int s_length;
-  int l;
-  unsigned long strings;
-  unsigned long pointers;
-  unsigned long hi_stack;
-
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
 
-  /* Set the initial register set.  */
-  l = issue_messages;
-  issue_messages = 0;
-  set_initial_gprs ();
-  issue_messages = l;
-
-  hi_stack = CPU.msize - 4;
   PC = bfd_get_start_address (prog_bfd);
 
-  /* For now ignore all parameters to the program */
-
   return SIM_RC_OK;
 }
-
-void
-sim_kill (SIM_DESC sd)
-{
-  /* nothing to do */
-}
-
-void
-sim_do_command (SIM_DESC sd, char * cmd)
-{
-  /* Nothing there yet; it's all an error.  */
-
-  if (cmd != NULL)
-    {
-      char ** simargv = buildargv (cmd);
-
-      if (strcmp (simargv[0], "watch") == 0)
-       {
-         if ((simargv[1] == NULL) || (simargv[2] == NULL))
-           {
-             fprintf (stderr, "Error: missing argument to watch cmd.\n");
-             return;
-           }
-
-         ENDWL++;
-
-         WL[ENDWL] = strtol (simargv[2], NULL, 0);
-         WLstr[ENDWL] = strdup (simargv[1]);
-         fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
-                  WL[ENDWL], ENDWL);
-
-       }
-      else if (strcmp (simargv[0], "dumpmem") == 0)
-       {
-         unsigned char * p;
-         FILE * dumpfile;
-
-         if (simargv[1] == NULL)
-           fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
-
-         fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
-
-         dumpfile = fopen (simargv[1], "w");
-         p = CPU.memory;
-         fwrite (p, CPU.msize-1, 1, dumpfile);
-         fclose (dumpfile);
-
-         fprintf (stderr, "done.\n");
-       }
-      else if (strcmp (simargv[0], "clearstats") == 0)
-       {
-         CPU.cycles = 0;
-         CPU.insts = 0;
-         ENDWL = 0;
-       }
-      else if (strcmp (simargv[0], "verbose") == 0)
-       {
-         issue_messages = 2;
-       }
-      else
-       {
-         fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
-                  cmd);
-       }
-    }
-  else
-    {
-      fprintf (stderr, "M.CORE sim commands: \n");
-      fprintf (stderr, "  watch <funcname> <addr>\n");
-      fprintf (stderr, "  dumpmem <filename>\n");
-      fprintf (stderr, "  clearstats\n");
-      fprintf (stderr, "  verbose\n");
-    }
-}
-
-void
-sim_set_callbacks (host_callback *ptr)
-{
-  callback = ptr;
-}
This page took 0.060506 seconds and 4 git commands to generate.