2199ed1996-04-13Fredrik Hübinette (Hubbe) #include "global.h" #include "language.h" #include "stralloc.h" #include "dynamic_buffer.h" #include "program.h" #include "las.h" #include "docode.h" #include "main.h" #include "error.h" #include "lex.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
66d51c1997-03-04Fredrik Hübinette (Hubbe) #include "peep.h"
062e9d1998-03-04Fredrik Hübinette (Hubbe) #include "dmalloc.h"
7310011998-05-01Henrik Grubbström (Grubba) #include "stuff.h"
327b991999-10-25Fredrik Hübinette (Hubbe) #include "bignum.h"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h"
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
433ca92000-11-27Fredrik Hübinette (Hubbe) RCSID("$Id: peep.c,v 1.40 2000/11/28 02:19:16 hubbe Exp $");
24ddc71998-03-28Henrik Grubbström (Grubba) 
2199ed1996-04-13Fredrik Hübinette (Hubbe) struct p_instr_s { short opcode; short line;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *file;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  INT32 arg;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  INT32 arg2;
2199ed1996-04-13Fredrik Hübinette (Hubbe) }; typedef struct p_instr_s p_instr;
66d51c1997-03-04Fredrik Hübinette (Hubbe) static void asm_opt(void);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  dynamic_buffer instrbuf;
2d12341997-03-10Fredrik Hübinette (Hubbe) static int hasarg(int opcode) { return instrs[opcode-F_OFFSET].flags & I_HASARG; }
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) static int hasarg2(int opcode) { return instrs[opcode-F_OFFSET].flags & I_HASARG2; } #ifdef PIKE_DEBUG static void dump_instr(p_instr *p) { if(!p) return; fprintf(stderr,"%s",get_token_name(p->opcode)); if(hasarg(p->opcode)) { fprintf(stderr,"(%d",p->arg); if(hasarg2(p->opcode)) fprintf(stderr,",%d",p->arg2); fprintf(stderr,")"); } } #endif
be478c1997-08-30Henrik Grubbström (Grubba) void init_bytecode(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
e43ca21996-11-15Fredrik Hübinette (Hubbe)  low_reinit_buf(&instrbuf);
2199ed1996-04-13Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void exit_bytecode(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
7a35a42000-08-14Henrik Grubbström (Grubba)  ptrdiff_t e, length;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  p_instr *c; c=(p_instr *)instrbuf.s.str; length=instrbuf.s.len / sizeof(p_instr); for(e=0;e<length;e++) free_string(c->file); toss_buffer(&instrbuf); }
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insert_opcode2(unsigned int f, INT32 b, INT32 c, INT32 current_line, struct pike_string *current_file)
2199ed1996-04-13Fredrik Hübinette (Hubbe) { p_instr *p;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
a96ce92000-04-19Fredrik Hübinette (Hubbe)  if(!hasarg2(f) && c) fatal("hasarg2(%d) is wrong!\n",f);
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(!instrbuf.s.len) fatal("Low make buf space failed!!!!!!\n"); #endif p->opcode=f; p->line=current_line; copy_shared_string(p->file, current_file); p->arg=b;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  p->arg2=c;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  return p - (p_instr *)instrbuf.s.str; }
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insert_opcode1(unsigned int f, INT32 b, INT32 current_line, struct pike_string *current_file)
a96ce92000-04-19Fredrik Hübinette (Hubbe) { #ifdef PIKE_DEBUG if(!hasarg(f) && b) fatal("hasarg(%d) is wrong!\n",f); #endif return insert_opcode2(f,b,0,current_line,current_file); }
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insert_opcode0(int f,int current_line, struct pike_string *current_file)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(hasarg(f))
596e361998-03-31Fredrik Hübinette (Hubbe)  fatal("hasarg(%d) is wrong!\n",f);
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif
a96ce92000-04-19Fredrik Hübinette (Hubbe)  return insert_opcode1(f,0,current_line, current_file);
2199ed1996-04-13Fredrik Hübinette (Hubbe) }
419fab1997-03-09Fredrik Hübinette (Hubbe) 
2199ed1996-04-13Fredrik Hübinette (Hubbe) void update_arg(int instr,INT32 arg) { p_instr *p;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
645e261996-04-23Fredrik Hübinette (Hubbe)  if(instr > (long)instrbuf.s.len / (long)sizeof(p_instr) || instr < 0)
2199ed1996-04-13Fredrik Hübinette (Hubbe)  fatal("update_arg outside known space.\n"); #endif p=(p_instr *)instrbuf.s.str; p[instr].arg=arg; } /**** Bytecode Generator *****/ void ins_f_byte(unsigned int b) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
06983f1996-09-22Fredrik Hübinette (Hubbe)  if(store_linenumbers && b<F_MAX_OPCODE) ADD_COMPILED(b);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #endif /* PIKE_DEBUG */
06983f1996-09-22Fredrik Hübinette (Hubbe) 
2199ed1996-04-13Fredrik Hübinette (Hubbe)  b-=F_OFFSET;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(b>255)
e82b301997-01-29Fredrik Hübinette (Hubbe)  error("Instruction too big %d\n",b); #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_program((unsigned char)b);
2199ed1996-04-13Fredrik Hübinette (Hubbe) } 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);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>8));
2199ed1996-04-13Fredrik Hübinette (Hubbe)  }else if(b < 256*256*256) { ins_f_byte(F_PREFIX_WORDX256);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>16)); add_to_program((unsigned char)(b>>8));
2199ed1996-04-13Fredrik Hübinette (Hubbe)  }else{ ins_f_byte(F_PREFIX_24BITX256);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>24)); add_to_program((unsigned char)(b>>16)); add_to_program((unsigned char)(b>>8));
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } } ins_f_byte(a);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)b);
2199ed1996-04-13Fredrik Hübinette (Hubbe) }
a96ce92000-04-19Fredrik Hübinette (Hubbe) 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);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>8));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  }else if(b < 256*256*256) { ins_f_byte(F_PREFIX2_WORDX256);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>16)); add_to_program((unsigned char)(b>>8));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  }else{ ins_f_byte(F_PREFIX2_24BITX256);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(b>>24)); add_to_program((unsigned char)(b>>16)); add_to_program((unsigned char)(b>>8));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  } } ins_f_byte_with_arg(a,c);
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)b);
a96ce92000-04-19Fredrik Hübinette (Hubbe) }
66d51c1997-03-04Fredrik Hübinette (Hubbe) void assemble(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
7a35a42000-08-14Henrik Grubbström (Grubba)  INT32 d,max_label,tmp;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  INT32 *labels, *jumps, *uses;
7a35a42000-08-14Henrik Grubbström (Grubba)  ptrdiff_t e, length;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  p_instr *c; c=(p_instr *)instrbuf.s.str; length=instrbuf.s.len / sizeof(p_instr);
66d51c1997-03-04Fredrik Hübinette (Hubbe)  max_label=-1;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  for(e=0;e<length;e++,c++) if(c->opcode == F_LABEL) if(c->arg > max_label) max_label = c->arg;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  labels=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); jumps=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); uses=(INT32 *)xalloc(sizeof(INT32) * (max_label+2));
66d51c1997-03-04Fredrik Hübinette (Hubbe)  for(e=0;e<=max_label;e++) { labels[e]=jumps[e]=-1; uses[e]=0; }
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
66d51c1997-03-04Fredrik Hübinette (Hubbe)  c=(p_instr *)instrbuf.s.str; for(e=0;e<length;e++)
873ceb2000-04-30Fredrik Hübinette (Hubbe)  if(c[e].opcode == F_LABEL && c[e].arg>=0)
7a35a42000-08-14Henrik Grubbström (Grubba)  labels[c[e].arg]=DO_NOT_WARN((INT32)e);
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
66d51c1997-03-04Fredrik Hübinette (Hubbe)  for(e=0;e<length;e++) {
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(instrs[c[e].opcode-F_OFFSET].flags & I_POINTER)
66d51c1997-03-04Fredrik Hübinette (Hubbe)  { while(1) {
419fab1997-03-09Fredrik Hübinette (Hubbe)  int tmp,tmp2;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  tmp=labels[c[e].arg];
b11eaa1997-07-20Fredrik Hübinette (Hubbe)  while(tmp<length && (c[tmp].opcode == F_LABEL || c[tmp].opcode == F_NOP)) tmp++;
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
b11eaa1997-07-20Fredrik Hübinette (Hubbe)  if(tmp>=length) break;
419fab1997-03-09Fredrik Hübinette (Hubbe)  if(c[tmp].opcode==F_BRANCH) { c[e].arg=c[tmp].arg; continue; } #define TWOO(X,Y) (((X)<<8)+(Y)) switch(TWOO(c[e].opcode,c[tmp].opcode)) { case TWOO(F_LOR,F_BRANCH_WHEN_NON_ZERO): c[e].opcode=F_BRANCH_WHEN_NON_ZERO; case TWOO(F_LOR,F_LOR): c[e].arg=c[tmp].arg; continue; case TWOO(F_LAND,F_BRANCH_WHEN_ZERO): c[e].opcode=F_BRANCH_WHEN_ZERO; case TWOO(F_LAND,F_LAND): c[e].arg=c[tmp].arg; continue;
71c5b92000-11-27Fredrik Hübinette (Hubbe)  case TWOO(F_LOR, F_RETURN): c[e].opcode=F_RETURN_IF_TRUE; break; case TWOO(F_BRANCH, F_RETURN): case TWOO(F_BRANCH, F_RETURN_0): case TWOO(F_BRANCH, F_RETURN_1): case TWOO(F_BRANCH, F_RETURN_LOCAL):
433ca92000-11-27Fredrik Hübinette (Hubbe)  if(c[e].file) free_string(c[e].file);
71c5b92000-11-27Fredrik Hübinette (Hubbe)  c[e]=c[tmp];
433ca92000-11-27Fredrik Hübinette (Hubbe)  if(c[e].file) add_ref(c[e].file);
71c5b92000-11-27Fredrik Hübinette (Hubbe)  break;
419fab1997-03-09Fredrik Hübinette (Hubbe)  } break;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  } uses[c[e].arg]++; } } for(e=0;e<=max_label;e++) if(!uses[e] && labels[e]>=0) c[labels[e]].opcode=F_NOP; asm_opt(); c=(p_instr *)instrbuf.s.str; length=instrbuf.s.len / sizeof(p_instr); for(e=0;e<=max_label;e++) labels[e]=jumps[e]=-1;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  c=(p_instr *)instrbuf.s.str; for(e=0;e<length;e++) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2ba9191999-10-23Fredrik Hübinette (Hubbe)  if((a_flag > 2 && store_linenumbers) || a_flag > 3)
2199ed1996-04-13Fredrik Hübinette (Hubbe)  {
393a592000-08-16Henrik Grubbström (Grubba)  fprintf(stderr, "===%3d %4lx ", c->line, DO_NOT_WARN((unsigned long)PC));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  dump_instr(c); fprintf(stderr,"\n");
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } #endif if(store_linenumbers) store_linenumber(c->line, c->file); switch(c->opcode) {
873ceb2000-04-30Fredrik Hübinette (Hubbe)  case F_NOP: case F_START_FUNCTION: break;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  case F_ALIGN:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  while(PC % c->arg) add_to_program(0);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  break;
873ceb2000-04-30Fredrik Hübinette (Hubbe)  case F_BYTE:
3a1bb12000-09-22Henrik Grubbström (Grubba)  add_to_program((unsigned char)(c->arg));
873ceb2000-04-30Fredrik Hübinette (Hubbe)  break;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  case F_DATA: ins_int(c->arg, (void(*)(char))add_to_program); break;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  case F_LABEL:
873ceb2000-04-30Fredrik Hübinette (Hubbe)  if(c->arg == -1) break;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(c->arg > max_label || c->arg < 0) fatal("max_label calculation failed!\n"); if(labels[c->arg] != -1) fatal("Duplicate label!\n"); #endif
393a592000-08-16Henrik Grubbström (Grubba)  labels[c->arg] = DO_NOT_WARN((INT32)PC);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  break;
2d12341997-03-10Fredrik Hübinette (Hubbe)  default: switch(instrs[c->opcode - F_OFFSET].flags) { case I_ISJUMP: ins_f_byte(c->opcode);
7951942000-04-20Fredrik Hübinette (Hubbe) 
2d12341997-03-10Fredrik Hübinette (Hubbe)  case I_ISPOINTER:
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n");
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif
393a592000-08-16Henrik Grubbström (Grubba)  tmp = DO_NOT_WARN((INT32)PC);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ins_int(jumps[c->arg], (void(*)(char))add_to_program);
2d12341997-03-10Fredrik Hübinette (Hubbe)  jumps[c->arg]=tmp; break;
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
87c7592000-04-18Fredrik Hübinette (Hubbe)  case I_TWO_ARGS:
a96ce92000-04-19Fredrik Hübinette (Hubbe)  ins_f_byte_with_2_args(c->opcode, c->arg,c->arg2); break;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  case I_HASARG: ins_f_byte_with_arg(c->opcode, c->arg); break;
2d12341997-03-10Fredrik Hübinette (Hubbe)  case 0:
2199ed1996-04-13Fredrik Hübinette (Hubbe)  ins_f_byte(c->opcode);
2d12341997-03-10Fredrik Hübinette (Hubbe)  break;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2d12341997-03-10Fredrik Hübinette (Hubbe)  default: fatal("Unknown instruction type.\n"); #endif }
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } c++; } for(e=0;e<=max_label;e++) {
66d51c1997-03-04Fredrik Hübinette (Hubbe)  int tmp2=labels[e];
2199ed1996-04-13Fredrik Hübinette (Hubbe)  while(jumps[e]!=-1) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(labels[e]==-1)
69bb402000-08-17Henrik Grubbström (Grubba)  fatal("Hyperspace error: unknown jump point %ld at %d (pc=%x).\n", PTRDIFF_T_TO_LONG(e), labels[e], jumps[e]);
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif tmp=read_int(jumps[e]); upd_int(jumps[e], tmp2 - jumps[e]); jumps[e]=tmp; } } free((char *)labels); free((char *)jumps);
66d51c1997-03-04Fredrik Hübinette (Hubbe)  free((char *)uses);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  exit_bytecode(); } /**** Peephole optimizer ****/
a7538d1998-05-12Fredrik Hübinette (Hubbe) int remove_clear_locals=0x7fffffff;
7a35a42000-08-14Henrik Grubbström (Grubba) static int fifo_len; static ptrdiff_t eye, len;
06983f1996-09-22Fredrik Hübinette (Hubbe) static p_instr *instructions;
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insopt2(int f, INT32 a, INT32 b, int cl, struct pike_string *cf)
419fab1997-03-09Fredrik Hübinette (Hubbe) { p_instr *p;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
a96ce92000-04-19Fredrik Hübinette (Hubbe)  if(!hasarg2(f) && b)
596e361998-03-31Fredrik Hübinette (Hubbe)  fatal("hasarg(%d) is wrong!\n",f);
419fab1997-03-09Fredrik Hübinette (Hubbe) #endif p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf); if(fifo_len) { MEMMOVE(p-fifo_len+1,p-fifo_len,fifo_len*sizeof(p_instr)); p-=fifo_len; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
419fab1997-03-09Fredrik Hübinette (Hubbe)  if(!instrbuf.s.len) fatal("Low make buf space failed!!!!!!\n"); #endif p->opcode=f;
e7df5b1997-03-17Fredrik Hübinette (Hubbe)  p->line=cl;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  copy_shared_string(p->file, lex.current_file);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  p->arg=a; p->arg2=b;
419fab1997-03-09Fredrik Hübinette (Hubbe)  return p - (p_instr *)instrbuf.s.str; }
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insopt1(int f, INT32 a, int cl, struct pike_string *cf)
a96ce92000-04-19Fredrik Hübinette (Hubbe) { #ifdef PIKE_DEBUG if(!hasarg(f) && a) fatal("hasarg(%d) is wrong!\n",f); #endif return insopt2(f,a,0,cl, cf); }
7a35a42000-08-14Henrik Grubbström (Grubba) ptrdiff_t insopt0(int f, int cl, struct pike_string *cf)
419fab1997-03-09Fredrik Hübinette (Hubbe) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
419fab1997-03-09Fredrik Hübinette (Hubbe)  if(hasarg(f))
596e361998-03-31Fredrik Hübinette (Hubbe)  fatal("hasarg(%d) is wrong!\n",f);
419fab1997-03-09Fredrik Hübinette (Hubbe) #endif
a96ce92000-04-19Fredrik Hübinette (Hubbe)  return insopt2(f,0,0,cl, cf);
419fab1997-03-09Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) static void debug(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
645e261996-04-23Fredrik Hübinette (Hubbe)  if(fifo_len > (long)instrbuf.s.len / (long)sizeof(p_instr))
66d51c1997-03-04Fredrik Hübinette (Hubbe)  fifo_len=(long)instrbuf.s.len / (long)sizeof(p_instr);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(eye < 0) fatal("Popped beyond start of code.\n"); if(instrbuf.s.len) {
66d51c1997-03-04Fredrik Hübinette (Hubbe)  p_instr *p;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  p=(p_instr *)low_make_buf_space(0, &instrbuf); if(!p[-1].file) fatal("No file name on last instruction!\n"); } #endif
66d51c1997-03-04Fredrik Hübinette (Hubbe) }
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
8ebb6a1998-04-27Fredrik Hübinette (Hubbe) static INLINE p_instr *instr(int offset)
2199ed1996-04-13Fredrik Hübinette (Hubbe) { p_instr *p; debug();
419fab1997-03-09Fredrik Hübinette (Hubbe)  if(offset < fifo_len)
2199ed1996-04-13Fredrik Hübinette (Hubbe)  {
419fab1997-03-09Fredrik Hübinette (Hubbe)  p=(p_instr *)low_make_buf_space(0, &instrbuf); p-=fifo_len; p+=offset; if(((char *)p)<instrbuf.s.str) return 0; return p;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  }else{
419fab1997-03-09Fredrik Hübinette (Hubbe)  offset-=fifo_len; offset+=eye; if(offset >= len) return 0; return instructions+offset;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } }
8ebb6a1998-04-27Fredrik Hübinette (Hubbe) static INLINE int opcode(int offset)
2199ed1996-04-13Fredrik Hübinette (Hubbe) { p_instr *a; a=instr(offset); if(a) return a->opcode; return -1; }
8ebb6a1998-04-27Fredrik Hübinette (Hubbe) static INLINE int argument(int offset)
2199ed1996-04-13Fredrik Hübinette (Hubbe) { p_instr *a; a=instr(offset); if(a) return a->arg; return -1; }
a96ce92000-04-19Fredrik Hübinette (Hubbe) static INLINE int argument2(int offset) { p_instr *a; a=instr(offset); if(a) return a->arg2; return -1; }
be478c1997-08-30Henrik Grubbström (Grubba) static void advance(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) { if(fifo_len) { fifo_len--; }else{ p_instr *p;
9c6f7d1997-04-15Fredrik Hübinette (Hubbe)  if((p=instr(0)))
a96ce92000-04-19Fredrik Hübinette (Hubbe)  insert_opcode2(p->opcode, p->arg, p->arg2, p->line, p->file);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  eye++; } debug(); } static void pop_n_opcodes(int n) {
66d51c1997-03-04Fredrik Hübinette (Hubbe)  int e,d; if(fifo_len)
2199ed1996-04-13Fredrik Hübinette (Hubbe)  {
66d51c1997-03-04Fredrik Hübinette (Hubbe)  p_instr *p;
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
419fab1997-03-09Fredrik Hübinette (Hubbe)  d=n; if(d>fifo_len) d=fifo_len;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
66d51c1997-03-04Fredrik Hübinette (Hubbe)  if((long)d > (long)instrbuf.s.len / (long)sizeof(p_instr)) fatal("Popping out of instructions.\n");
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif
66d51c1997-03-04Fredrik Hübinette (Hubbe) 
b956702000-11-25Henrik Grubbström (Grubba)  /* FIXME: It looks like the fifo could be optimized. * /grubba 2000-11-21 (in Versailles) */
66d51c1997-03-04Fredrik Hübinette (Hubbe)  p=(p_instr *)low_make_buf_space(0, &instrbuf);
419fab1997-03-09Fredrik Hübinette (Hubbe)  p-=fifo_len;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  for(e=0;e<d;e++) free_string(p[e].file); fifo_len-=d; if(fifo_len) MEMMOVE(p,p+d,fifo_len*sizeof(p_instr)); n-=d;
419fab1997-03-09Fredrik Hübinette (Hubbe)  low_make_buf_space(-((INT32)sizeof(p_instr))*d, &instrbuf);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  }
66d51c1997-03-04Fredrik Hübinette (Hubbe)  eye+=n;
2199ed1996-04-13Fredrik Hübinette (Hubbe) }
b956702000-11-25Henrik Grubbström (Grubba) #define DO_OPTIMIZATION_PREQUEL(topop) do { \ struct pike_string *cf; \ INT32 cl=instr(0)->line; \ \ DO_IF_DEBUG( \ if(a_flag>5) \ { \ int e; \ fprintf(stderr,"PEEP at %d:",cl); \ for(e=0;e<topop;e++) \ { \ fprintf(stderr," "); \ dump_instr(instr(e)); \ } \ fprintf(stderr," => "); \ } \ ) \ \ copy_shared_string(cf,instr(0)->file); \ pop_n_opcodes(topop) #define DO_OPTIMIZATION_POSTQUEL(q) \ fifo_len+=q; \ free_string(cf); \ debug(); \ \ DO_IF_DEBUG( \ if(a_flag>5) \ { \ int e; \ for(e=0;e<q;e++) \ { \ fprintf(stderr," "); \ dump_instr(instr(e)); \ } \ fprintf(stderr,"\n"); \ } \ ) \ \ fifo_len += q + 3; \ } while(0)
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
8ebb6a1998-04-27Fredrik Hübinette (Hubbe) static void do_optimization(int topop, ...) { va_list arglist; int q=-1;
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
b956702000-11-25Henrik Grubbström (Grubba)  DO_OPTIMIZATION_PREQUEL(topop);
8ebb6a1998-04-27Fredrik Hübinette (Hubbe)  va_start(arglist, topop); while(1) { q++; switch(va_arg(arglist, int)) { case 0: break; case 1: { int i=va_arg(arglist, int);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  insopt0(i,cl,cf);
8ebb6a1998-04-27Fredrik Hübinette (Hubbe)  continue; } case 2: { int i=va_arg(arglist, int); int j=va_arg(arglist, int);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  insopt1(i,j,cl,cf); continue; } case 3: { int i=va_arg(arglist, int); int j=va_arg(arglist, int); int k=va_arg(arglist, int); insopt2(i,j,k,cl,cf);
8ebb6a1998-04-27Fredrik Hübinette (Hubbe)  continue; } } break; } va_end(arglist);
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
b956702000-11-25Henrik Grubbström (Grubba)  DO_OPTIMIZATION_POSTQUEL(q);
8ebb6a1998-04-27Fredrik Hübinette (Hubbe) }
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
66d51c1997-03-04Fredrik Hübinette (Hubbe) static void asm_opt(void)
2199ed1996-04-13Fredrik Hübinette (Hubbe) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(a_flag > 3) { p_instr *c;
7a35a42000-08-14Henrik Grubbström (Grubba)  ptrdiff_t e, length;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  c=(p_instr *)instrbuf.s.str; length=instrbuf.s.len / sizeof(p_instr); fprintf(stderr,"Optimization begins: \n"); for(e=0;e<length;e++,c++) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  fprintf(stderr,"---%3d: ",c->line); dump_instr(c); fprintf(stderr,"\n");
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } } #endif
7018811999-11-08Henrik Grubbström (Grubba) #ifndef IN_TPIKE
2199ed1996-04-13Fredrik Hübinette (Hubbe) #include "peep_engine.c"
7018811999-11-08Henrik Grubbström (Grubba) #endif /* IN_TPIKE */
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2199ed1996-04-13Fredrik Hübinette (Hubbe)  if(a_flag > 4) { p_instr *c;
7a35a42000-08-14Henrik Grubbström (Grubba)  ptrdiff_t e, length;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  c=(p_instr *)instrbuf.s.str; length=instrbuf.s.len / sizeof(p_instr); fprintf(stderr,"Optimization begins: \n"); for(e=0;e<length;e++,c++) {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  fprintf(stderr,">>>%3d: ",c->line); dump_instr(c); fprintf(stderr,"\n");
2199ed1996-04-13Fredrik Hübinette (Hubbe)  } } #endif }