Diff for /gforth/Attic/engine.c between versions 1.6 and 1.24

version 1.6, 1994/05/18 17:29:52 version 1.24, 1995/02/23 20:17:18
Line 1 Line 1
 /*  /*
   $Id$  
   Copyright 1992 by the ANSI figForth Development Group    Copyright 1992 by the ANSI figForth Development Group
 */  */
   
Line 14 Line 13
 #include <stdlib.h>  #include <stdlib.h>
 #include <time.h>  #include <time.h>
 #include <sys/time.h>  #include <sys/time.h>
   #include <unistd.h>
 #include "forth.h"  #include "forth.h"
 #include "io.h"  #include "io.h"
   
 #ifndef unlink  #ifndef SEEK_SET
         extern unlink(char *);  /* should be defined in stdio.h, but some systems don't have it */
 #endif  #define SEEK_SET 0
 #ifndef ftruncate  
         extern ftruncate(int, int);  
 #endif  #endif
   
 typedef union {  typedef union {
   struct {    struct {
 #ifdef BIG_ENDIAN  #ifdef WORDS_BIGENDIAN
     Cell high;      Cell high;
     Cell low;      Cell low;
 #else  #else
Line 48  typedef struct F83Name { Line 46  typedef struct F83Name {
 #define F83NAME_SMUDGE(np)      (((np)->countetc & 0x40) != 0)  #define F83NAME_SMUDGE(np)      (((np)->countetc & 0x40) != 0)
 #define F83NAME_IMMEDIATE(np)   (((np)->countetc & 0x20) != 0)  #define F83NAME_IMMEDIATE(np)   (((np)->countetc & 0x20) != 0)
   
 /* NEXT and NEXT1 are split into several parts to help scheduling */  /* !!someone should organize this ifdef chaos */
   #if defined(LONG_LATENCY)
   #if defined(AUTO_INCREMENT)
   #define NEXT_P0         (cfa=*ip++)
   #define IP              (ip-1)
   #else /* AUTO_INCREMENT */
   #define NEXT_P0         (cfa=*ip)
   #define IP              ip
   #endif /* AUTO_INCREMENT */
   #define NEXT_INST       (cfa)
   #define INC_IP(const_inc)       ({cfa=IP[const_inc]; ip+=(const_inc);})
   #else /* LONG_LATENCY */
   /* NEXT and NEXT1 are split into several parts to help scheduling,
      unless CISC_NEXT is defined */
   #define NEXT_P0
   /* in order for execute to work correctly, NEXT_P0 (or other early
      fetches) should not update the ip (or should we put
      compensation-code into execute? */
   #define NEXT_INST       (*ip)
   /* the next instruction (or what is in its place, e.g., an immediate
      argument */
   #define INC_IP(const_inc)       (ip+=(const_inc))
   /* increment the ip by const_inc and perform NEXT_P0 (or prefetching) again */
   #define IP              ip
   /* the pointer to the next instruction (i.e., NEXT_INST could be
      defined as *IP) */
   #endif /* LONG_LATENCY */
   
   #if defined(CISC_NEXT) && !defined(LONG_LATENCY)
   #define NEXT1_P1
   #define NEXT_P1
   #define DEF_CA
 #ifdef DIRECT_THREADED  #ifdef DIRECT_THREADED
 #       define NEXT1_P1   #define NEXT1_P2 ({goto *cfa;})
 #       define NEXT1_P2 ({goto *cfa;})  #else
 #       define DEF_CA  #define NEXT1_P2 ({goto **cfa;})
 #else  #endif /* DIRECT_THREADED */
 #       define NEXT1_P1 ({ca = *cfa;})  #define NEXT_P2 ({cfa = *ip++; NEXT1_P2;})
 #       define NEXT1_P2 ({goto *ca;})  #else /* defined(CISC_NEXT) && !defined(LONG_LATENCY) */
 #       define DEF_CA   Label ca;  #ifdef DIRECT_THREADED
 #endif  #define NEXT1_P1
 #define NEXT_P1 ({cfa = *ip++; NEXT1_P1;})  #define NEXT1_P2 ({goto *cfa;})
   #define DEF_CA
   #else /* DIRECT_THREADED */
   #define NEXT1_P1 ({ca = *cfa;})
   #define NEXT1_P2 ({goto *ca;})
   #define DEF_CA  Label ca;
   #endif /* DIRECT_THREADED */
   #if defined(LONG_LATENCY)
   #if defined(AUTO_INCREMENT)
   #define NEXT_P1 NEXT1_P1
   #else /* AUTO_INCREMENT */
   #define NEXT_P1 ({ip++; NEXT1_P1;})
   #endif /* AUTO_INCREMENT */
   #else /* LONG_LATENCY */
   #define NEXT_P1 ({cfa=*ip++; NEXT1_P1;})
   #endif /* LONG_LATENCY */
   #define NEXT_P2 NEXT1_P2
   #endif /* defined(CISC_NEXT) && !defined(LONG_LATENCY) */
   
 #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})  #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})
 #define NEXT ({DEF_CA NEXT_P1; NEXT1_P2;})  #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
   
 #ifdef USE_TOS  #ifdef USE_TOS
 #define IF_TOS(x) x  #define IF_TOS(x) x
Line 80  typedef struct F83Name { Line 126  typedef struct F83Name {
 int emitcounter;  int emitcounter;
 #define NULLC '\0'  #define NULLC '\0'
   
 #define cstr(to,from,size)\  char *cstr(Char *from, UCell size, int clear)
         {       memcpy(to,from,size);\  /* if clear is true, scratch can be reused, otherwise we want more of
                 to[size]=NULLC;}     the same */
   {
     static char *scratch=NULL;
     static unsigned scratchsize=0;
     static char *nextscratch;
     char *oldnextscratch;
   
     if (clear)
       nextscratch=scratch;
     if (scratch==NULL) {
       scratch=malloc(size+1);
       nextscratch=scratch;
       scratchsize=size;
     }
     else if (nextscratch+size>scratch+scratchsize) {
       char *oldscratch=scratch;
       scratch = realloc(scratch, (nextscratch-scratch)+size+1);
       nextscratch=scratch+(nextscratch-oldscratch);
       scratchsize=size;
     }
     memcpy(nextscratch,from,size);
     nextscratch[size]='\0';
     oldnextscratch = nextscratch;
     nextscratch += size+1;
     return oldnextscratch;
   }
   
 #define NEWLINE '\n'  #define NEWLINE '\n'
   
   #ifndef HAVE_RINT
   #define rint(x) floor((x)+0.5)
   #endif
   
 static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};  static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};
   
 #if ~defined(select) && defined(DOS)  static Address up0=NULL;
 /* select replacement for DOS computers for ms only */  
 void select(int n, int a, int b, int c, struct timeval * timeout)  /* if machine.h has not defined explicit registers, define them as implicit */
 {  #ifndef IPREG
    struct timeval time1;  #define IPREG
    struct timeval time2;  #endif
    struct timezone zone1;  #ifndef SPREG
   #define SPREG
    gettimeofday(&time1,&zone1);  #endif
    time1.tv_sec += timeout->tv_sec;  #ifndef RPREG
    time1.tv_usec += timeout->tv_usec;  #define RPREG
    while(time1.tv_usec >= 1000000)  #endif
      {  #ifndef FPREG
         time1.tv_usec -= 1000000;  #define FPREG
         time1.tv_sec++;  #endif
      }  #ifndef LPREG
    do  #define LPREG
      {  #endif
         gettimeofday(&time2,&zone1);  #ifndef CFAREG
      }  #define CFAREG
    while(time2.tv_usec < time1.tv_usec || time2.tv_sec < time1.tv_sec);  #endif
 }  #ifndef UPREG
   #define UPREG
   #endif
   #ifndef TOSREG
   #define TOSREG
   #endif
   #ifndef FTOSREG
   #define FTOSREG
 #endif  #endif
   
 Label *engine(Xt *ip, Cell *sp, Cell *rp, Float *fp, Address lp)  Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0)
 /* executes code at ip, if ip!=NULL  /* executes code at ip, if ip!=NULL
    returns array of machine code labels (for use in a loader), if ip==NULL     returns array of machine code labels (for use in a loader), if ip==NULL
 */  */
 {  {
   Xt cfa;    register Xt *ip IPREG = ip0;
   Address up=NULL;    register Cell *sp SPREG = sp0;
     register Cell *rp RPREG = rp0;
     register Float *fp FPREG = fp0;
     register Address lp LPREG = lp0;
     register Xt cfa CFAREG;
     register Address up UPREG = up0;
     IF_TOS(register Cell TOS TOSREG;)
     IF_FTOS(register Float FTOS FTOSREG;)
   static Label symbols[]= {    static Label symbols[]= {
     &&docol,      &&docol,
     &&docon,      &&docon,
     &&dovar,      &&dovar,
     &&douser,      &&douser,
       &&dodefer,
       &&dostruc,
     &&dodoes,      &&dodoes,
     &&dodoes,  /* dummy for does handler address */      &&dodoes,  /* dummy for does handler address */
 #include "prim_labels.i"  #include "prim_labels.i"
   };    };
   IF_TOS(register Cell TOS;)  
   IF_FTOS(Float FTOS;)  
 #ifdef CPU_DEP  #ifdef CPU_DEP
   CPU_DEP;    CPU_DEP;
 #endif  #endif
   
   #ifdef DEBUG
     fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n",
             (unsigned)ip,(unsigned)sp,(unsigned)rp,
             (unsigned)fp,(unsigned)lp,(unsigned)up);
   #endif
   
   if (ip == NULL)    if (ip == NULL)
     return symbols;      return symbols;
     
   IF_TOS(TOS = sp[0]);    IF_TOS(TOS = sp[0]);
   IF_FTOS(FTOS = fp[0]);    IF_FTOS(FTOS = fp[0]);
   prep_terminal();    prep_terminal();
     NEXT_P0;
   NEXT;    NEXT;
       
  docol:   docol:
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef undefined  #ifdef CISC_NEXT
   /* this is the simple version */    /* this is the simple version */
   *--rp = (Cell)ip;    *--rp = (Cell)ip;
   ip = (Xt *)PFA1(cfa);    ip = (Xt *)PFA1(cfa);
     NEXT_P0;
   NEXT;    NEXT;
 #endif  #else
   /* this one is important, so we help the compiler optimizing    /* this one is important, so we help the compiler optimizing
      The following version may be better (for scheduling), but probably has       The following version may be better (for scheduling), but probably has
      problems with code fields employing calls and delay slots       problems with code fields employing calls and delay slots
Line 164  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 262  Label *engine(Xt *ip, Cell *sp, Cell *rp
     ip = current_ip+1;      ip = current_ip+1;
     NEXT1_P2;      NEXT1_P2;
   }    }
     #endif
   
  docon:   docon:
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));    fprintf(stderr,"%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 175  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 274  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = *(Cell *)PFA1(cfa);    *--sp = *(Cell *)PFA1(cfa);
 #endif  #endif
     NEXT_P0;
   NEXT;    NEXT;
       
  dovar:   dovar:
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 187  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 287  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = (Cell)PFA1(cfa);    *--sp = (Cell)PFA1(cfa);
 #endif  #endif
     NEXT_P0;
   NEXT;    NEXT;
       
   /* !! user? */  
     
  douser:   douser:
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 201  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 300  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = (Cell)(up+*(Cell*)PFA1(cfa));    *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
 #endif  #endif
     NEXT_P0;
   NEXT;    NEXT;
       
    dodefer:
   #ifdef DEBUG
     fprintf(stderr,"%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
   #endif
     cfa = *(Xt *)PFA1(cfa);
     NEXT1;
   
    dostruc:
   #ifdef DEBUG
     fprintf(stderr,"%08x: struc: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
   #endif
     TOS += *(Cell*)PFA1(cfa); 
     NEXT_P0;
     NEXT;
   
  dodoes:   dodoes:
   /* this assumes the following structure:    /* this assumes the following structure:
      defining-word:       defining-word:
Line 222  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 337  Label *engine(Xt *ip, Cell *sp, Cell *rp
             
      */       */
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x/%08x: does: %08x\n",(Cell)ip,(Cell)cfa,*(Cell)PFA(cfa));    fprintf(stderr,"%08x/%08x: does: %08x\n",(Cell)ip,(Cell)PFA(cfa),(Cell)DOES_CODE1(cfa));
   fflush(stdout);    fflush(stderr);
 #endif  #endif
   *--rp = (Cell)ip;    *--rp = (Cell)ip;
   /* PFA1 might collide with DOES_CODE1 here, so we use PFA */    /* PFA1 might collide with DOES_CODE1 here, so we use PFA */
     ip = DOES_CODE1(cfa);
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
   TOS = (Cell)PFA(cfa);    TOS = (Cell)PFA(cfa);
 #else  #else
   *--sp = (Cell)PFA(cfa);    *--sp = (Cell)PFA(cfa);
 #endif  #endif
   ip = DOES_CODE1(cfa);    NEXT_P0;
   NEXT;    NEXT;
     
 #include "primitives.i"  #include "primitives.i"
 }  }

Removed from v.1.6  
changed lines
  Added in v.1.24


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