File:  [gforth] / gforth / Attic / engine.c
Revision 1.13: download - view: text, annotated - select for diffs
Wed Aug 31 19:42:44 1994 UTC (29 years, 7 months ago) by pazsan
Branches: MAIN
CVS tags: HEAD
Added options to allow good register scheduling on i386
added blocks

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

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