diff --git a/.gitattributes b/.gitattributes
index dd6f3f861be09fb1d221d3dae982065c224cb891..5aa2c0c014f2d57ae0c357e0b574224fde0ca865 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -176,6 +176,14 @@ testfont binary
 /src/builtin_functions_t.c foreign_ident
 /src/callback.c foreign_ident
 /src/callback.h foreign_ident
+/src/code/bytecode.c foreign_ident
+/src/code/bytecode.h foreign_ident
+/src/code/computedgoto.c foreign_ident
+/src/code/computedgoto.h foreign_ident
+/src/code/ia32.c foreign_ident
+/src/code/ia32.h foreign_ident
+/src/code/sparc.c foreign_ident
+/src/code/sparc.h foreign_ident
 /src/combine_path.h foreign_ident
 /src/compilation.h foreign_ident
 /src/configure.in foreign_ident
@@ -600,6 +608,8 @@ testfont binary
 /src/pike_threadlib.h foreign_ident
 /src/pike_types.c foreign_ident
 /src/pike_types.h foreign_ident
+/src/pikecode.c foreign_ident
+/src/pikecode.h foreign_ident
 /src/port.c foreign_ident
 /src/port.h foreign_ident
 /src/post_modules/GL/Makefile.in foreign_ident
diff --git a/src/Makefile.in b/src/Makefile.in
index 416f11f302a5c936f4c3a9cacc4bfb577bd6e1fa..09f5fe80453d79e4b424f2f596d1256feea563e2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.269 2001/07/18 11:36:00 grubba Exp $
+# $Id: Makefile.in,v 1.270 2001/07/20 12:44:50 grubba Exp $
 #
 
 # This line is needed on some machines.
@@ -135,6 +135,7 @@ OBJ= \
  mapping.o \
  pike_memory.o \
  module_support.o \
+ pikecode.o \
  object.o \
  opcodes.o \
  operators.o \
diff --git a/src/code/README.txt b/src/code/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..831afaacaeb4628c8bea286ef7da317c963ec061
--- /dev/null
+++ b/src/code/README.txt
@@ -0,0 +1,37 @@
+Code generation templates for Pike.
+
+These paired files should all implement the following functions/macros:
+
+void ins_pointer(INT32 ptr);
+	Store a 32bit pointer at the current offset.
+
+INT32 read_pointer(INT32 off);
+	Read a 32bit pointer from the specified offset.
+
+void upd_pointer(INT32 off, INT32 ptr);
+	Store a 32bit pointer at the specified offset.
+
+void ins_align(INT32 align);
+	Align the current offset to the specified alignment.
+
+void ins_byte(INT32 val);
+	Insert an 8bit unsigned value at the current offset.
+
+void ins_data(INT32 val);
+	Insert a 32bit value at the current offset.
+
+void ins_f_byte(unsigned int op);
+	Insert the opcode 'op' at the current offset.
+
+void ins_f_byte_with_arg(unsigned int op, unsigned INT32 arg);
+	Insert the opcode 'op' with the primary argument 'arg' at
+	the current offset.
+
+void ins_f_byte_with_2_args(unsigned int op,
+			    unsigned INT32 arg1,
+			    unsigned INT32 arg2);
+	Insert the opcode 'op' with the primary argument 'arg1' and
+	the secondary argument 'arg2' at the current offset.
+
+void UPDATE_PC(void)
+	Insert code to update the runtime linenumber information.
diff --git a/src/code/bytecode.c b/src/code/bytecode.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4fc6435de898b80034960b02f956534a1cff2cb
--- /dev/null
+++ b/src/code/bytecode.c
@@ -0,0 +1,115 @@
+/*
+ * $Id: bytecode.c,v 1.1 2001/07/20 12:44:52 grubba Exp $
+ *
+ * Default bytecode assembler for Pike.
+ *
+ */
+
+void ins_pointer(INT32 ptr)
+{
+  ins_int(ptr, add_to_program);
+}
+
+INT32 read_pointer(INT32 off)
+{
+  return read_int(off);
+}
+
+void upd_pointer(INT32 off, INT32 ptr)
+{
+  upd_int(off, ptr);
+}
+
+void ins_align(INT32 align)
+{
+  while(Pike_compiler->new_program->num_program % c->arg) {
+    add_to_program(0);
+  }
+}
+
+void ins_byte(INT32 val)
+{
+  add_to_program(val);
+}
+
+void ins_data(INT32 val)
+{
+  ins_int(val, add_to_program);
+}
+
+void ins_f_byte(unsigned int b)
+{
+#ifdef PIKE_DEBUG
+  if(store_linenumbers && b<F_MAX_OPCODE)
+    ADD_COMPILED(b);
+#endif /* PIKE_DEBUG */
+
+  b-=F_OFFSET;
+#ifdef PIKE_DEBUG
+  if(b>255)
+    Pike_error("Instruction too big %d\n",b);
+#endif
+    
+  add_to_program((unsigned char)b);
+}
+
+static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
+{
+  switch(b >> 8)
+  {
+  case 0 : break;
+  case 1 : ins_f_byte(F_PREFIX_256); break;
+  case 2 : ins_f_byte(F_PREFIX_512); break;
+  case 3 : ins_f_byte(F_PREFIX_768); break;
+  case 4 : ins_f_byte(F_PREFIX_1024); break;
+  default:
+    if( b < 256*256)
+    {
+      ins_f_byte(F_PREFIX_CHARX256);
+      add_to_program((unsigned char)(b>>8));
+    }else if(b < 256*256*256) {
+      ins_f_byte(F_PREFIX_WORDX256);
+      add_to_program((unsigned char)(b>>16));
+      add_to_program((unsigned char)(b>>8));
+    }else{
+      ins_f_byte(F_PREFIX_24BITX256);
+      add_to_program((unsigned char)(b>>24));
+      add_to_program((unsigned char)(b>>16));
+      add_to_program((unsigned char)(b>>8));
+    }
+  }
+  ins_f_byte(a);
+  add_to_program((PIKE_OPCODE_T)b);
+}
+
+static void ins_f_byte_with_2_args(unsigned int a,
+				   unsigned INT32 c,
+				   unsigned INT32 b)
+{
+  switch(b >> 8)
+  {
+  case 0 : break;
+  case 1 : ins_f_byte(F_PREFIX2_256); break;
+  case 2 : ins_f_byte(F_PREFIX2_512); break;
+  case 3 : ins_f_byte(F_PREFIX2_768); break;
+  case 4 : ins_f_byte(F_PREFIX2_1024); break;
+  default:
+    if( b < 256*256)
+    {
+      ins_f_byte(F_PREFIX2_CHARX256);
+      add_to_program((unsigned char)(b>>8));
+    }else if(b < 256*256*256) {
+      ins_f_byte(F_PREFIX2_WORDX256);
+      add_to_program((unsigned char)(b>>16));
+      add_to_program((unsigned char)(b>>8));
+    }else{
+      ins_f_byte(F_PREFIX2_24BITX256);
+      add_to_program((unsigned char)(b>>24));
+      add_to_program((unsigned char)(b>>16));
+      add_to_program((unsigned char)(b>>8));
+    }
+  }
+  ins_f_byte_with_arg(a,c);
+  add_to_program((PIKE_OPCODE_T)b);
+}
+
diff --git a/src/code/bytecode.h b/src/code/bytecode.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f716e4ea028fbc9e0b66088e2bdfe659fc7cadf
--- /dev/null
+++ b/src/code/bytecode.h
@@ -0,0 +1,5 @@
+/*
+ * $Id: bytecode.h,v 1.1 2001/07/20 12:44:52 grubba Exp $
+ */
+
+#define UPDATE_PC()
diff --git a/src/code/computedgoto.c b/src/code/computedgoto.c
new file mode 100644
index 0000000000000000000000000000000000000000..04029f262b5ed7c1271b44b0fc4f832aa87b5b88
--- /dev/null
+++ b/src/code/computedgoto.c
@@ -0,0 +1,68 @@
+/*
+ * $Id: computedgoto.c,v 1.1 2001/07/20 12:44:53 grubba Exp $
+ *
+ * Machine code generator for sparc.
+ *
+ * Henrik Grubbstr�m 20010720
+ */
+
+void ins_pointer(INT32 ptr)
+{
+  add_to_program((void *)(ptrdiff_t)ptr);
+}
+
+INT32 read_pointer(INT32 off)
+{
+  return (INT32)(ptrdiff_t)Pike_compiler->new_program->program[off];
+}
+
+void upd_pointer(INT32 off, INT32 ptr)
+{
+  Pike_compiler->new_program->program[off] = (void *)(ptrdiff_t)ptr;
+}
+
+void ins_align(INT32 align)
+{
+  /* Already aligned... */
+}
+
+void ins_byte(INT32 val)
+{
+  add_to_program((void *)(ptrdiff_t)val);
+}
+
+void ins_data(INT32 val)
+{
+  add_to_program((void *)(ptrdiff_t)val);
+}
+
+void ins_f_byte(unsigned int b)
+{
+#ifdef PIKE_DEBUG
+  if(store_linenumbers && b<F_MAX_OPCODE)
+    ADD_COMPILED(b);
+#endif /* PIKE_DEBUG */
+
+  b-=F_OFFSET;
+#ifdef PIKE_DEBUG
+  if(b>255)
+    Pike_error("Instruction too big %d\n",b);
+#endif
+    
+  add_to_program(fcode_to_opcode[b]);
+}
+
+void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
+{
+  ins_f_byte(a);
+  add_to_program((PIKE_OPCODE_T)b);
+}
+
+void ins_f_byte_with_2_args(unsigned int a,
+			    unsigned INT32 c,
+			    unsigned INT32 b)
+{
+  ins_f_byte_with_arg(a,c);
+  add_to_program((PIKE_OPCODE_T)b);
+}
+
diff --git a/src/code/computedgoto.h b/src/code/computedgoto.h
new file mode 100644
index 0000000000000000000000000000000000000000..49b3eaa9e4a79f9a87b4e9e5b37382baa110a35a
--- /dev/null
+++ b/src/code/computedgoto.h
@@ -0,0 +1,5 @@
+/*
+ * $Id: computedgoto.h,v 1.1 2001/07/20 12:44:53 grubba Exp $
+ */
+
+#define UPDATE_PC()
diff --git a/src/code/ia32.c b/src/code/ia32.c
new file mode 100644
index 0000000000000000000000000000000000000000..3ea5169c2217180f6cb0440e46d3803e72b342e1
--- /dev/null
+++ b/src/code/ia32.c
@@ -0,0 +1,119 @@
+/*
+ * $Id: ia32.c,v 1.1 2001/07/20 12:44:54 grubba Exp $
+ *
+ * Machine code generator for IA32.
+ *
+ */
+
+void ins_pointer(INT32 ptr)
+{
+  ins_int(ptr, add_to_program);
+}
+
+INT32 read_pointer(INT32 off)
+{
+  return read_int(off);
+}
+
+void upd_pointer(INT32 off, INT32 ptr)
+{
+  upd_int(off, ptr);
+}
+
+void ins_align(INT32 align)
+{
+  while(Pike_compiler->new_program->num_program % c->arg) {
+    add_to_program(0);
+  }
+}
+
+void ins_byte(INT32 val)
+{
+  add_to_program(val);
+}
+
+void ins_data(INT32 val)
+{
+  ins_int(val, add_to_program);
+}
+
+#define PUSH_INT(X) ins_int((INT32)(X), add_to_program)
+#define PUSH_ADDR(X) PUSH_INT((X))
+
+/* This is ugly, but since the code may be moved we cannot use
+ * relative addressing :(
+ */
+#define CALL_ABSOLUTE(X) do{			\
+  add_to_program(0xb8);	/* mov $xxx,%eax */	\
+  PUSH_INT(X);					\
+  add_to_program(0xff);	/* jsr *(%eax) */	\
+  add_to_program(0xd0);				\
+}while(0)
+
+#define UPDATE_PC() do {						\
+    INT32 tmp=PC;							\
+    add_to_program(0xa1 /* mov $xxxxx, %eax */);			\
+    ins_int((INT32)(&Pike_interpreter.frame_pointer), add_to_program);	\
+									\
+    add_to_program(0xc7); /* movl $xxxxx, yy%(eax) */			\
+    add_to_program(0x40);						\
+    add_to_program(OFFSETOF(pike_frame, pc));				\
+    ins_int((INT32)tmp, add_to_program);				\
+}while(0)
+
+void ins_f_byte(unsigned int b)
+{
+#ifdef PIKE_DEBUG
+  if(store_linenumbers && b<F_MAX_OPCODE)
+    ADD_COMPILED(b);
+#endif /* PIKE_DEBUG */
+
+  b-=F_OFFSET;
+#ifdef PIKE_DEBUG
+  if(b>255)
+    Pike_error("Instruction too big %d\n",b);
+#endif
+
+  do{
+    static int last_prog_id=-1;
+    static int last_num_linenumbers=-1;
+    if(last_prog_id != Pike_compiler->new_program->id ||
+       last_num_linenumbers != Pike_compiler->new_program->num_linenumbers)
+    {
+      last_prog_id=Pike_compiler->new_program->id;
+      last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;
+      UPDATE_PC();
+    }
+  }while(0);
+  
+  CALL_ABSOLUTE(instrs[b].address);
+  return;
+}
+
+static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
+{
+  add_to_program(0xc7);  /* movl $xxxx, (%esp) */
+  add_to_program(0x04); 
+  add_to_program(0x24); 
+  PUSH_INT(b);
+  ins_f_byte(a);
+  return;
+}
+
+static void ins_f_byte_with_2_args(unsigned int a,
+				   unsigned INT32 c,
+				   unsigned INT32 b)
+{
+  add_to_program(0xc7);  /* movl $xxxx, (%esp) */
+  add_to_program(0x04); 
+  add_to_program(0x24); 
+  PUSH_INT(c);
+  add_to_program(0xc7);  /* movl $xxxx, 4(%esp) */
+  add_to_program(0x44);
+  add_to_program(0x24);
+  add_to_program(0x04);
+  PUSH_INT(b);
+  ins_f_byte(a);
+  return;
+}
+
diff --git a/src/code/ia32.h b/src/code/ia32.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd826fdb3a4aff075eb7a7fdce1ad1fd37641515
--- /dev/null
+++ b/src/code/ia32.h
@@ -0,0 +1,15 @@
+/*
+ * $Id: ia32.h,v 1.1 2001/07/20 12:44:54 grubba Exp $
+ */
+
+#define UPDATE_PC() do {						\
+    INT32 tmp=PC;							\
+    add_to_program(0xa1 /* mov $xxxxx, %eax */);			\
+    ins_int((INT32)(&Pike_interpreter.frame_pointer), add_to_program);	\
+									\
+    add_to_program(0xc7); /* movl $xxxxx, yy%(eax) */			\
+    add_to_program(0x40);						\
+    add_to_program(OFFSETOF(pike_frame, pc));				\
+    ins_int((INT32)tmp, add_to_program);				\
+}while(0)
+
diff --git a/src/code/sparc.c b/src/code/sparc.c
new file mode 100644
index 0000000000000000000000000000000000000000..46f5efbd5f4dd462ca0945047f258de59c987943
--- /dev/null
+++ b/src/code/sparc.c
@@ -0,0 +1,98 @@
+/*
+ * $Id: sparc.c,v 1.1 2001/07/20 12:44:55 grubba Exp $
+ *
+ * Machine code generator for sparc.
+ *
+ * Henrik Grubbstr�m 20010720
+ */
+
+void ins_pointer(INT32 ptr)
+{
+  add_to_program(ptr);
+}
+
+INT32 read_pointer(INT32 off)
+{
+  return Pike_compiler->new_program->program[off];
+}
+
+void upd_pointer(INT32 off, INT32 ptr)
+{
+  Pike_compiler->new_program->program[off] = ptr;
+}
+
+void ins_align(INT32 align)
+{
+  /* Already aligned... */
+}
+
+void ins_byte(INT32 val)
+{
+  add_to_program(val);
+}
+
+void ins_data(INT32 val)
+{
+  add_to_program(val);
+}
+
+
+#define CALL_ABSOLUTE(X) do {						\
+    INT32 delta_;							\
+    struct program *p_ = Pike_compiler->new_program;			\
+    INT32 off_ = p_->num_program;					\
+    /* call X	*/							\
+    add_to_program(0); /* Placeholder... */				\
+    delta_ = ((PIKE_OPCODE_T *)(X)) - (p_->program + off_);		\
+    p_->program[off_] = 0x40000000 | (delta_ & 0x3fffffff);		\
+    add_to_relocations(off_);						\
+    /* noop		*/						\
+    add_to_program(0x01000000);						\
+  } while(0)
+
+void ins_f_byte(unsigned int b)
+{
+#ifdef PIKE_DEBUG
+  if(store_linenumbers && b<F_MAX_OPCODE)
+    ADD_COMPILED(b);
+#endif /* PIKE_DEBUG */
+
+  b-=F_OFFSET;
+#ifdef PIKE_DEBUG
+  if(b>255)
+    Pike_error("Instruction too big %d\n",b);
+#endif
+    
+  do{
+    static int last_prog_id=-1;
+    static int last_num_linenumbers=-1;
+    if(last_prog_id != Pike_compiler->new_program->id ||
+       last_num_linenumbers != Pike_compiler->new_program->num_linenumbers)
+    {
+      last_prog_id=Pike_compiler->new_program->id;
+      last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;
+      UPDATE_PC();
+    }
+  }while(0);
+  
+  CALL_ABSOLUTE(instrs[b].address);
+  return;
+}
+
+void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
+{
+  SET_REG(REG_O0, b);
+  ins_f_byte(a);
+  return;
+}
+
+void ins_f_byte_with_2_args(unsigned int a,
+			    unsigned INT32 c,
+			    unsigned INT32 b)
+{
+  SET_REG(REG_O0, c);
+  SET_REG(REG_O1, b);
+  ins_f_byte(a);
+  return;
+}
+
diff --git a/src/code/sparc.h b/src/code/sparc.h
new file mode 100644
index 0000000000000000000000000000000000000000..36225f559de0a9fb27a22e593a83629b072a96a3
--- /dev/null
+++ b/src/code/sparc.h
@@ -0,0 +1,43 @@
+/*
+ * $Id: sparc.h,v 1.1 2001/07/20 12:44:55 grubba Exp $
+ */
+
+#define REG_O0	8
+#define REG_O1	9
+#define REG_O2	10
+#define REG_O3	11
+#define REG_O4	12
+#define REG_O5	13
+#define REG_O6	14
+#define REG_O7	15
+
+#define SET_REG(REG, X) do {						\
+    INT32 val_ = X;							\
+    INT32 reg_ = REG;							\
+    if ((-4096 <= val_) && (val_ <= 4095)) {				\
+      /* or %g0, val_, reg */						\
+      add_to_program(0x80102000|(reg_<<25)|(val_ & 0x1fff));		\
+    } else {								\
+      /* sethi %hi(val_), reg */					\
+      add_to_program(0x01000000|(reg_<<25)|((val_ >> 10)&0x3fffff));	\
+      if (val_ & 0x3ff) {						\
+	/* or reg, %lo(val_), reg */					\
+	add_to_program(0x80102000|(reg_<<25)|(reg_<<14)|(val_ & 0x3ff)); \
+      }									\
+      if (val_ < 0) {							\
+	/* sra reg, %g0, reg */						\
+	add_to_program(0x81380000|(reg_<<25)|(reg_<<14));		\
+      }									\
+    }									\
+  } while(0)
+
+#define UPDATE_PC() do {						\
+    INT32 tmp = PC;							\
+    SET_REG(REG_O3, ((INT32)(&Pike_interpreter.frame_pointer)));	\
+    /* lduw %o3, %o3 */							\
+    add_to_program(0xc0000000|(REG_O3<<25)|(REG_O3<<14));		\
+    SET_REG(REG_O4, tmp);						\
+    /* stw %o4, yy(%o3) */						\
+    add_to_program(0xc0202000|(REG_O4<<25)|(REG_O3<<14)|		\
+		   OFFSETOF(pike_frame, pc));				\
+  } while(0)
diff --git a/src/peep.c b/src/peep.c
index 52cdc55776f597f0fedf1b5f59b88852dd56dcca..77b66539a950b225b2ebf9c6d1d9549f71f4f7a4 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -17,8 +17,9 @@
 #include "builtin_functions.h"
 #include "constants.h"
 #include "interpret.h"
+#include "pikecode.h"
 
-RCSID("$Id: peep.c,v 1.61 2001/07/19 16:20:26 grubba Exp $");
+RCSID("$Id: peep.c,v 1.62 2001/07/20 12:44:49 grubba Exp $");
 
 static void asm_opt(void);
 
@@ -136,239 +137,6 @@ void update_arg(int instr,INT32 arg)
 
 /**** Bytecode Generator *****/
 
-#ifdef PIKE_USE_MACHINE_CODE
-/* FIXME: Move this to pike_cpulib.h */
-#ifdef __GNUC__
-
-#ifdef __i386__
-
-#define PUSH_INT(X) ins_int((INT32)(X), add_to_program)
-#define PUSH_ADDR(X) PUSH_INT((X))
-
-/* This is ugly, but since the code may be moved we cannot use
- * relative addressing :(
- */
-#define CALL_ABSOLUTE(X) do{			\
-  add_to_program(0xb8);	/* mov $xxx,%eax */	\
-  PUSH_INT(X);					\
-  add_to_program(0xff);	/* jsr *(%eax) */	\
-  add_to_program(0xd0);				\
-}while(0)
-
-#define UPDATE_PC() do {						\
-    INT32 tmp=PC;							\
-    add_to_program(0xa1 /* mov $xxxxx, %eax */);			\
-    ins_int((INT32)(&Pike_interpreter.frame_pointer), add_to_program);	\
-									\
-    add_to_program(0xc7); /* movl $xxxxx, yy%(eax) */			\
-    add_to_program(0x40);						\
-    add_to_program(OFFSETOF(pike_frame, pc));				\
-    ins_int((INT32)tmp, add_to_program);				\
-}while(0)
-
-#elif defined(sparc)
-
-#define REG_O0	8
-#define REG_O1	9
-#define REG_O2	10
-#define REG_O3	11
-#define REG_O4	12
-#define REG_O5	13
-#define REG_O6	14
-#define REG_O7	15
-
-#define SET_REG(REG, X) do {						\
-    INT32 val_ = X;							\
-    INT32 reg_ = REG;							\
-    if ((-4096 <= val_) && (val_ <= 4095)) {				\
-      /* or %g0, val_, reg */						\
-      add_to_program(0x80102000|(reg_<<25)|(val_ & 0x1fff));		\
-    } else {								\
-      /* sethi %hi(val_), reg */					\
-      add_to_program(0x01000000|(reg_<<25)|((val_ >> 10)&0x3fffff));	\
-      if (val_ & 0x3ff) {						\
-	/* or reg, %lo(val_), reg */					\
-	add_to_program(0x80102000|(reg_<<25)|(reg_<<14)|(val_ & 0x3ff)); \
-      }									\
-      if (val_ < 0) {							\
-	/* sra reg, %g0, reg */						\
-	add_to_program(0x81380000|(reg_<<25)|(reg_<<14));		\
-      }									\
-    }									\
-  } while(0)
-
-#define CALL_ABSOLUTE(X) do {						\
-    INT32 delta_;							\
-    struct program *p_ = Pike_compiler->new_program;			\
-    INT32 off_ = p_->num_program;					\
-    /* call X	*/							\
-    add_to_program(0); /* Placeholder... */				\
-    delta_ = ((PIKE_OPCODE_T *)(X)) - (p_->program + off_);		\
-    p_->program[off_] = 0x40000000 | (delta_ & 0x3fffffff);		\
-    add_to_relocations(off_);						\
-    /* noop		*/						\
-    add_to_program(0x01000000);						\
-  } while(0)
-
-#if 1
-#define UPDATE_PC() do {						\
-    INT32 tmp = PC;							\
-    SET_REG(REG_O3, ((INT32)(&Pike_interpreter.frame_pointer)));	\
-    /* lduw %o3, %o3 */							\
-    add_to_program(0xc0000000|(REG_O3<<25)|(REG_O3<<14));		\
-    SET_REG(REG_O4, tmp);						\
-    /* stw %o4, yy(%o3) */						\
-    add_to_program(0xc0202000|(REG_O4<<25)|(REG_O3<<14)|		\
-		   OFFSETOF(pike_frame, pc));				\
-  } while(0)
-#else
-#define UPDATE_PC()
-#endif
-#endif /* __i386__ || sparc */
-#endif /* __GNUC__ */
-
-#else /* !PIKE_USE_MACHINE_CODE */
-#undef UPDATE_PC
-#define UPDATE_PC()
-#endif /* PIKE_USE_MACHINE_CODE */
-
-void ins_f_byte(unsigned int b)
-{
-#ifdef PIKE_DEBUG
-  if(store_linenumbers && b<F_MAX_OPCODE)
-    ADD_COMPILED(b);
-#endif /* PIKE_DEBUG */
-
-  b-=F_OFFSET;
-#ifdef PIKE_DEBUG
-  if(b>255)
-    Pike_error("Instruction too big %d\n",b);
-#endif
-    
-#ifdef PIKE_USE_MACHINE_CODE
-  do{
-    static int last_prog_id=-1;
-    static int last_num_linenumbers=-1;
-    if(last_prog_id != Pike_compiler->new_program->id ||
-       last_num_linenumbers != Pike_compiler->new_program->num_linenumbers)
-    {
-      last_prog_id=Pike_compiler->new_program->id;
-      last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;
-      UPDATE_PC();
-    }
-  }while(0);
-  
-  CALL_ABSOLUTE(instrs[b].address);
-  return;
-#endif
-
-#ifdef HAVE_COMPUTED_GOTO
-  add_to_program(fcode_to_opcode[b]);
-#else /* !HAVE_COMPUTED_GOTO */
-  add_to_program((unsigned char)b);
-#endif /* HAVE_COMPUTED_GOTO */
-}
-
-static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
-{
-#ifdef PIKE_USE_MACHINE_CODE
-#ifdef __GNUC__
-#ifdef __i386__
-  add_to_program(0xc7);  /* movl $xxxx, (%esp) */
-  add_to_program(0x04); 
-  add_to_program(0x24); 
-  PUSH_INT(b);
-#elif defined(sparc)
-  SET_REG(REG_O0, b);
-#endif /* __i386__ || sparc */
-  ins_f_byte(a);
-  return;
-#endif /* __GNUC__ */
-#endif
-
-#ifndef HAVE_COMPUTED_GOTO
-  switch(b >> 8)
-  {
-  case 0 : break;
-  case 1 : ins_f_byte(F_PREFIX_256); break;
-  case 2 : ins_f_byte(F_PREFIX_512); break;
-  case 3 : ins_f_byte(F_PREFIX_768); break;
-  case 4 : ins_f_byte(F_PREFIX_1024); break;
-  default:
-    if( b < 256*256)
-    {
-      ins_f_byte(F_PREFIX_CHARX256);
-      add_to_program((unsigned char)(b>>8));
-    }else if(b < 256*256*256) {
-      ins_f_byte(F_PREFIX_WORDX256);
-      add_to_program((unsigned char)(b>>16));
-      add_to_program((unsigned char)(b>>8));
-    }else{
-      ins_f_byte(F_PREFIX_24BITX256);
-      add_to_program((unsigned char)(b>>24));
-      add_to_program((unsigned char)(b>>16));
-      add_to_program((unsigned char)(b>>8));
-    }
-  }
-#endif /* !HAVE_COMPUTED_GOTO */
-  ins_f_byte(a);
-  add_to_program((PIKE_OPCODE_T)b);
-}
-
-static void ins_f_byte_with_2_args(unsigned int a,
-				   unsigned INT32 c,
-				   unsigned INT32 b)
-{
-#ifdef PIKE_USE_MACHINE_CODE
-#ifdef __GNUC__
-#ifdef __i386__
-  add_to_program(0xc7);  /* movl $xxxx, (%esp) */
-  add_to_program(0x04); 
-  add_to_program(0x24); 
-  PUSH_INT(c);
-  add_to_program(0xc7);  /* movl $xxxx, 4(%esp) */
-  add_to_program(0x44);
-  add_to_program(0x24);
-  add_to_program(0x04);
-  PUSH_INT(b);
-#elif defined(sparc)
-  SET_REG(REG_O0, c);
-  SET_REG(REG_O1, b);
-#endif /* __i386__ || sparc */
-  ins_f_byte(a);
-  return;
-#endif /* __GNUC__ */
-#endif
-
-#ifdef HAVE_COMPUTED_GOTO
-  switch(b >> 8)
-  {
-  case 0 : break;
-  case 1 : ins_f_byte(F_PREFIX2_256); break;
-  case 2 : ins_f_byte(F_PREFIX2_512); break;
-  case 3 : ins_f_byte(F_PREFIX2_768); break;
-  case 4 : ins_f_byte(F_PREFIX2_1024); break;
-  default:
-    if( b < 256*256)
-    {
-      ins_f_byte(F_PREFIX2_CHARX256);
-      add_to_program((unsigned char)(b>>8));
-    }else if(b < 256*256*256) {
-      ins_f_byte(F_PREFIX2_WORDX256);
-      add_to_program((unsigned char)(b>>16));
-      add_to_program((unsigned char)(b>>8));
-    }else{
-      ins_f_byte(F_PREFIX2_24BITX256);
-      add_to_program((unsigned char)(b>>24));
-      add_to_program((unsigned char)(b>>16));
-      add_to_program((unsigned char)(b>>8));
-    }
-  }
-#endif /* !HAVE_COMPUTED_GOTO */
-  ins_f_byte_with_arg(a,c);
-  add_to_program((PIKE_OPCODE_T)b);
-}
-
 void assemble(void)
 {
   INT32 d,max_label,tmp;
@@ -512,31 +280,15 @@ void assemble(void)
     case F_START_FUNCTION:
       break;
     case F_ALIGN:
-#ifndef HAVE_COMPUTED_GOTO
-#if !(defined(PIKE_USE_MACHINE_CODE) && defined(sparc))
-      while(PC % c->arg) add_to_program(0);
-#endif /* !(PIKE_USE_MACHINE_CODE && sparc) */
-#endif /* HAVE_COMPUTED_GOTO */
+      ins_align(c->arg);
       break;
 
     case F_BYTE:
-#ifdef HAVE_COMPUTED_GOTO
-      add_to_program((void *)(ptrdiff_t)(unsigned char)(c->arg));
-#elif defined(PIKE_USE_MACHINE_CODE) && defined(sparc)
-      add_to_program(c->arg);
-#else /* !HAVE_COMPUTED_GOTO */
-      add_to_program((unsigned char)(c->arg));
-#endif /* HAVE_COMPUTED_GOTO */
+      ins_byte((unsigned char)(c->arg));
       break;
 
     case F_DATA:
-#ifdef HAVE_COMPUTED_GOTO
-      add_to_program((void *)(ptrdiff_t)c->arg);
-#elif defined(PIKE_USE_MACHINE_CODE) && defined(sparc)
-      add_to_program(c->arg);
-#else /* !HAVE_COMPUTED_GOTO */
-      ins_int(c->arg, (void(*)(char))add_to_program);
-#endif /* HAVE_COMPUTED_GOTO */
+      ins_data(c->arg);
       break;
 
     case F_LABEL:
@@ -567,23 +319,17 @@ void assemble(void)
 	if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n");
 #endif
 	tmp = DO_NOT_WARN((INT32)PC);
-#ifdef HAVE_COMPUTED_GOTO
-	add_to_program(jumps[c->arg]);
-#elif defined(PIKE_USE_MACHINE_CODE) && defined(sparc)
-	add_to_program(jumps[c->arg]);
-#else /* !HAVE_COMPUTED_GOTO */
-	ins_int(jumps[c->arg], (void(*)(char))add_to_program);
-#endif /* HAVE_COMPUTED_GOTO */
+	ins_pointer(jumps[c->arg]);
 	jumps[c->arg]=tmp;
 	break;
 
-	case I_TWO_ARGS:
-	  ins_f_byte_with_2_args(c->opcode, c->arg, c->arg2);
-	  break;
+      case I_TWO_ARGS:
+	ins_f_byte_with_2_args(c->opcode, c->arg, c->arg2);
+	break;
 	  
-	case I_HASARG:
-	  ins_f_byte_with_arg(c->opcode, c->arg);
-	  break;
+      case I_HASARG:
+	ins_f_byte_with_arg(c->opcode, c->arg);
+	break;
 
       case 0:
 	ins_f_byte(c->opcode);
@@ -610,20 +356,9 @@ void assemble(void)
 	fatal("Hyperspace error: unknown jump point %ld at %d (pc=%x).\n",
 	      PTRDIFF_T_TO_LONG(e), labels[e], jumps[e]);
 #endif
-#ifdef HAVE_COMPUTED_GOTO
-      tmp = (int)(ptrdiff_t)(Pike_compiler->new_program->program[jumps[e]]);
-      Pike_compiler->new_program->program[jumps[e]] =
-	(PIKE_OPCODE_T)(ptrdiff_t)(tmp2 - jumps[e]);
-      jumps[e] = tmp;
-#elif defined(PIKE_USE_MACHINE_CODE) && defined(sparc)
-      tmp = Pike_compiler->new_program->program[jumps[e]];
-      Pike_compiler->new_program->program[jumps[e]] = tmp2 - jumps[e];
-      jumps[e] = tmp;      
-#else /* !HAVE_COMPUTED_GOTO */
-      tmp=read_int(jumps[e]);
-      upd_int(jumps[e], tmp2 - jumps[e]);
+      tmp = read_pointer(jumps[e]);
+      upd_pointer(jumps[e], tmp2 - jumps[e]);
       jumps[e]=tmp;
-#endif /* HAVE_COMPUTED_GOTO */
     }
   }
 
diff --git a/src/pikecode.c b/src/pikecode.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d83a7704ec750248d5078de4271e173c0941e50
--- /dev/null
+++ b/src/pikecode.c
@@ -0,0 +1,31 @@
+/*
+ * $Id: pikecode.c,v 1.1 2001/07/20 12:44:49 grubba Exp $
+ *
+ * Generic strap for the code-generator.
+ *
+ * Henrik Grubbstr�m 20010720
+ */
+
+#include "global.h"
+#include "program.h"
+#include "opcodes.h"
+#include "docode.h"
+#include "interpret.h"
+#include "language.h"
+#include "lex.h"
+
+#include "pikecode.h"
+
+#ifdef PIKE_USE_MACHINE_CODE
+#ifdef __i386__
+#include "code/ia32.c"
+#elif defined(sparc) || defined(__sparc__)
+#include "code/sparc.c"
+#else /* Unsupported cpu */
+#error Unknown CPU
+#endif /* CPU type */
+#elif defined(HAVE_COMPUTED_GOTO)
+#include "code/computedgoto.c"
+#else /* Default */
+#include "code/bytecode.c"
+#endif /* Interpreter type. */
diff --git a/src/pikecode.h b/src/pikecode.h
new file mode 100644
index 0000000000000000000000000000000000000000..6161766ec1de90475f373c3a2e3ea41a000c7a84
--- /dev/null
+++ b/src/pikecode.h
@@ -0,0 +1,41 @@
+/*
+ * $Id: pikecode.h,v 1.1 2001/07/20 12:44:50 grubba Exp $
+ *
+ * Generic headerfile for the code-generator.
+ *
+ * Henrik Grubbstr�m 20010720
+ */
+
+#ifndef CODE_PIKECODE_H
+#define CODE_PIKECODE_H
+
+void ins_pointer(INT32 ptr);
+INT32 read_pointer(INT32 off);
+void upd_pointer(INT32 off, INT32 ptr);
+
+void ins_byte(INT32 val);
+void ins_data(INT32 val);
+
+void ins_align(INT32 align);
+
+void ins_f_byte(unsigned int b);
+void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b);
+void ins_f_byte_with_2_args(unsigned int a,
+			    unsigned INT32 c,
+			    unsigned INT32 b);
+
+#ifdef PIKE_USE_MACHINE_CODE
+#ifdef __i386__
+#include "code/ia32.h"
+#elif defined(sparc) || defined(__sparc__)
+#include "code/sparc.h"
+#else /* Unsupported cpu */
+#error Unknown CPU
+#endif /* CPU type */
+#elif defined(HAVE_COMPUTED_GOTO)
+#include "code/computedgoto.h"
+#else /* Default */
+#include "code/bytecode.h"
+#endif /* Interpreter type. */
+
+#endif /* CODE_PIKECODE_H */