diff --git a/sim/arm/sim-main.h b/sim/arm/sim-main.h
index 17c3132bb0a4..ba44314927a2 100644
--- a/sim/arm/sim-main.h
+++ b/sim/arm/sim-main.h
@@ -19,6 +19,8 @@
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 #include "sim-base.h"
 #include "bfd.h"
@@ -28,9 +30,4 @@
 
 extern struct ARMul_State *state;
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
diff --git a/sim/common/sim-cpu.c b/sim/common/sim-cpu.c
index f0964819622f..fa3e77abd35e 100644
--- a/sim/common/sim-cpu.c
+++ b/sim/common/sim-cpu.c
@@ -31,12 +31,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 /* ??? wip.  better solution must wait.  */
 
 SIM_RC
-sim_cpu_alloc_all (SIM_DESC sd, int ncpus)
+sim_cpu_alloc_all_extra (SIM_DESC sd, int ncpus, size_t extra_bytes)
 {
   int c;
 
   for (c = 0; c < ncpus; ++c)
-    STATE_CPU (sd, c) = sim_cpu_alloc (sd);
+    STATE_CPU (sd, c) = sim_cpu_alloc_extra (sd, extra_bytes);
   return SIM_RC_OK;
 }
 
@@ -44,15 +44,24 @@ sim_cpu_alloc_all (SIM_DESC sd, int ncpus)
    EXTRA_BYTES is additional space to allocate for the sim_cpu struct.  */
 
 sim_cpu *
-sim_cpu_alloc (SIM_DESC sd)
+sim_cpu_alloc_extra (SIM_DESC sd, size_t extra_bytes)
 {
-  int extra_bytes = 0;
+  sim_cpu *cpu;
 
-#ifdef CGEN_ARCH
-  extra_bytes += cgen_cpu_max_extra_bytes (sd);
+#ifndef CGEN_ARCH
+# define cgen_cpu_max_extra_bytes(sd) 0
+#endif
+#ifdef SIM_HAVE_COMMON_SIM_CPU
+  cpu = zalloc (sizeof (*cpu));
+
+  extra_bytes += cgen_cpu_max_extra_bytes(sd);
+  if (extra_bytes)
+    CPU_ARCH_DATA (cpu) = zalloc (extra_bytes);
+#else
+  cpu = zalloc (sizeof (*cpu) + cgen_cpu_max_extra_bytes (sd));
 #endif
 
-  return zalloc (sizeof (sim_cpu) + extra_bytes);
+  return cpu;
 }
 
 /* Free all resources held by all cpus.  */
@@ -72,6 +81,10 @@ sim_cpu_free_all (SIM_DESC sd)
 void
 sim_cpu_free (sim_cpu *cpu)
 {
+#ifdef SIM_HAVE_COMMON_SIM_CPU
+  free (CPU_ARCH_DATA (cpu));
+#endif
+
   free (cpu);
 }
 
diff --git a/sim/common/sim-cpu.h b/sim/common/sim-cpu.h
index 4f5972b0939d..ab41508acb65 100644
--- a/sim/common/sim-cpu.h
+++ b/sim/common/sim-cpu.h
@@ -122,10 +122,24 @@ typedef struct {
 
 } sim_cpu_base;
 
+#ifdef SIM_HAVE_COMMON_SIM_CPU
+struct _sim_cpu {
+  /* All the common state.  */
+  sim_cpu_base base;
+
+  /* Pointer for sim target to store arbitrary cpu data.  Normally the
+     target should define a struct and use it here.  */
+  void *arch_data;
+#define CPU_ARCH_DATA(cpu) ((cpu)->arch_data)
+};
+#endif
+
 /* Create all cpus.  */
-extern SIM_RC sim_cpu_alloc_all (SIM_DESC, int);
+extern SIM_RC sim_cpu_alloc_all_extra (SIM_DESC, int, size_t);
+#define sim_cpu_alloc_all(state, ncpus) sim_cpu_alloc_all_extra (state, ncpus, 0)
 /* Create a cpu.  */
-extern sim_cpu *sim_cpu_alloc (SIM_DESC);
+extern sim_cpu *sim_cpu_alloc_extra (SIM_DESC, size_t);
+#define sim_cpu_alloc(sd) sim_cpu_alloc_extra (sd, 0)
 /* Release resources held by all cpus.  */
 extern void sim_cpu_free_all (SIM_DESC);
 /* Release resources held by a cpu.  */
diff --git a/sim/cr16/sim-main.h b/sim/cr16/sim-main.h
index adf242a2ce4a..7ac6bd2c0de5 100644
--- a/sim/cr16/sim-main.h
+++ b/sim/cr16/sim-main.h
@@ -19,6 +19,8 @@
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 
 typedef long int           word;
@@ -29,9 +31,4 @@ typedef unsigned long int  uword;
 
 #include "cr16_sim.h"
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
diff --git a/sim/d10v/sim-main.h b/sim/d10v/sim-main.h
index 8a4e944db4e2..5327e7ec3d02 100644
--- a/sim/d10v/sim-main.h
+++ b/sim/d10v/sim-main.h
@@ -19,6 +19,8 @@
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 
 typedef long int           word;
@@ -29,9 +31,4 @@ typedef unsigned long int  uword;
 
 #include "d10v_sim.h"
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
diff --git a/sim/mn10300/sim-main.h b/sim/mn10300/sim-main.h
index dd4f966399b2..37e5ce011b5f 100644
--- a/sim/mn10300/sim-main.h
+++ b/sim/mn10300/sim-main.h
@@ -22,6 +22,8 @@
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #define SIM_ENGINE_HALT_HOOK(SD,LAST_CPU,CIA) /* disable this hook */
 
 #include "sim-basics.h"
@@ -53,17 +55,6 @@ mn10300_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER),
 #define IMEM8_IMMED(EA, N) \
 (sim_core_read_aligned_1(STATE_CPU(sd, 0), EA, exec_map, (EA) + (N)))
 
-
-/* FIXME: For moment, save/restore PC value found in struct State.
-   Struct State will one day go away, being placed in the sim_cpu
-   state. */
-
-struct _sim_cpu {
-  sim_event *pending_nmi;
-  sim_cia cia;
-  sim_cpu_base base;
-};
-
 /* For compatibility, until all functions converted to passing
    SIM_DESC as an argument */
 extern SIM_DESC simulator;
diff --git a/sim/sh/sim-main.h b/sim/sh/sim-main.h
index 5f04623fba7e..5504ad241099 100644
--- a/sim/sh/sim-main.h
+++ b/sim/sh/sim-main.h
@@ -19,6 +19,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 #include "sim-base.h"
 
@@ -118,9 +120,4 @@ typedef union
 /* TODO: Move into sim_cpu.  */
 extern saved_state_type saved_state;
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
