sim: overhaul & unify endian settings management
[deliverable/binutils-gdb.git] / sim / mips / interp.c
index ed44cd97e604193202328e58723f83ef477999ea..a6f504acc764f4ea1004f74e76ea4f1de351b071 100644 (file)
@@ -22,7 +22,9 @@ code on the hardware.
 
 */
 
-#include "config.h"
+/* This must come before any other includes.  */
+#include "defs.h"
+
 #include "bfd.h"
 #include "sim-main.h"
 #include "sim-utils.h"
@@ -32,31 +34,22 @@ code on the hardware.
 
 #include "itable.h"
 
-
-#include "config.h"
-
 #include <stdio.h>
 #include <stdarg.h>
 #include <ansidecl.h>
 #include <ctype.h>
 #include <limits.h>
 #include <math.h>
-#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
 #include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 
 #include "getopt.h"
 #include "libiberty.h"
 #include "bfd.h"
-#include "gdb/callback.h"   /* GDB simulator callback interface */
-#include "gdb/remote-sim.h" /* GDB simulator interface */
+#include "elf-bfd.h"
+#include "sim/callback.h"   /* GDB simulator callback interface */
+#include "sim/sim.h" /* GDB simulator interface */
+#include "sim-syscall.h"   /* Simulator system call support */
 
 char* pr_addr (SIM_ADDR addr);
 char* pr_uword64 (uword64 addr);
@@ -71,7 +64,7 @@ char* pr_uword64 (uword64 addr);
    trap is required. NOTE: Care must be taken, since this value may be
    used in later revisions of the MIPS ISA. */
 
-#define RSVD_INSTRUCTION           (0x00000005)
+#define RSVD_INSTRUCTION           (0x00000039)
 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
 
 #define RSVD_INSTRUCTION_ARG_SHIFT 6
@@ -146,7 +139,6 @@ static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
 
 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
 
-
 #define MEM_SIZE (8 << 20)     /* 8 MBytes */
 
 
@@ -343,24 +335,27 @@ mips_pc_set (sim_cpu *cpu, sim_cia pc)
   PC = pc;
 }
 
+static int mips_reg_fetch (SIM_CPU *, int, unsigned char *, int);
+static int mips_reg_store (SIM_CPU *, int, unsigned char *, int);
+
 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 * const *argv)
 {
   int i;
-  SIM_DESC sd = sim_state_alloc (kind, cb);
+  SIM_DESC sd = sim_state_alloc_extra (kind, cb,
+                                      sizeof (struct mips_sim_state));
   sim_cpu *cpu;
 
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
 
   /* The cpu data is kept in a separately allocated chunk of memory.  */
-  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+  if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
     return 0;
 
   cpu = STATE_CPU (sd, 0); /* FIXME */
 
   /* FIXME: watchpoints code shouldn't need this */
-  STATE_WATCHPOINTS (sd)->pc = &(PC);
-  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
   STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
 
   /* Initialize the mechanism for doing insn profiling.  */
@@ -374,9 +369,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
   sim_add_option_table (sd, NULL, mips_options);
 
 
-  /* getopt will print the error message so we just have to exit if this fails.
-     FIXME: Hmmm...  in the case of gdb we need getopt to call
-     print_filtered.  */
+  /* The parser will print an error message for us, so we silently return.  */
   if (sim_parse_args (sd, argv) != SIM_RC_OK)
     {
       /* Uninstall the modules to avoid memory leaks,
@@ -400,9 +393,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
 
       /* Look for largest memory region defined on command-line at
         phys address 0. */
-#ifdef SIM_HAVE_FLATMEM
-      mem_size = STATE_MEM_SIZE (sd);
-#endif
       for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
        {
          /* If we find an entry at address 0, then we will end up
@@ -437,7 +427,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
              mem_size = (match->modulo != 0
                          ? match->modulo : match->nr_bytes);
              /* Delete old region. */
-             sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
+             sim_do_commandf (sd, "memory delete %d:0x%" PRIxTW "@%d",
                               match->space, match->addr, match->level);
            }         
          else if (mem_size == 0)
@@ -446,8 +436,11 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
          if (mem_size > K1SIZE)
            mem_size = K1SIZE;
          /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
-         sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
+         sim_do_commandf (sd, "memory alias 0x%x@1,0x%x%%0x%lx,0x%0x",
                           K1BASE, K1SIZE, (long)mem_size, K0BASE);
+         if (WITH_TARGET_WORD_BITSIZE == 64)
+           sim_do_commandf (sd, "memory alias 0x%x,0x%" PRIxTW ",0x%" PRIxTA,
+                            (K0BASE), mem_size, EXTENDED(K0BASE));
        }
 
       device_init(sd);
@@ -460,13 +453,13 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
 
       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                       0x9FC00000, 
                       4 * 1024 * 1024, /* 4 MB */
                       0xBFC00000);
 
       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                       0x80000000, 
                       4 * 1024 * 1024, /* 4 MB */
                       0xA0000000);
@@ -475,7 +468,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
       for (i=0; i<8; i++) /* 32 MB total */
        {
          unsigned size = 4 * 1024 * 1024;  /* 4 MB */
-         sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+         sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                           0x88000000 + (i * size), 
                           size, 
                           0xA8000000 + (i * size));
@@ -506,13 +499,13 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
       /* --- memory --- */
 
       /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                       0x9FC00000, 
                       4 * 1024 * 1024, /* 4 MB */
                       0xBFC00000);
 
       /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                       0x80000000, 
                       4 * 1024 * 1024, /* 4 MB */
                       0xA0000000);
@@ -521,7 +514,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
       for (i=0; i<8; i++) /* 32 MB total */
        {
          unsigned size = 4 * 1024 * 1024;  /* 4 MB */
-         sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+         sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
                           0x88000000 + (i * size), 
                           size, 
                           0xA8000000 + (i * size));
@@ -529,15 +522,15 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
 
       /* Dummy memory regions for unsimulated devices - sorted by address */
 
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB1000000, 0x400); /* ISA I/O */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2100000, 0x004); /* ISA ctl */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2500000, 0x004); /* LED/switch */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2700000, 0x004); /* RTC */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB3C00000, 0x004); /* RTC */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF8000, 0x900); /* DRAMC */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF9000, 0x200); /* EBIF */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFE000, 0x01c); /* EBIF */
+      sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFF500, 0x300); /* PIO */
 
 
       /* --- simulated devices --- */
@@ -550,8 +543,12 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
       {
        /* FIXME: poking at dv-sockser internals, use tcp backend if
         --sockser_addr option was given.*/
+#ifdef HAVE_DV_SOCKSER
        extern char* sockser_addr;
-       if(sockser_addr == NULL)
+#else
+# define sockser_addr NULL
+#endif
+       if (sockser_addr == NULL)
          sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
        else
          sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
@@ -706,11 +703,16 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
   if (idt_monitor_base != 0)
     {
       unsigned loop;
-      unsigned idt_monitor_size = 1 << 11;
+      address_word idt_monitor_size = 1 << 11;
 
       /* the default monitor region */
-      sim_do_commandf (sd, "memory region 0x%x,0x%x",
-                      idt_monitor_base, idt_monitor_size);
+      if (WITH_TARGET_WORD_BITSIZE == 64)
+       sim_do_commandf (sd, "memory alias 0x%x,0x%" PRIxTW ",0x%" PRIxTA,
+                        idt_monitor_base, idt_monitor_size,
+                        EXTENDED (idt_monitor_base));
+      else
+       sim_do_commandf (sd, "memory region 0x%x,0x%" PRIxTA,
+                        idt_monitor_base, idt_monitor_size);
 
       /* Entry into the IDT monitor is via fixed address vectors, and
         not using machine instructions. To avoid clashing with use of
@@ -807,6 +809,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
     {
       SIM_CPU *cpu = STATE_CPU (sd, i);
 
+      CPU_REG_FETCH (cpu) = mips_reg_fetch;
+      CPU_REG_STORE (cpu) = mips_reg_store;
       CPU_PC_FETCH (cpu) = mips_pc_get;
       CPU_PC_STORE (cpu) = mips_pc_set;
     }
@@ -835,96 +839,20 @@ get_insn_name (sim_cpu *cpu, int i)
 }
 
 void
-sim_close (SIM_DESC sd, int quitting)
+mips_sim_close (SIM_DESC sd, int quitting)
 {
-#ifdef DEBUG
-  printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
-#endif
-
-
-  /* "quitting" is non-zero if we cannot hang on errors */
-
-  /* shut down modules */
-  sim_module_uninstall (sd);
-
-  /* Ensure that any resources allocated through the callback
-     mechanism are released: */
-  sim_io_shutdown (sd);
-
 #if WITH_TRACE_ANY_P
   if (tracefh != NULL && tracefh != stderr)
    fclose(tracefh);
   tracefh = NULL;
 #endif
-
-  /* FIXME - free SD */
-
-  return;
 }
 
-
-int
-sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
+static int
+mips_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
 {
-  int index;
-  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
-
-  /* Return the number of bytes written, or zero if error. */
-#ifdef DEBUG
-  sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
-#endif
-
-  /* We use raw read and write routines, since we do not want to count
-     the GDB memory accesses in our statistics gathering. */
-
-  for (index = 0; index < size; index++)
-    {
-      address_word vaddr = (address_word)addr + index;
-      address_word paddr;
-      int cca;
-      if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
-       break;
-      if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
-       break;
-    }
-
-  return(index);
-}
-
-int
-sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
-{
-  int index;
-  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
-
-  /* Return the number of bytes read, or zero if error. */
-#ifdef DEBUG
-  sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
-#endif /* DEBUG */
-
-  for (index = 0; (index < size); index++)
-    {
-      address_word vaddr = (address_word)addr + index;
-      address_word paddr;
-      int cca;
-      if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
-       break;
-      if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
-       break;
-    }
-
-  return(index);
-}
-
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
-{
-  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
   /* NOTE: gdb (the client) stores registers in target byte order
      while the simulator uses host byte order */
-#ifdef DEBUG
-  sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
-#endif /* DEBUG */
 
   /* Unfortunately this suffers from the same problem as the register
      numbering one. We need to know what the width of each logical
@@ -932,12 +860,10 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 
   if (cpu->register_widths[rn] == 0)
     {
-      sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+      sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
       return 0;
     }
 
-
-
   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
     {
       cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
@@ -1001,26 +927,18 @@ 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
+mips_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
 {
-  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
   /* NOTE: gdb (the client) stores registers in target byte order
      while the simulator uses host byte order */
-#ifdef DEBUG
-#if 0  /* FIXME: doesn't compile */
-  sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
-#endif
-#endif /* DEBUG */
 
   if (cpu->register_widths[rn] == 0)
     {
-      sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
+      sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
       return 0;
     }
 
-
-
   /* Any floating point register */
   if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
     {
@@ -1086,7 +1004,8 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 }
 
 SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+                    char * const *argv, char * const *env)
 {
 
 #ifdef DEBUG
@@ -1105,7 +1024,16 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
       for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
        {
          sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
-         CPU_PC_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
+         sim_cia pc = bfd_get_start_address (abfd);
+
+         /* The 64-bit BFD sign-extends MIPS addresses to model
+            32-bit compatibility segments with 64-bit addressing.
+            These addresses work as is on 64-bit targets but
+            can be truncated for 32-bit targets.  */
+         if (WITH_TARGET_WORD_BITSIZE == 32)
+           pc = (unsigned32) pc;
+
+         CPU_PC_SET (cpu, pc);
        }
     }
 
@@ -1231,6 +1159,23 @@ Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
   return SIM_RC_OK;
 }
 
+/* stat structures from MIPS32/64.  */
+static const char stat32_map[] =
+"st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
+":st_rdev,2:st_size,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
+":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
+
+static const char stat64_map[] =
+"st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
+":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
+":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
+
+/* Map for calls using the host struct stat.  */
+static const CB_TARGET_DEFS_MAP CB_stat_map[] =
+{
+  { "stat", CB_SYS_stat, 15 },
+  { 0, -1, -1 }
+};
 
 
 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
@@ -1251,7 +1196,7 @@ sim_monitor (SIM_DESC sd,
 
   /* The following callback functions are available, however the
      monitor we are simulating does not make use of them: get_errno,
-     isatty, lseek, rename, system, time and unlink */
+     isatty, rename, system and time.  */
   switch (reason)
     {
 
@@ -1325,6 +1270,56 @@ sim_monitor (SIM_DESC sd,
        break;
       }
 
+    case 13: /* int unlink(const char *path) */
+      {
+       char *path = fetch_str (sd, A0);
+       V0 = sim_io_unlink (sd, path);
+       free (path);
+       break;
+      }
+
+    case 14: /* int lseek(int fd, int offset, int whence) */
+      {
+       V0 = sim_io_lseek (sd, A0, A1, A2);
+       break;
+      }
+
+    case 15: /* int stat(const char *path, struct stat *buf); */
+      {
+       /* As long as the infrastructure doesn't cache anything
+          related to the stat mapping, this trick gets us a dual
+          "struct stat"-type mapping in the least error-prone way.  */
+       host_callback *cb = STATE_CALLBACK (sd);
+       const char *saved_map = cb->stat_map;
+       CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
+       bfd *prog_bfd = STATE_PROG_BFD (sd);
+       int is_elf32bit = (elf_elfheader(prog_bfd)->e_ident[EI_CLASS] ==
+                          ELFCLASS32);
+       static CB_SYSCALL s;
+       CB_SYSCALL_INIT (&s);
+       s.func = 15;
+       /* Mask out the sign extension part for 64-bit targets because the
+          MIPS simulator's memory model is still 32-bit.  */
+       s.arg1 = A0 & 0xFFFFFFFF;
+       s.arg2 = A1 & 0xFFFFFFFF;
+       s.p1 = (PTR) sd;
+       s.p2 = (PTR) cpu;
+       s.read_mem = sim_syscall_read_mem;
+       s.write_mem = sim_syscall_write_mem;
+
+       cb->syscall_map = (CB_TARGET_DEFS_MAP *) CB_stat_map;
+       cb->stat_map = is_elf32bit ? stat32_map : stat64_map;
+
+       if (cb_syscall (cb, &s) != CB_RC_OK)
+         sim_engine_halt (sd, cpu, NULL, mips_pc_get (cpu),
+                          sim_stopped, SIM_SIGILL);
+
+       V0 = s.result;
+       cb->stat_map = saved_map;
+       cb->syscall_map = saved_syscall_map;
+       break;
+      }
+
     case 17: /* void _exit() */
       {
        sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
@@ -1393,7 +1388,7 @@ sim_monitor (SIM_DESC sd,
       {
        address_word s = A0;
        unsigned char c;
-       signed_word *ap = &A1; /* 1st argument */
+       address_word *ap = &A1; /* 1st argument */
         /* This isn't the quickest way, since we call the host print
            routine for every character almost. But it does avoid
            having to allocate and manage a temporary string buffer. */
@@ -1476,18 +1471,43 @@ sim_monitor (SIM_DESC sd,
                          sim_io_printf(sd,"<binary not supported>");
                        else
                          {
-                           sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
-                           if (longlong)
-                             sim_io_printf(sd, tmp, lv);
-                           else
-                             sim_io_printf(sd, tmp, (int)lv);
+#define _P(c, fmt64, fmt32) \
+  case c: \
+    if (longlong) \
+      sim_io_printf (sd, "%" fmt64, lv); \
+    else \
+      sim_io_printf (sd, "%" fmt32, (int)lv); \
+    break;
+#define P(c, fmtc) _P(c, PRI##fmtc##64, PRI##fmtc##32)
+                           switch (c)
+                             {
+                             P('d', d)
+                             P('o', o)
+                             P('x', x)
+                             P('X', X)
+                             P('u', u)
+                             }
                          }
+#undef P
+#undef _P
                      }
                    else if (strchr ("eEfgG", c))
                      {
                        double dbl = *(double*)(ap++);
-                       sprintf (tmp, "%%%d.%d%c", width, trunc, c);
-                       sim_io_printf (sd, tmp, dbl);
+
+#define P(c, fmtc) \
+  case c: \
+    sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
+    break;
+                       switch (c)
+                         {
+                         P('e', e)
+                         P('E', E)
+                         P('f', f)
+                         P('g', g)
+                         P('G', G)
+                         }
+#undef P
                        trunc = 0;
                      }
                  }
@@ -1514,26 +1534,21 @@ store_word (SIM_DESC sd,
            uword64 vaddr,
            signed_word val)
 {
-  address_word paddr;
-  int uncached;
+  address_word paddr = vaddr;
 
   if ((vaddr & 3) != 0)
     SignalExceptionAddressStore ();
   else
     {
-      if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
-                             isTARGET, isREAL))
-       {
-         const uword64 mask = 7;
-         uword64 memval;
-         unsigned int byte;
-
-         paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
-         byte = (vaddr & mask) ^ (BigEndianCPU << 2);
-         memval = ((uword64) val) << (8 * byte);
-         StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
-                      isREAL);
-       }
+      const uword64 mask = 7;
+      uword64 memval;
+      unsigned int byte;
+
+      paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
+      byte = (vaddr & mask) ^ (BigEndianCPU << 2);
+      memval = ((uword64) val) << (8 * byte);
+      StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
+                  isREAL);
     }
 }
 
@@ -1551,24 +1566,18 @@ load_word (SIM_DESC sd,
     }
   else
     {
-      address_word paddr;
-      int uncached;
-
-      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
-                             isTARGET, isREAL))
-       {
-         const uword64 mask = 0x7;
-         const unsigned int reverse = ReverseEndian ? 1 : 0;
-         const unsigned int bigend = BigEndianCPU ? 1 : 0;
-         uword64 memval;
-         unsigned int byte;
-
-         paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
-         LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
-                              isDATA, isREAL);
-         byte = (vaddr & mask) ^ (bigend << 2);
-         return EXTEND32 (memval >> (8 * byte));
-       }
+      address_word paddr = vaddr;
+      const uword64 mask = 0x7;
+      const unsigned int reverse = ReverseEndian ? 1 : 0;
+      const unsigned int bigend = BigEndianCPU ? 1 : 0;
+      uword64 memval;
+      unsigned int byte;
+
+      paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
+      LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
+                 isREAL);
+      byte = (vaddr & mask) ^ (bigend << 2);
+      return EXTEND32 (memval >> (8 * byte));
     }
 
   return 0;
@@ -1713,7 +1722,7 @@ dotrace (SIM_DESC sd,
         int type,
         SIM_ADDR address,
         int width,
-        char *comment,...)
+        const char *comment, ...)
 {
   if (STATE & simTRACE) {
     va_list ap;
@@ -2186,18 +2195,17 @@ void
 decode_coproc (SIM_DESC sd,
               sim_cpu *cpu,
               address_word cia,
-              unsigned int instruction)
+              unsigned int instruction,
+              int coprocnum,
+              CP0_operation op,
+              int rt,
+              int rd,
+              int sel)
 {
-  int coprocnum = ((instruction >> 26) & 3);
-
   switch (coprocnum)
     {
     case 0: /* standard CPU control and cache registers */
       {
-        int code = ((instruction >> 21) & 0x1F);
-       int rt = ((instruction >> 16) & 0x1F);
-       int rd = ((instruction >> 11) & 0x1F);
-       int tail = instruction & 0x3ff;
         /* R4000 Users Manual (second edition) lists the following CP0
            instructions:
                                                                   CODE><-RT><RD-><--TAIL--->
@@ -2212,15 +2220,10 @@ decode_coproc (SIM_DESC sd,
           CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
           ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
           */
-        if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */        
-            || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */        
-           && tail == 0)
+       if (((op == cp0_mfc0) || (op == cp0_mtc0)      /* MFC0  /  MTC0  */
+            || (op == cp0_dmfc0) || (op == cp0_dmtc0))  /* DMFC0 / DMTC0  */
+           && sel == 0)
          {
-           /* Clear double/single coprocessor move bit. */
-           code &= ~1;
-
-           /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
-           
            switch (rd)  /* NOTEs: Standard CP0 registers */
              {
                /* 0 = Index               R4000   VR4100  VR4300 */
@@ -2248,7 +2251,7 @@ decode_coproc (SIM_DESC sd,
 
              case 8:
                /* 8 = BadVAddr            R4000   VR4100  VR4300 */
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
                else
                  COP0_BADVADDR = GPR[rt];
@@ -2256,21 +2259,21 @@ decode_coproc (SIM_DESC sd,
 
 #endif /* SUBTARGET_R3900 */
              case 12:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = SR;
                else
                  SR = GPR[rt];
                break;
                /* 13 = Cause              R4000   VR4100  VR4300 */
              case 13:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = CAUSE;
                else
                  CAUSE = GPR[rt];
                break;
                /* 14 = EPC                R4000   VR4100  VR4300 */
              case 14:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed_address) EPC;
                else
                  EPC = GPR[rt];
@@ -2279,7 +2282,7 @@ decode_coproc (SIM_DESC sd,
 #ifdef SUBTARGET_R3900
                 /* 16 = Debug */
               case 16:
-                if (code == 0x00)
+                if (op == cp0_mfc0 || op == cp0_dmfc0)
                   GPR[rt] = Debug;
                 else
                   Debug = GPR[rt];
@@ -2287,7 +2290,7 @@ decode_coproc (SIM_DESC sd,
 #else
                /* 16 = Config             R4000   VR4100  VR4300 */
               case 16:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = C0_CONFIG;
                else
                  /* only bottom three bits are writable */
@@ -2297,7 +2300,7 @@ decode_coproc (SIM_DESC sd,
 #ifdef SUBTARGET_R3900
                 /* 17 = Debug */
               case 17:
-                if (code == 0x00)
+                if (op == cp0_mfc0 || op == cp0_dmfc0)
                   GPR[rt] = DEPC;
                 else
                   DEPC = GPR[rt];
@@ -2320,7 +2323,7 @@ decode_coproc (SIM_DESC sd,
                GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
                /* CPR[0,rd] = GPR[rt]; */
              default:
-               if (code == 0x00)
+               if (op == cp0_mfc0 || op == cp0_dmfc0)
                  GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
                else
                  COP0_GPR[rd] = GPR[rt];
@@ -2332,12 +2335,12 @@ decode_coproc (SIM_DESC sd,
 #endif
              }
          }
-       else if ((code == 0x00 || code == 0x01)
+       else if ((op == cp0_mfc0 || op == cp0_dmfc0)
                 && rd == 16)
          {
            /* [D]MFC0 RT,C0_CONFIG,SEL */
            signed32 cfg = 0;
-           switch (tail & 0x07) 
+           switch (sel)
              {
              case 0:
                cfg = C0_CONFIG;
@@ -2366,7 +2369,7 @@ decode_coproc (SIM_DESC sd,
              }
            GPR[rt] = cfg;
          }
-       else if (code == 0x10 && (tail & 0x3f) == 0x18)
+       else if (op == cp0_eret && sel == 0x18)
          {
            /* ERET */
            if (SR & status_ERL)
@@ -2382,7 +2385,7 @@ decode_coproc (SIM_DESC sd,
                SR &= ~status_EXL;
              }
          }
-        else if (code == 0x10 && (tail & 0x3f) == 0x10)
+        else if (op == cp0_rfe && sel == 0x10)
           {
             /* RFE */
 #ifdef SUBTARGET_R3900
@@ -2394,7 +2397,7 @@ decode_coproc (SIM_DESC sd,
            /* TODO: CACHE register */
 #endif /* SUBTARGET_R3900 */
           }
-        else if (code == 0x10 && (tail & 0x3f) == 0x1F)
+        else if (op == cp0_deret && sel == 0x1F)
           {
             /* DERET */
             Debug &= ~Debug_DM;
This page took 0.123422 seconds and 4 git commands to generate.