Diff for /gforth/engine/main.c between versions 1.73 and 1.74

version 1.73, 2002/12/08 09:57:54 version 1.74, 2002/12/08 20:24:35
Line 81  char *progname = "gforth"; Line 81  char *progname = "gforth";
 int optind = 1;  int optind = 1;
 #endif  #endif
   
 #define CODE_BLOCK_SIZE (1024*1024)  #define CODE_BLOCK_SIZE (256*1024)
 Address code_area=0;  Address code_area=0;
 Cell code_area_size = CODE_BLOCK_SIZE;  Cell code_area_size = CODE_BLOCK_SIZE;
 Address code_here=0; /* does for code-area what HERE does for the dictionary */  Address code_here=0; /* does for code-area what HERE does for the dictionary */
 Address start_flush=0; /* start of unflushed code */  Address start_flush=0; /* start of unflushed code */
   Cell last_jump=0; /* if the last prim was compiled without jump, this
                        is it's number, otherwise this contains 0 */
   
 static int no_super=0;   /* true if compile_prim should not fuse prims */  static int no_super=0;   /* true if compile_prim should not fuse prims */
 /* --no-dynamic by default on gcc versions >=3.1 (it works with 3.0.4,  /* --no-dynamic by default on gcc versions >=3.1 (it works with 3.0.4,
Line 449  void print_sizes(Cell sizebyte) Line 451  void print_sizes(Cell sizebyte)
 #ifndef NO_DYNAMIC  #ifndef NO_DYNAMIC
 typedef struct {  typedef struct {
   Label start;    Label start;
   Cell length; /* excluding the jump */    Cell length; /* only includes the jump iff superend is true*/
     Cell restlength; /* length of the rest (i.e., the jump or (on superend) 0) */
   char superend; /* true if primitive ends superinstruction, i.e.,    char superend; /* true if primitive ends superinstruction, i.e.,
                      unconditional branch, execute, etc. */                       unconditional branch, execute, etc. */
   Cell nimmargs;    Cell nimmargs;
Line 508  void check_prims(Label symbols1[]) Line 511  void check_prims(Label symbols1[])
       pi->length = symbols1[i+1]-symbols1[i];        pi->length = symbols1[i+1]-symbols1[i];
     else      else
       pi->length = prim_len;        pi->length = prim_len;
       pi->restlength = symbols1[i+1] - symbols1[i] - pi->length;
     pi->nimmargs = 0;      pi->nimmargs = 0;
     if (debug)      if (debug)
       fprintf(stderr, "Prim %3d @ %p %p %p, length=%3d superend=%1d",        fprintf(stderr, "Prim %3d @ %p %p %p, length=%3d restlength=%2d superend=%1d",
               i, s1, s2, s3, prim_len, pi->superend);                i, s1, s2, s3, pi->length, pi->restlength, pi->superend);
     assert(prim_len>=0);      assert(prim_len>=0);
     while (j<prim_len) {      while (j<(pi->length+pi->restlength)) {
       if (s1[j]==s3[j]) {        if (s1[j]==s3[j]) {
         if (s1[j] != s2[j]) {          if (s1[j] != s2[j]) {
           pi->start = NULL; /* not relocatable */            pi->start = NULL; /* not relocatable */
           if (debug)            if (debug)
             fprintf(stderr,"\n   non_reloc: engine1!=engine2 offset %3d",j);              fprintf(stderr,"\n   non_reloc: engine1!=engine2 offset %3d",j);
             /* assert(j<prim_len); */
           break;            break;
         }          }
         j++;          j++;
Line 540  void check_prims(Label symbols1[]) Line 545  void check_prims(Label symbols1[])
           pi->start = NULL; /* not relocatable */            pi->start = NULL; /* not relocatable */
           if (debug)            if (debug)
             fprintf(stderr,"\n   non_reloc: engine1!=engine3 offset %3d",j);              fprintf(stderr,"\n   non_reloc: engine1!=engine3 offset %3d",j);
             /* assert(j<prim_len);*/
           break;            break;
         }          }
         j+=4;          j+=4;
Line 551  void check_prims(Label symbols1[]) Line 557  void check_prims(Label symbols1[])
 #endif  #endif
 }  }
   
   #ifndef NO_DYNAMIC
   void flush_to_here(void)
   {
     FLUSH_ICACHE(start_flush, code_here-start_flush);
     start_flush=code_here;
   }
   
   void append_jump(void)
   {
     if (last_jump) {
       PrimInfo *pi = &priminfos[last_jump];
       
       memcpy(code_here, pi->start+pi->length, pi->restlength);
       code_here += pi->restlength;
       last_jump=0;
       flush_to_here();
     }
   }
   
   Address append_prim(Cell p)
   {
     PrimInfo *pi = &priminfos[p];
     Address old_code_here = code_here;
   
     if (code_area+code_area_size < code_here+pi->length+pi->restlength) {
       /* not enough space for all cases */
       append_jump();
       code_here = start_flush = code_area = my_alloc(code_area_size);
       old_code_here = code_here;
     }
     memcpy(code_here, pi->start, pi->length);
     code_here += pi->length;
     if (pi->superend)
       flush_to_here();
     return old_code_here;
   }
   #endif
   
 #ifdef NO_IP  #ifdef NO_IP
 int nbranchinfos=0;  int nbranchinfos=0;
   
Line 586  Cell *compile_prim1arg(Cell p) Line 630  Cell *compile_prim1arg(Cell p)
   int l = priminfos[p].length;    int l = priminfos[p].length;
   Address old_code_here=code_here;    Address old_code_here=code_here;
   
   memcpy(code_here, vm_prims[p], l);    assert(vm_prims[p]==priminfos[p].start);
   code_here+=l;    append_prim(p);
   return (Cell*)(old_code_here+priminfos[p].immargs[0].offset);    return (Cell*)(old_code_here+priminfos[p].immargs[0].offset);
 }  }
   
Line 595  Cell *compile_call2(Cell targetptr) Line 639  Cell *compile_call2(Cell targetptr)
 {  {
   Cell *next_code_target;    Cell *next_code_target;
   PrimInfo *pi = &priminfos[N_call2];    PrimInfo *pi = &priminfos[N_call2];
     Address old_code_here = append_prim(N_call2);
   
   memcpy(code_here, pi->start, pi->length);    next_code_target = (Cell *)(old_code_here + pi->immargs[0].offset);
   next_code_target = (Cell *)(code_here + pi->immargs[0].offset);    register_branchinfo(old_code_here + pi->immargs[1].offset, targetptr);
   register_branchinfo(code_here + pi->immargs[1].offset, targetptr);  
   code_here += pi->length;  
   return next_code_target;    return next_code_target;
 }  }
 #endif  #endif
Line 668  void compile_prim1(Cell *start) Line 711  void compile_prim1(Cell *start)
       set_rel_target(compile_prim1arg(N_abranch),*(Xt)last_prim);        set_rel_target(compile_prim1arg(N_abranch),*(Xt)last_prim);
     } else {      } else {
       unsigned j;        unsigned j;
         Address old_code_here = append_prim(i);
   
       memcpy(code_here, *last_prim, pi->length);  
       for (j=0; j<pi->nimmargs; j++) {        for (j=0; j<pi->nimmargs; j++) {
         struct immarg *ia = &(pi->immargs[j]);          struct immarg *ia = &(pi->immargs[j]);
         Cell argval = last_start[pi->nimmargs - j]; /* !! specific to prims */          Cell argval = last_start[pi->nimmargs - j]; /* !! specific to prims */
         if (ia->rel) { /* !! assumption: relative refs are branches */          if (ia->rel) { /* !! assumption: relative refs are branches */
           register_branchinfo(code_here + ia->offset, argval);            register_branchinfo(old_code_here + ia->offset, argval);
         } else /* plain argument */          } else /* plain argument */
           *(Cell *)(code_here + ia->offset) = argval;            *(Cell *)(old_code_here + ia->offset) = argval;
       }        }
       code_here += pi->length;  
     }      }
     if (next_code_target!=NULL)      if (next_code_target!=NULL)
       *next_code_target = (Cell)code_here;        *next_code_target = (Cell)code_here;
Line 692  void compile_prim1(Cell *start) Line 734  void compile_prim1(Cell *start)
 #elif !defined(NO_DYNAMIC)  #elif !defined(NO_DYNAMIC)
   Label prim=(Label)*start;    Label prim=(Label)*start;
   unsigned i;    unsigned i;
   Address old_code_here=code_here;    Address old_code_here;
   static Address last_jump=0;  
   
   i = ((Xt)prim)-vm_prims;    i = ((Xt)prim)-vm_prims;
   prim = *(Xt)prim;    prim = *(Xt)prim;
Line 702  void compile_prim1(Cell *start) Line 743  void compile_prim1(Cell *start)
     return;      return;
   }    }
   if (i>=npriminfos || priminfos[i].start == 0) { /* not a relocatable prim */    if (i>=npriminfos || priminfos[i].start == 0) { /* not a relocatable prim */
     if (last_jump) { /* make sure the last sequence is complete */      append_jump();
       memcpy(code_here, last_jump, IND_JUMP_LENGTH);  
       code_here += IND_JUMP_LENGTH;  
       last_jump = 0;  
       FLUSH_ICACHE(start_flush, code_here-start_flush);  
       start_flush=code_here;  
     }  
     *start = (Cell)prim;      *start = (Cell)prim;
     return;      return;
   }    }
Line 716  void compile_prim1(Cell *start) Line 751  void compile_prim1(Cell *start)
 #ifdef ALIGN_CODE  #ifdef ALIGN_CODE
   ALIGN_CODE;    ALIGN_CODE;
 #endif  #endif
   memcpy(code_here, (Address)prim, priminfos[i].length);    assert(prim==priminfos[i].start);
   code_here += priminfos[i].length;    old_code_here = append_prim(i);
   last_jump = (priminfos[i].superend) ? 0 : (prim+priminfos[i].length);    last_jump = (priminfos[i].superend) ? 0 : i;
   if (last_jump == 0) {  
     FLUSH_ICACHE(start_flush, code_here-start_flush);  
     start_flush=code_here;  
   }  
   *start = (Cell)old_code_here;    *start = (Cell)old_code_here;
   return;    return;
 #else /* !defined(DOUBLY_INDIRECT), no code replication */  #else /* !defined(DOUBLY_INDIRECT), no code replication */

Removed from v.1.73  
changed lines
  Added in v.1.74


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>