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"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
2199ed1996-04-13Fredrik Hübinette (Hubbe) #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"
d9a93b2001-07-01Fredrik Hübinette (Hubbe) #include "builtin_functions.h" #include "constants.h"
6a21702001-07-17Fredrik Hübinette (Hubbe) #include "interpret.h"
dd6bca2001-07-20Henrik Grubbström (Grubba) #include "pikecode.h"
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
a468a02001-07-24Henrik Grubbström (Grubba) RCSID("$Id: peep.c,v 1.65 2001/07/24 13:51:53 grubba Exp $");
24ddc71998-03-28Henrik Grubbström (Grubba) 
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; }
80fe612001-07-21Fredrik Hübinette (Hubbe) #ifndef FLUSH_CODE_GENERATOR_STATE #define FLUSH_CODE_GENERATOR_STATE() #endif
2199ed1996-04-13Fredrik Hübinette (Hubbe)  /**** Bytecode Generator *****/
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;
7386972001-06-30Fredrik Hübinette (Hubbe)  int reoptimize=!(debug_options & NO_PEEP_OPTIMIZING);
85f4f52001-01-31Martin Stjernholm #ifdef PIKE_DEBUG int synch_depth; #endif
2199ed1996-04-13Fredrik Hübinette (Hubbe)  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) 
928f952000-11-30Fredrik Hübinette (Hubbe)  while(reoptimize)
66d51c1997-03-04Fredrik Hübinette (Hubbe)  {
928f952000-11-30Fredrik Hübinette (Hubbe)  reoptimize=0; for(e=0;e<=max_label;e++) { labels[e]=jumps[e]=-1; uses[e]=0; } c=(p_instr *)instrbuf.s.str; for(e=0;e<length;e++) if(c[e].opcode == F_LABEL && c[e].arg>=0) labels[c[e].arg]=DO_NOT_WARN((INT32)e); for(e=0;e<length;e++)
66d51c1997-03-04Fredrik Hübinette (Hubbe)  {
928f952000-11-30Fredrik Hübinette (Hubbe)  if(instrs[c[e].opcode-F_OFFSET].flags & I_POINTER)
66d51c1997-03-04Fredrik Hübinette (Hubbe)  {
928f952000-11-30Fredrik Hübinette (Hubbe)  while(1)
419fab1997-03-09Fredrik Hübinette (Hubbe)  {
928f952000-11-30Fredrik Hübinette (Hubbe)  int tmp,tmp2; tmp=labels[c[e].arg]; while(tmp<length && (c[tmp].opcode == F_LABEL || c[tmp].opcode == F_NOP)) tmp++; if(tmp>=length) break; if(c[tmp].opcode==F_BRANCH) { c[e].arg=c[tmp].arg; continue; }
419fab1997-03-09Fredrik Hübinette (Hubbe) #define TWOO(X,Y) (((X)<<8)+(Y))
928f952000-11-30Fredrik Hübinette (Hubbe)  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; 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): if(c[e].file) free_string(c[e].file); c[e]=c[tmp]; if(c[e].file) add_ref(c[e].file); break; }
71c5b92000-11-27Fredrik Hübinette (Hubbe)  break;
419fab1997-03-09Fredrik Hübinette (Hubbe)  }
928f952000-11-30Fredrik Hübinette (Hubbe)  uses[c[e].arg]++;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  } }
928f952000-11-30Fredrik Hübinette (Hubbe)  for(e=0;e<=max_label;e++) { if(!uses[e] && labels[e]>=0) { c[labels[e]].opcode=F_NOP; reoptimize++; } } if(!reoptimize) break; asm_opt(); reoptimize=0;
66d51c1997-03-04Fredrik Hübinette (Hubbe)  } 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;
85f4f52001-01-31Martin Stjernholm #ifdef PIKE_DEBUG synch_depth = 0; #endif
80fe612001-07-21Fredrik Hübinette (Hubbe)  FLUSH_CODE_GENERATOR_STATE();
2199ed1996-04-13Fredrik Hübinette (Hubbe)  for(e=0;e<length;e++) {
6a21702001-07-17Fredrik Hübinette (Hubbe)  int linenumbers_stored=0;
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)  {
85f4f52001-01-31Martin Stjernholm  if (c->opcode == F_POP_SYNCH_MARK) synch_depth--; fprintf(stderr, "===%4d %4lx %*s", c->line, DO_NOT_WARN((unsigned long)PC), synch_depth, "");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  dump_instr(c); fprintf(stderr,"\n");
85f4f52001-01-31Martin Stjernholm  if (c->opcode == F_SYNCH_MARK) synch_depth++;
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:
928f952000-11-30Fredrik Hübinette (Hubbe)  case F_NOTREACHED:
873ceb2000-04-30Fredrik Hübinette (Hubbe)  case F_START_FUNCTION: break;
2199ed1996-04-13Fredrik Hübinette (Hubbe)  case F_ALIGN:
dd6bca2001-07-20Henrik Grubbström (Grubba)  ins_align(c->arg);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  break;
873ceb2000-04-30Fredrik Hübinette (Hubbe)  case F_BYTE:
dd6bca2001-07-20Henrik Grubbström (Grubba)  ins_byte((unsigned char)(c->arg));
873ceb2000-04-30Fredrik Hübinette (Hubbe)  break;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  case F_DATA:
dd6bca2001-07-20Henrik Grubbström (Grubba)  ins_data(c->arg);
9b08a21998-03-31Fredrik Hübinette (Hubbe)  break;
a468a02001-07-24Henrik Grubbström (Grubba)  case F_ENTRY: #ifdef INS_ENTRY INS_ENTRY(); #endif /* INS_ENTRY */ 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);
6a21702001-07-17Fredrik Hübinette (Hubbe)  UPDATE_PC();
80fe612001-07-21Fredrik Hübinette (Hubbe)  FLUSH_CODE_GENERATOR_STATE();
2199ed1996-04-13Fredrik Hübinette (Hubbe)  break;
3958992001-06-23Fredrik Hübinette (Hubbe)  case F_VOLATILE_RETURN: ins_f_byte(F_RETURN); break;
2d12341997-03-10Fredrik Hübinette (Hubbe)  default: switch(instrs[c->opcode - F_OFFSET].flags) { case I_ISJUMP:
852c152001-07-23Fredrik Hübinette (Hubbe) #ifdef INS_F_JUMP tmp=INS_F_JUMP(c->opcode); if(tmp != -1) { upd_pointer(tmp, jumps[c->arg]); jumps[c->arg]=~tmp; break; } #endif
2d12341997-03-10Fredrik Hübinette (Hubbe)  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);
dd6bca2001-07-20Henrik Grubbström (Grubba)  ins_pointer(jumps[c->arg]);
2d12341997-03-10Fredrik Hübinette (Hubbe)  jumps[c->arg]=tmp; break;
2199ed1996-04-13Fredrik Hübinette (Hubbe) 
dd6bca2001-07-20Henrik Grubbström (Grubba)  case I_TWO_ARGS: ins_f_byte_with_2_args(c->opcode, c->arg, c->arg2); break;
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
dd6bca2001-07-20Henrik Grubbström (Grubba)  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)  }
852c152001-07-23Fredrik Hübinette (Hubbe)  #ifdef ALIGN_PIKE_JUMPS if(e+1 < length) { switch(c->opcode) { case F_RETURN: case F_VOLATILE_RETURN: case F_BRANCH: case F_RETURN_0: case F_RETURN_1: case F_RETURN_LOCAL: #define CALLS(X) \ case PIKE_CONCAT3(F_,X,_AND_RETURN): \ case PIKE_CONCAT3(F_MARK_,X,_AND_RETURN): CALLS(APPLY) CALLS(CALL_FUNCTION) CALLS(CALL_LFUN) CALLS(CALL_BUILTIN) while( ((INT32) PC & (ALIGN_PIKE_JUMPS-1) ) ) ins_byte(0); } } #endif
2199ed1996-04-13Fredrik Hübinette (Hubbe)  c++; } for(e=0;e<=max_label;e++) {
c696242001-07-18Henrik Grubbström (Grubba)  INT32 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)
a4a1722000-12-05Per Hedbor  fatal("Hyperspace error: unknown jump point %ld at %d (pc=%x).\n",
69bb402000-08-17Henrik Grubbström (Grubba)  PTRDIFF_T_TO_LONG(e), labels[e], jumps[e]);
2199ed1996-04-13Fredrik Hübinette (Hubbe) #endif
852c152001-07-23Fredrik Hübinette (Hubbe) #ifdef INS_F_JUMP if(jumps[e] < 0) { tmp = read_pointer(~jumps[e]); UPDATE_F_JUMP(~jumps[e], tmp2); jumps[e]=tmp; continue; } #endif
dd6bca2001-07-20Henrik Grubbström (Grubba)  tmp = read_pointer(jumps[e]); upd_pointer(jumps[e], tmp2 - jumps[e]);
2199ed1996-04-13Fredrik Hübinette (Hubbe)  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) 
9cdf3f2000-12-02Henrik Grubbström (Grubba) static INLINE 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)
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  fatal("hasarg2(%d /*%s */) is wrong!\n",f,get_f_name(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;
9cdf3f2000-12-02Henrik Grubbström (Grubba)  copy_shared_string(p->file, cf);
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; }
9cdf3f2000-12-02Henrik Grubbström (Grubba) static INLINE 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)
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(f));
a96ce92000-04-19Fredrik Hübinette (Hubbe) #endif return insopt2(f,a,0,cl, cf); }
8d553a2000-12-02Henrik Grubbström (Grubba) static INLINE 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))
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(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;
85f4f52001-01-31Martin Stjernholm  int synch_depth = 0;
7a35a42000-08-14Henrik Grubbström (Grubba) 
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++) {
85f4f52001-01-31Martin Stjernholm  if (c->opcode == F_POP_SYNCH_MARK) synch_depth--; fprintf(stderr,"---%4d: %*s",c->line,synch_depth,"");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  dump_instr(c); fprintf(stderr,"\n");
85f4f52001-01-31Martin Stjernholm  if (c->opcode == F_SYNCH_MARK) synch_depth++;
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 }