* interp.c: (mn10300_option_handler): New function parses arguments
[binutils-gdb.git] / sim / mn10300 / interp.c
index cf42f2392f27f5ae083ebeaa7532fcf513fe28d3..1a1e9f7b42aa556384bc4cd0ab7ee7dd67a2bc4d 100644 (file)
@@ -1,8 +1,33 @@
 #include <signal.h>
+
+#if WITH_COMMON
+#include "sim-main.h"
+#include "sim-options.h"
+/* start-sanitize-am30 */
+#include "sim-hw.h"
+/* end-sanitize-am30 */
+#else
+#include "mn10300_sim.h"
+#endif
+
 #include "sysdep.h"
 #include "bfd.h"
+#include "sim-assert.h"
 
-#include "mn10300_sim.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 "bfd.h"
 
 #ifndef INLINE
 #ifdef __GNUC__
 #endif
 #endif
 
+
 host_callback *mn10300_callback;
 int mn10300_debug;
-static SIM_OPEN_KIND sim_kind;
-static char *myname;
 
+
+/* simulation target board.  NULL=default configuration */
+static char* board = NULL;
+
+static DECLARE_OPTION_HANDLER (mn10300_option_handler);
+
+enum {
+  OPTION_BOARD = OPTION_START,
+};
+
+static SIM_RC
+mn10300_option_handler (sd, cpu, opt, arg, is_command)
+     SIM_DESC sd;
+     sim_cpu *cpu;
+     int opt;
+     char *arg;
+     int is_command;
+{
+  int cpu_nr;
+  switch (opt)
+    {
+    case OPTION_BOARD:
+      {
+       if (arg)
+         {
+           board = zalloc(strlen(arg) + 1);
+           strcpy(board, arg);
+         }
+       return SIM_RC_OK;
+      }
+    }
+  
+  return SIM_RC_OK;
+}
+
+static const OPTION mn10300_options[] = 
+{
+/* start-sanitize-am30 */
+#define BOARD_AM32 "am32"
+  { {"board", required_argument, NULL, OPTION_BOARD},
+     '\0', "none" /* rely on compile-time string concatenation for other options */
+           "|" BOARD_AM32
+    , "Customize simulation for a particular board.", mn10300_option_handler },
+/* end-sanitize-am30 */
+
+  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+};
+
+#if WITH_COMMON
+#else
 static void dispatch PARAMS ((uint32, uint32, int));
 static long hash PARAMS ((long));
 static void init_system PARAMS ((void));
+
+static SIM_OPEN_KIND sim_kind;
+static char *myname;
 #define MAX_HASH  127
 
 struct hash_entry
@@ -145,7 +222,7 @@ hash(insn)
   return ((insn & 0xff000000) >> 24) & 0x7f;
 }
 
-static void
+static INLINE void
 dispatch (insn, extension, length)
      uint32 insn;
      uint32 extension;
@@ -177,119 +254,6 @@ dispatch (insn, extension, length)
   PC += length;
 }
 
-/* FIXME These would more efficient to use than load_mem/store_mem,
-   but need to be changed to use the memory map.  */
-
-uint8
-get_byte (x)
-     uint8 *x;
-{
-  return *x;
-}
-
-uint16
-get_half (x)
-     uint8 *x;
-{
-  uint8 *a = x;
-  return (a[1] << 8) + (a[0]);
-}
-
-uint32
-get_word (x)
-      uint8 *x;
-{
-  uint8 *a = x;
-  return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
-}
-
-void
-put_byte (addr, data)
-     uint8 *addr;
-     uint8 data;
-{
-  uint8 *a = addr;
-  a[0] = data;
-}
-
-void
-put_half (addr, data)
-     uint8 *addr;
-     uint16 data;
-{
-  uint8 *a = addr;
-  a[0] = data & 0xff;
-  a[1] = (data >> 8) & 0xff;
-}
-
-void
-put_word (addr, data)
-     uint8 *addr;
-     uint32 data;
-{
-  uint8 *a = addr;
-  a[0] = data & 0xff;
-  a[1] = (data >> 8) & 0xff;
-  a[2] = (data >> 16) & 0xff;
-  a[3] = (data >> 24) & 0xff;
-}
-
-uint32
-load_mem (addr, len)
-     SIM_ADDR addr;
-     int len;
-{
-  uint8 *p = addr + State.mem;
-
-  if (addr > max_mem)
-    abort ();
-
-  switch (len)
-    {
-    case 1:
-      return p[0];
-    case 2:
-      return p[1] << 8 | p[0];
-    case 3:
-      return p[2] << 16 | p[1] << 8 | p[0];
-    case 4:
-      return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
-    default:
-      abort ();
-    }
-}
-
-void
-store_mem (addr, len, data)
-     SIM_ADDR addr;
-     int len;
-     uint32 data;
-{
-  uint8 *p = addr + State.mem;
-
-  if (addr > max_mem)
-    abort ();
-
-  switch (len)
-    {
-    case 1:
-      p[0] = data;
-      return;
-    case 2:
-      p[0] = data;
-      p[1] = data >> 8;
-      return;
-    case 4:
-      p[0] = data;
-      p[1] = data >> 8;
-      p[2] = data >> 16;
-      p[3] = data >> 24;
-      return;
-    default:
-      abort ();
-    }
-}
-
 void
 sim_size (power)
      int power;
@@ -326,7 +290,7 @@ sim_write (sd, addr, buffer, size)
   init_system ();
 
   for (i = 0; i < size; i++)
-    store_mem (addr + i, 1, buffer[i]);
+    store_byte (addr + i, buffer[i]);
 
   return size;
 }
@@ -348,8 +312,10 @@ compare_simops (arg1, arg2)
 }
 
 SIM_DESC
-sim_open (kind,argv)
+sim_open (kind, cb, abfd, argv)
      SIM_OPEN_KIND kind;
+     host_callback *cb;
+     struct _bfd *abfd;
      char **argv;
 {
   struct simops *s;
@@ -357,6 +323,8 @@ sim_open (kind,argv)
   char **p;
   int i;
 
+  mn10300_callback = cb;
+
   /* Sort the opcode array from smallest opcode to largest.
      This will generally improve simulator performance as the smaller
      opcodes are generally preferred to the larger opcodes.  */
@@ -392,7 +360,7 @@ sim_open (kind,argv)
          if (h->opcode == s->opcode
              && h->mask == s->mask
              && h->ops == s)
-           continue;
+           break;
          else
            h = h->next;
        }
@@ -465,6 +433,8 @@ sim_resume (sd, step, siggnal)
   else
     State.exception = 0;
 
+  State.exited = 0;
+
   do
     {
       unsigned long insn, extension;
@@ -486,6 +456,7 @@ sim_resume (sd, step, siggnal)
          case 0x04:
          case 0x08:
          case 0x0c:
+         case 0x10:
          case 0x11:
          case 0x12:
          case 0x13:
@@ -749,9 +720,9 @@ sim_resume (sd, step, siggnal)
          case 0x3a:
          case 0x3b:
          case 0xcc:
-           insn = load_mem (PC, 1);
+           insn = load_byte (PC);
            insn <<= 16;
-           insn |= load_mem (PC + 1, 2);
+           insn |= load_half (PC + 1);
            extension = 0;
            dispatch (insn, extension, 3);
            break;
@@ -777,7 +748,7 @@ sim_resume (sd, step, siggnal)
              {
                insn = inst;
                insn <<= 16;
-               insn |= load_mem (PC + 2, 2);
+               insn |= load_half (PC + 2);
                extension = 0;
              }
            dispatch (insn, extension, 4);
@@ -785,18 +756,18 @@ sim_resume (sd, step, siggnal)
 
          /* Five byte insns.  */
          case 0xcd:
-           insn = load_mem (PC, 1);
+           insn = load_byte (PC);
            insn <<= 24;
-           insn |= (load_mem (PC + 1, 2) << 8);
-           insn |= load_mem (PC + 3, 1);
-           extension = load_mem (PC + 4, 1);
+           insn |= (load_half (PC + 1) << 8);
+           insn |= load_byte (PC + 3);
+           extension = load_byte (PC + 4);
            dispatch (insn, extension, 5);
            break;
 
          case 0xdc:
-           insn = load_mem (PC, 1);
+           insn = load_byte (PC);
            insn <<= 24;
-           extension = load_mem (PC + 1, 4);
+           extension = load_word (PC + 1);
            insn |= (extension & 0xffffff00) >> 8;
            extension &= 0xff;
            dispatch (insn, extension, 5);
@@ -806,29 +777,29 @@ sim_resume (sd, step, siggnal)
          case 0xfc:
          case 0xfd:
            insn = (inst << 16);
-           extension = load_mem (PC + 2, 4);
+           extension = load_word (PC + 2);
            insn |= ((extension & 0xffff0000) >> 16);
            extension &= 0xffff;
            dispatch (insn, extension, 6);
            break;
            
          case 0xdd:
-           insn = load_mem (PC, 1) << 24;
-           extension = load_mem (PC + 1, 4);
+           insn = load_byte (PC) << 24;
+           extension = load_word (PC + 1);
            insn |= ((extension >> 8) & 0xffffff);
            extension = (extension & 0xff) << 16;
-           extension |= load_mem (PC + 5, 1) << 8;
-           extension |= load_mem (PC + 6, 1);
+           extension |= load_byte (PC + 5) << 8;
+           extension |= load_byte (PC + 6);
            dispatch (insn, extension, 7);
            break;
 
          case 0xfe:
            insn = inst << 16;
-           extension = load_mem (PC + 2, 4);
+           extension = load_word (PC + 2);
            insn |= ((extension >> 16) & 0xffff);
            extension <<= 8;
            extension &= 0xffff00;
-           extension |= load_mem (PC + 6, 1);
+           extension |= load_byte (PC + 6);
            dispatch (insn, extension, 7);
            break;
 
@@ -882,24 +853,21 @@ sim_info (sd, verbose)
 }
 
 SIM_RC
-sim_create_inferior (sd, argv, env)
+sim_create_inferior (sd, abfd, argv, env)
      SIM_DESC sd;
+     struct _bfd *abfd;
      char **argv;
      char **env;
 {
+  if (abfd != NULL)
+    PC = bfd_get_start_address (abfd);
+  else
+    PC = 0;
   return SIM_RC_OK;
 }
 
 void
-sim_kill (sd)
-     SIM_DESC sd;
-{
-  /* nothing to do */
-}
-
-void
-sim_set_callbacks (sd, p)
-     SIM_DESC sd;
+sim_set_callbacks (p)
      host_callback *p;
 {
   mn10300_callback = p;
@@ -915,31 +883,16 @@ sim_stop_reason (sd, reason, sigrc)
      enum sim_stop *reason;
      int *sigrc;
 {
-  *reason = sim_stopped;
+  if (State.exited)
+    *reason = sim_exited;
+  else
+    *reason = sim_stopped;
   if (State.exception == SIGQUIT)
     *sigrc = 0;
   else
     *sigrc = State.exception;
 }
 
-void
-sim_fetch_register (sd, rn, memory)
-     SIM_DESC sd;
-     int rn;
-     unsigned char *memory;
-{
-  put_word (memory, State.regs[rn]);
-}
-void
-sim_store_register (sd, rn, memory)
-     SIM_DESC sd;
-     int rn;
-     unsigned char *memory;
-{
-  State.regs[rn] = get_word (memory);
-}
-
 int
 sim_read (sd, addr, buffer, size)
      SIM_DESC sd;
@@ -949,7 +902,7 @@ sim_read (sd, addr, buffer, size)
 {
   int i;
   for (i = 0; i < size; i++)
-    buffer[i] = load_mem (addr + i, 1);
+    buffer[i] = load_byte (addr + i);
 
   return size;
 } 
@@ -973,11 +926,333 @@ sim_load (sd, prog, abfd, from_tty)
   bfd *prog_bfd;
 
   prog_bfd = sim_load_file (sd, myname, mn10300_callback, prog, abfd,
-                           sim_kind == SIM_OPEN_DEBUG);
+                           sim_kind == SIM_OPEN_DEBUG,
+                           0, sim_write);
   if (prog_bfd == NULL)
     return SIM_RC_FAIL;
-  PC = bfd_get_start_address (prog_bfd);
   if (abfd == NULL)
     bfd_close (prog_bfd);
   return SIM_RC_OK;
 } 
+#endif  /* not WITH_COMMON */
+
+
+#if WITH_COMMON
+
+/* For compatibility */
+SIM_DESC simulator;
+
+/* These default values correspond to expected usage for the chip.  */
+
+SIM_DESC
+sim_open (kind, cb, abfd, argv)
+     SIM_OPEN_KIND kind;
+     host_callback *cb;
+     struct _bfd *abfd;
+     char **argv;
+{
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  mn10300_callback = cb;
+
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+  /* for compatibility */
+  simulator = sd;
+
+  /* FIXME: should be better way of setting up interrupts.  For
+     moment, only support watchpoints causing a breakpoint (gdb
+     halt). */
+  STATE_WATCHPOINTS (sd)->pc = &(PC);
+  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
+  STATE_WATCHPOINTS (sd)->interrupt_handler = NULL;
+  STATE_WATCHPOINTS (sd)->interrupt_names = NULL;
+
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+    return 0;
+  sim_add_option_table (sd, NULL, mn10300_options);
+
+  /* Allocate core managed memory */
+  sim_do_command (sd, "memory region 0,0x100000");
+  sim_do_command (sd, "memory region 0x40000000,0x100000");
+
+  /* getopt will print the error message so we just have to exit if this fails.
+     FIXME: Hmmm...  in the case of gdb we need getopt to call
+     print_filtered.  */
+  if (sim_parse_args (sd, argv) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* start-sanitize-am30 */
+  if ( NULL != board
+       && (strcmp(board, BOARD_AM32) == 0 ) )
+       {
+        /* device support for mn1030002 */
+        /* interrupt controller */
+
+        sim_hw_parse (sd, "/mn103int@0x34000100/reg 0x34000100 0x7C 0x34000200 0x8 0x3400280 0x8");
+
+        /* DEBUG: NMI input's */
+        sim_hw_parse (sd, "/glue@0x30000000/reg 0x30000000 12");
+        sim_hw_parse (sd, "/glue@0x30000000 > int0 nmirq /mn103int");
+        sim_hw_parse (sd, "/glue@0x30000000 > int1 watchdog /mn103int");
+        sim_hw_parse (sd, "/glue@0x30000000 > int2 syserr /mn103int");
+
+        /* DEBUG: ACK input */
+        sim_hw_parse (sd, "/glue@0x30002000/reg 0x30002000 4");
+        sim_hw_parse (sd, "/glue@0x30002000 > int ack /mn103int");
+        
+        /* DEBUG: LEVEL output */
+        sim_hw_parse (sd, "/glue@0x30004000/reg 0x30004000 8");
+        sim_hw_parse (sd, "/mn103int > nmi int0 /glue@0x30004000");
+        sim_hw_parse (sd, "/mn103int > level int1 /glue@0x30004000");
+
+        /* DEBUG: A bunch of interrupt inputs */
+        sim_hw_parse (sd, "/glue@0x30006000/reg 0x30006000 32");
+        sim_hw_parse (sd, "/glue@0x30006000 > int0 irq-0 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int1 irq-1 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int2 irq-2 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int3 irq-3 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int4 irq-4 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int5 irq-5 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int6 irq-6 /mn103int");
+        sim_hw_parse (sd, "/glue@0x30006000 > int7 irq-7 /mn103int");
+
+        /* processor interrupt device */
+
+        /* the device */
+        sim_hw_parse (sd, "/mn103cpu@0x20000000");
+        sim_hw_parse (sd, "/mn103cpu@0x20000000/reg 0x20000000 0x42");
+
+        /* DEBUG: ACK output wired upto a glue device */
+        sim_hw_parse (sd, "/glue@0x20002000");
+        sim_hw_parse (sd, "/glue@0x20002000/reg 0x20002000 4");
+        sim_hw_parse (sd, "/mn103cpu > ack int0 /glue@0x20002000");
+
+        /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */
+        sim_hw_parse (sd, "/glue@0x20004000");
+        sim_hw_parse (sd, "/glue@0x20004000/reg 0x20004000 12");
+        sim_hw_parse (sd, "/glue@0x20004000 > int0 reset /mn103cpu");
+        sim_hw_parse (sd, "/glue@0x20004000 > int1 nmi /mn103cpu");
+        sim_hw_parse (sd, "/glue@0x20004000 > int2 level /mn103cpu");
+
+        /* REAL: The processor wired up to the real interrupt controller */
+        sim_hw_parse (sd, "/mn103cpu > ack ack /mn103int");
+        sim_hw_parse (sd, "/mn103int > level level /mn103cpu");
+        sim_hw_parse (sd, "/mn103int > nmi nmi /mn103cpu");
+
+
+        /* PAL */
+
+        /* the device */
+        sim_hw_parse (sd, "/pal@0x31000000");
+        sim_hw_parse (sd, "/pal@0x31000000/reg 0x31000000 64");
+        sim_hw_parse (sd, "/pal@0x31000000/poll? true");
+
+        /* DEBUG: PAL wired up to a glue device */
+        sim_hw_parse (sd, "/glue@0x31002000");
+        sim_hw_parse (sd, "/glue@0x31002000/reg 0x31002000 16");
+        sim_hw_parse (sd, "/pal@0x31000000 > countdown int0 /glue@0x31002000");
+        sim_hw_parse (sd, "/pal@0x31000000 > timer int1 /glue@0x31002000");
+        sim_hw_parse (sd, "/pal@0x31000000 > int int2 /glue@0x31002000");
+        sim_hw_parse (sd, "/glue@0x31002000 > int0 int3 /glue@0x31002000");
+        sim_hw_parse (sd, "/glue@0x31002000 > int1 int3 /glue@0x31002000");
+        sim_hw_parse (sd, "/glue@0x31002000 > int2 int3 /glue@0x31002000");
+        
+        /* REAL: The PAL wired up to the real interrupt controller */
+        sim_hw_parse (sd, "/pal@0x31000000 > countdown irq-0 /mn103int");
+        sim_hw_parse (sd, "/pal@0x31000000 > timer irq-1 /mn103int");
+        sim_hw_parse (sd, "/pal@0x31000000 > int irq-2 /mn103int");
+        
+        /* 8 and 16 bit timers */
+        sim_hw_parse (sd, "/mn103tim@0x34001000/reg 0x34001000 36 0x34001080 100");
+  
+        /* Hook timer interrupts up to interrupt controller */
+        sim_hw_parse (sd, "/mn103tim > timer-0-underflow timer-0-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-1-underflow timer-1-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-2-underflow timer-2-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-3-underflow timer-3-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-4-underflow timer-4-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-5-underflow timer-5-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-6-underflow timer-6-underflow /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-6-compare-a timer-6-compare-a /mn103int");
+        sim_hw_parse (sd, "/mn103tim > timer-6-compare-b timer-6-compare-b /mn103int");
+
+
+        /* Serial devices 0,1,2 */
+        sim_hw_parse (sd, "/mn103ser@0x34000800/reg 0x34000800 48");
+  
+        /* Hook serial interrupts up to interrupt controller */
+        sim_hw_parse (sd, "/mn103ser > serial-0-receive serial-0-receive /mn103int");
+        sim_hw_parse (sd, "/mn103ser > serial-0-transmit serial-0-transmit /mn103int");
+        sim_hw_parse (sd, "/mn103ser > serial-1-receive serial-0-receive /mn103int");
+        sim_hw_parse (sd, "/mn103ser > serial-1-transmit serial-0-transmit /mn103int");
+        sim_hw_parse (sd, "/mn103ser > serial-2-receive serial-0-receive /mn103int");
+        sim_hw_parse (sd, "/mn103ser > serial-2-transmit serial-0-transmit /mn103int");
+       }
+  
+  /* end-sanitize-am30 */
+
+  /* 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)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* establish any remaining configuration options */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  if (sim_post_argv_init (sd) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+
+  /* set machine specific configuration */
+/*   STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
+/*                          | PSW_CY | PSW_OV | PSW_S | PSW_Z); */
+
+  return sd;
+}
+
+
+void
+sim_close (sd, quitting)
+     SIM_DESC sd;
+     int quitting;
+{
+  sim_module_uninstall (sd);
+}
+
+
+SIM_RC
+sim_create_inferior (sd, prog_bfd, argv, env)
+     SIM_DESC sd;
+     struct _bfd *prog_bfd;
+     char **argv;
+     char **env;
+{
+  memset (&State, 0, sizeof (State));
+  if (prog_bfd != NULL) {
+    PC = bfd_get_start_address (prog_bfd);
+  } else {
+    PC = 0;
+  }
+  CIA_SET (STATE_CPU (sd, 0), (unsigned64) PC);
+
+  return SIM_RC_OK;
+}
+
+void
+sim_do_command (sd, cmd)
+     SIM_DESC sd;
+     char *cmd;
+{
+  char *mm_cmd = "memory-map";
+  char *int_cmd = "interrupt";
+
+  if (sim_args_command (sd, cmd) != SIM_RC_OK)
+    {
+      if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
+       sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
+      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
+       sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
+      else
+       sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
+    }
+}
+#endif  /* WITH_COMMON */
+
+/* FIXME These would more efficient to use than load_mem/store_mem,
+   but need to be changed to use the memory map.  */
+
+uint8
+get_byte (x)
+     uint8 *x;
+{
+  return *x;
+}
+
+uint16
+get_half (x)
+     uint8 *x;
+{
+  uint8 *a = x;
+  return (a[1] << 8) + (a[0]);
+}
+
+uint32
+get_word (x)
+      uint8 *x;
+{
+  uint8 *a = x;
+  return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
+}
+
+void
+put_byte (addr, data)
+     uint8 *addr;
+     uint8 data;
+{
+  uint8 *a = addr;
+  a[0] = data;
+}
+
+void
+put_half (addr, data)
+     uint8 *addr;
+     uint16 data;
+{
+  uint8 *a = addr;
+  a[0] = data & 0xff;
+  a[1] = (data >> 8) & 0xff;
+}
+
+void
+put_word (addr, data)
+     uint8 *addr;
+     uint32 data;
+{
+  uint8 *a = addr;
+  a[0] = data & 0xff;
+  a[1] = (data >> 8) & 0xff;
+  a[2] = (data >> 16) & 0xff;
+  a[3] = (data >> 24) & 0xff;
+}
+
+int
+sim_fetch_register (sd, rn, memory, length)
+     SIM_DESC sd;
+     int rn;
+     unsigned char *memory;
+     int length;
+{
+  put_word (memory, State.regs[rn]);
+  return -1;
+}
+int
+sim_store_register (sd, rn, memory, length)
+     SIM_DESC sd;
+     int rn;
+     unsigned char *memory;
+     int length;
+{
+  State.regs[rn] = get_word (memory);
+  return -1;
+}