File:  [gforth] / gforth / Attic / engine.c
Revision 1.20: download - view: text, annotated - select for diffs
Mon Dec 12 17:10:35 1994 UTC (28 years, 9 months ago) by anton
Branches: MAIN
CVS tags: HEAD
Reorganized configuration: configure is now created by autoconf from
configure.in; I still left it in the CVS repository because not
everyone has autoconf. decstation.h renamed to mips.h and apollo68k to
m68k. Added general 32bit.h description, which the other machine
descriptions use. Created/copied replacement files install-sh memcmp.c
memmove.c select.c (carved out from ecvt.c) strtol.c
strtoul.c. Bytesex is now handled by configure.

Deciding the threading method is now done in machine.h, this should
also be done for USE_TOS and USE_FTOS.

    1: /*
    2:   Copyright 1992 by the ANSI figForth Development Group
    3: */
    4: 
    5: #include <ctype.h>
    6: #include <stdio.h>
    7: #include <string.h>
    8: #include <math.h>
    9: #include <sys/types.h>
   10: #include <sys/stat.h>
   11: #include <fcntl.h>
   12: #include <assert.h>
   13: #include <stdlib.h>
   14: #include <time.h>
   15: #include <sys/time.h>
   16: #include "forth.h"
   17: #include "io.h"
   18: 
   19: #ifndef SEEK_SET
   20: /* should be defined in stdio.h, but some systems don't have it */
   21: #define SEEK_SET 0
   22: #endif
   23: 
   24: typedef union {
   25:   struct {
   26: #ifdef WORDS_BIGENDIAN
   27:     Cell high;
   28:     Cell low;
   29: #else
   30:     Cell low;
   31:     Cell high;
   32: #endif;
   33:   } cells;
   34:   DCell dcell;
   35: } Double_Store;
   36: 
   37: typedef struct F83Name {
   38:   struct F83Name	*next;  /* the link field for old hands */
   39:   char			countetc;
   40:   Char			name[0];
   41: } F83Name;
   42: 
   43: /* are macros for setting necessary? */
   44: #define F83NAME_COUNT(np)	((np)->countetc & 0x1f)
   45: #define F83NAME_SMUDGE(np)	(((np)->countetc & 0x40) != 0)
   46: #define F83NAME_IMMEDIATE(np)	(((np)->countetc & 0x20) != 0)
   47: 
   48: /* NEXT and NEXT1 are split into several parts to help scheduling,
   49:    unless CISC_NEXT is defined */
   50: #ifdef CISC_NEXT
   51: #define NEXT1_P1
   52: #define NEXT_P1
   53: #define DEF_CA
   54: #ifdef DIRECT_THREADED
   55: #define NEXT1_P2 ({goto *cfa;})
   56: #else
   57: #define NEXT1_P2 ({goto **cfa;})
   58: #endif /* DIRECT_THREADED */
   59: #define NEXT_P2 ({cfa = *ip++; NEXT1_P2;})
   60: #else /* CISC_NEXT */
   61: #ifdef DIRECT_THREADED
   62: #define NEXT1_P1
   63: #define NEXT1_P2 ({goto *cfa;})
   64: #define DEF_CA
   65: #else /* DIRECT_THREADED */
   66: #define NEXT1_P1 ({ca = *cfa;})
   67: #define NEXT1_P2 ({goto *ca;})
   68: #define DEF_CA	Label ca;
   69: #endif /* DIRECT_THREADED */
   70: #define NEXT_P1 ({cfa=*ip++; NEXT1_P1;})
   71: #define NEXT_P2 NEXT1_P2
   72: #endif /* CISC_NEXT */
   73: 
   74: #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})
   75: #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
   76: 
   77: #ifdef USE_TOS
   78: #define IF_TOS(x) x
   79: #else
   80: #define IF_TOS(x)
   81: #define TOS (sp[0])
   82: #endif
   83: 
   84: #ifdef USE_FTOS
   85: #define IF_FTOS(x) x
   86: #else
   87: #define IF_FTOS(x)
   88: #define FTOS (fp[0])
   89: #endif
   90: 
   91: int emitcounter;
   92: #define NULLC '\0'
   93: 
   94: char *cstr(Char *from, UCell size, int clear)
   95: /* if clear is true, scratch can be reused, otherwise we want more of
   96:    the same */
   97: {
   98:   static char *scratch=NULL;
   99:   static unsigned scratchsize=0;
  100:   static char *nextscratch;
  101:   char *oldnextscratch;
  102: 
  103:   if (clear)
  104:     nextscratch=scratch;
  105:   if (scratch==NULL) {
  106:     scratch=malloc(size+1);
  107:     nextscratch=scratch;
  108:     scratchsize=size;
  109:   }
  110:   else if (nextscratch+size>scratch+scratchsize) {
  111:     char *oldscratch=scratch;
  112:     scratch = realloc(scratch, (nextscratch-scratch)+size+1);
  113:     nextscratch=scratch+(nextscratch-oldscratch);
  114:     scratchsize=size;
  115:   }
  116:   memcpy(nextscratch,from,size);
  117:   nextscratch[size]='\0';
  118:   oldnextscratch = nextscratch;
  119:   nextscratch += size+1;
  120:   return oldnextscratch;
  121: }
  122: 
  123: #define NEWLINE	'\n'
  124: 
  125: 
  126: static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};
  127: 
  128: static Address up0=NULL;
  129: 
  130: /* if machine.h has not defined explicit registers, define them as implicit */
  131: #ifndef IPREG
  132: #define IPREG
  133: #endif
  134: #ifndef SPREG
  135: #define SPREG
  136: #endif
  137: #ifndef RPREG
  138: #define RPREG
  139: #endif
  140: #ifndef FPREG
  141: #define FPREG
  142: #endif
  143: #ifndef LPREG
  144: #define LPREG
  145: #endif
  146: #ifndef CFAREG
  147: #define CFAREG
  148: #endif
  149: #ifndef UPREG
  150: #define UPREG
  151: #endif
  152: #ifndef TOSREG
  153: #define TOSREG
  154: #endif
  155: #ifndef FTOSREG
  156: #define FTOSREG
  157: #endif
  158: 
  159: Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0)
  160: /* executes code at ip, if ip!=NULL
  161:    returns array of machine code labels (for use in a loader), if ip==NULL
  162: */
  163: {
  164:   register Xt *ip IPREG = ip0;
  165:   register Cell *sp SPREG = sp0;
  166:   register Cell *rp RPREG = rp0;
  167:   register Float *fp FPREG = fp0;
  168:   register Address lp LPREG = lp0;
  169:   register Xt cfa CFAREG;
  170:   register Address up UPREG = up0;
  171:   IF_TOS(register Cell TOS TOSREG;)
  172:   IF_FTOS(register Float FTOS FTOSREG;)
  173:   static Label symbols[]= {
  174:     &&docol,
  175:     &&docon,
  176:     &&dovar,
  177:     &&douser,
  178:     &&dodefer,
  179:     &&dodoes,
  180:     &&dodoes,  /* dummy for does handler address */
  181: #include "prim_labels.i"
  182:   };
  183: #ifdef CPU_DEP
  184:   CPU_DEP;
  185: #endif
  186: 
  187: #ifdef DEBUG
  188:   fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n",
  189:           (unsigned)ip,(unsigned)sp,(unsigned)rp,
  190: 	  (unsigned)fp,(unsigned)lp,(unsigned)up);
  191: #endif
  192: 
  193:   if (ip == NULL)
  194:     return symbols;
  195: 
  196:   IF_TOS(TOS = sp[0]);
  197:   IF_FTOS(FTOS = fp[0]);
  198:   prep_terminal();
  199:   NEXT;
  200:   
  201:  docol:
  202: #ifdef DEBUG
  203:   fprintf(stderr,"%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
  204: #endif
  205: #ifdef CISC_NEXT
  206:   /* this is the simple version */
  207:   *--rp = (Cell)ip;
  208:   ip = (Xt *)PFA1(cfa);
  209:   NEXT;
  210: #else
  211:   /* this one is important, so we help the compiler optimizing
  212:      The following version may be better (for scheduling), but probably has
  213:      problems with code fields employing calls and delay slots
  214:   */
  215:   {
  216:     DEF_CA
  217:     Xt *current_ip = (Xt *)PFA1(cfa);
  218:     cfa = *current_ip;
  219:     NEXT1_P1;
  220:     *--rp = (Cell)ip;
  221:     ip = current_ip+1;
  222:     NEXT1_P2;
  223:   }
  224: #endif
  225:   
  226:  docon:
  227: #ifdef DEBUG
  228:   fprintf(stderr,"%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));
  229: #endif
  230: #ifdef USE_TOS
  231:   *sp-- = TOS;
  232:   TOS = *(Cell *)PFA1(cfa);
  233: #else
  234:   *--sp = *(Cell *)PFA1(cfa);
  235: #endif
  236:   NEXT;
  237:   
  238:  dovar:
  239: #ifdef DEBUG
  240:   fprintf(stderr,"%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
  241: #endif
  242: #ifdef USE_TOS
  243:   *sp-- = TOS;
  244:   TOS = (Cell)PFA1(cfa);
  245: #else
  246:   *--sp = (Cell)PFA1(cfa);
  247: #endif
  248:   NEXT;
  249:   
  250:   /* !! user? */
  251:   
  252:  douser:
  253: #ifdef DEBUG
  254:   fprintf(stderr,"%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
  255: #endif
  256: #ifdef USE_TOS
  257:   *sp-- = TOS;
  258:   TOS = (Cell)(up+*(Cell*)PFA1(cfa));
  259: #else
  260:   *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
  261: #endif
  262:   NEXT;
  263:   
  264:  dodefer:
  265: #ifdef DEBUG
  266:   fprintf(stderr,"%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
  267: #endif
  268:   cfa = *(Xt *)PFA1(cfa);
  269:   NEXT1;
  270: 
  271:  dodoes:
  272:   /* this assumes the following structure:
  273:      defining-word:
  274:      
  275:      ...
  276:      DOES>
  277:      (possible padding)
  278:      possibly handler: jmp dodoes
  279:      (possible branch delay slot(s))
  280:      Forth code after DOES>
  281:      
  282:      defined word:
  283:      
  284:      cfa: address of or jump to handler OR
  285:           address of or jump to dodoes, address of DOES-code
  286:      pfa:
  287:      
  288:      */
  289: #ifdef DEBUG
  290:   fprintf(stderr,"%08x/%08x: does: %08x\n",(Cell)ip,(Cell)PFA(cfa),(Cell)DOES_CODE1(cfa));
  291:   fflush(stderr);
  292: #endif
  293:   *--rp = (Cell)ip;
  294:   /* PFA1 might collide with DOES_CODE1 here, so we use PFA */
  295:   ip = DOES_CODE1(cfa);
  296: #ifdef USE_TOS
  297:   *sp-- = TOS;
  298:   TOS = (Cell)PFA(cfa);
  299: #else
  300:   *--sp = (Cell)PFA(cfa);
  301: #endif
  302:   NEXT;
  303: 
  304: #include "primitives.i"
  305: }

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