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 */