#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"
 
 extern struct ARMul_State *state;
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
 
 /* ??? 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;
 }
 
    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;
+
+#ifndef CGEN_ARCH
+# define cgen_cpu_max_extra_bytes(sd) 0
+#endif
+#ifdef SIM_HAVE_COMMON_SIM_CPU
+  cpu = zalloc (sizeof (*cpu));
 
-#ifdef CGEN_ARCH
   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.  */
 void
 sim_cpu_free (sim_cpu *cpu)
 {
+#ifdef SIM_HAVE_COMMON_SIM_CPU
+  free (CPU_ARCH_DATA (cpu));
+#endif
+
   free (cpu);
 }
 \f
 
 
 } 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.  */
 
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 
 typedef long int           word;
 
 #include "cr16_sim.h"
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
 
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 
 typedef long int           word;
 
 #include "d10v_sim.h"
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif
 
 #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"
 #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;
 
 #ifndef SIM_MAIN_H
 #define SIM_MAIN_H
 
+#define SIM_HAVE_COMMON_SIM_CPU
+
 #include "sim-basics.h"
 #include "sim-base.h"
 
 /* TODO: Move into sim_cpu.  */
 extern saved_state_type saved_state;
 
-struct _sim_cpu {
-
-  sim_cpu_base base;
-};
-
 #endif