Annotation of gforth/engine.c, revision 1.14

1.1       anton       1: /*
1.14    ! anton       2:   $Id: engine.c,v 1.13 1994/08/31 19:42:44 pazsan Exp $
1.1       anton       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>
1.2       pazsan     15: #include <time.h>
1.6       pazsan     16: #include <sys/time.h>
1.1       anton      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: 
1.14    ! anton      44: /* NEXT and NEXT1 are split into several parts to help scheduling,
        !            45:    unless CISC_NEXT is defined */
        !            46: #ifdef CISC_NEXT
        !            47: #define NEXT1_P1
        !            48: #define NEXT_P1
        !            49: #define DEF_CA
1.1       anton      50: #ifdef DIRECT_THREADED
1.14    ! anton      51: #define NEXT1_P2 ({goto *cfa;})
1.1       anton      52: #else
1.14    ! anton      53: #define NEXT1_P2 ({goto **cfa;})
        !            54: #endif /* DIRECT_THREADED */
        !            55: #define NEXT_P2 ({cfa = *ip++; NEXT1_P2;})
        !            56: #else /* CISC_NEXT */
        !            57: #ifdef DIRECT_THREADED
        !            58: #define NEXT1_P1
        !            59: #define NEXT1_P2 ({goto *cfa;})
        !            60: #define DEF_CA
        !            61: #else /* DIRECT_THREADED */
        !            62: #define NEXT1_P1 ({ca = *cfa;})
        !            63: #define NEXT1_P2 ({goto *ca;})
        !            64: #define DEF_CA Label ca;
        !            65: #endif /* DIRECT_THREADED */
        !            66: #define NEXT_P1 ({cfa=*ip++; NEXT1_P1;})
        !            67: #define NEXT_P2 NEXT1_P2
        !            68: #endif /* CISC_NEXT */
1.1       anton      69: 
1.14    ! anton      70: #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})
        !            71: #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
1.1       anton      72: 
                     73: #ifdef USE_TOS
                     74: #define IF_TOS(x) x
                     75: #else
                     76: #define IF_TOS(x)
                     77: #define TOS (sp[0])
                     78: #endif
                     79: 
                     80: #ifdef USE_FTOS
                     81: #define IF_FTOS(x) x
                     82: #else
                     83: #define IF_FTOS(x)
                     84: #define FTOS (fp[0])
                     85: #endif
                     86: 
                     87: int emitcounter;
                     88: #define NULLC '\0'
                     89: 
1.14    ! anton      90: char *cstr(Char *from, UCell size, int clear)
        !            91: /* if clear is true, scratch can be reused, otherwise we want more of
        !            92:    the same */
        !            93: {
        !            94:   static char *scratch=NULL;
        !            95:   static unsigned scratchsize=0;
        !            96:   static char *nextscratch;
        !            97:   char *oldnextscratch;
        !            98: 
        !            99:   if (clear)
        !           100:     nextscratch=scratch;
        !           101:   if (scratch==NULL) {
        !           102:     scratch=malloc(size+1);
        !           103:     nextscratch=scratch;
        !           104:     scratchsize=size;
        !           105:   }
        !           106:   else if (nextscratch+size>scratch+scratchsize) {
        !           107:     char *oldscratch=scratch;
        !           108:     scratch = realloc(scratch, (nextscratch-scratch)+size+1);
        !           109:     nextscratch=scratch+(nextscratch-oldscratch);
        !           110:     scratchsize=size;
        !           111:   }
        !           112:   memcpy(nextscratch,from,size);
        !           113:   nextscratch[size]='\0';
        !           114:   oldnextscratch = nextscratch;
        !           115:   nextscratch += size+1;
        !           116:   return oldnextscratch;
        !           117: }
1.13      pazsan    118: 
1.1       anton     119: #define NEWLINE        '\n'
                    120: 
1.13      pazsan    121: 
1.1       anton     122: static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};
1.6       pazsan    123: 
1.11      pazsan    124: static Address up0=NULL;
                    125: 
1.13      pazsan    126: #if defined(i386) && defined(FORCE_REG)
                    127: #  define REG(reg) __asm__(reg)
                    128: 
                    129: Label *engine(Xt *ip0, Cell *sp0, Cell *rp, Float *fp, Address lp)
                    130: {
                    131:    register Xt *ip REG("%esi")=ip0;
                    132:    register Cell *sp REG("%edi")=sp0;
                    133: 
                    134: #else
                    135: #  define REG(reg)
                    136: 
1.5       anton     137: Label *engine(Xt *ip, Cell *sp, Cell *rp, Float *fp, Address lp)
1.13      pazsan    138: {
                    139: #endif
1.1       anton     140: /* executes code at ip, if ip!=NULL
                    141:    returns array of machine code labels (for use in a loader), if ip==NULL
                    142: */
1.13      pazsan    143:   register Xt cfa
                    144: #ifdef i386
                    145: #  ifdef USE_TOS
                    146:    REG("%ecx")
                    147: #  else
                    148:    REG("%edx")
                    149: #  endif
                    150: #endif
                    151:    ;
1.11      pazsan    152:   Address up=up0;
1.1       anton     153:   static Label symbols[]= {
                    154:     &&docol,
                    155:     &&docon,
                    156:     &&dovar,
1.4       pazsan    157:     &&douser,
1.12      anton     158:     &&dodefer,
1.1       anton     159:     &&dodoes,
1.6       pazsan    160:     &&dodoes,  /* dummy for does handler address */
1.1       anton     161: #include "prim_labels.i"
                    162:   };
                    163:   IF_TOS(register Cell TOS;)
                    164:   IF_FTOS(Float FTOS;)
                    165: #ifdef CPU_DEP
                    166:   CPU_DEP;
                    167: #endif
                    168: 
                    169:   if (ip == NULL)
                    170:     return symbols;
1.10      anton     171: 
1.1       anton     172:   IF_TOS(TOS = sp[0]);
                    173:   IF_FTOS(FTOS = fp[0]);
                    174:   prep_terminal();
                    175:   NEXT;
                    176:   
                    177:  docol:
                    178: #ifdef DEBUG
1.6       pazsan    179:   printf("%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
1.1       anton     180: #endif
1.13      pazsan    181: #ifdef i386
1.1       anton     182:   /* this is the simple version */
                    183:   *--rp = (Cell)ip;
                    184:   ip = (Xt *)PFA1(cfa);
                    185:   NEXT;
                    186: #endif
                    187:   /* this one is important, so we help the compiler optimizing
                    188:      The following version may be better (for scheduling), but probably has
                    189:      problems with code fields employing calls and delay slots
                    190:   */
                    191:   {
1.4       pazsan    192:     DEF_CA
1.1       anton     193:     Xt *current_ip = (Xt *)PFA1(cfa);
                    194:     cfa = *current_ip;
                    195:     NEXT1_P1;
                    196:     *--rp = (Cell)ip;
                    197:     ip = current_ip+1;
1.3       pazsan    198:     NEXT1_P2;
1.1       anton     199:   }
                    200:   
                    201:  docon:
                    202: #ifdef DEBUG
1.6       pazsan    203:   printf("%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));
1.1       anton     204: #endif
                    205: #ifdef USE_TOS
                    206:   *sp-- = TOS;
                    207:   TOS = *(Cell *)PFA1(cfa);
                    208: #else
                    209:   *--sp = *(Cell *)PFA1(cfa);
                    210: #endif
                    211:   NEXT;
                    212:   
                    213:  dovar:
                    214: #ifdef DEBUG
1.6       pazsan    215:   printf("%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
1.1       anton     216: #endif
                    217: #ifdef USE_TOS
                    218:   *sp-- = TOS;
                    219:   TOS = (Cell)PFA1(cfa);
                    220: #else
                    221:   *--sp = (Cell)PFA1(cfa);
                    222: #endif
                    223:   NEXT;
                    224:   
                    225:   /* !! user? */
                    226:   
1.4       pazsan    227:  douser:
                    228: #ifdef DEBUG
1.6       pazsan    229:   printf("%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
1.4       pazsan    230: #endif
                    231: #ifdef USE_TOS
                    232:   *sp-- = TOS;
1.5       anton     233:   TOS = (Cell)(up+*(Cell*)PFA1(cfa));
1.4       pazsan    234: #else
1.5       anton     235:   *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
1.4       pazsan    236: #endif
                    237:   NEXT;
                    238:   
1.12      anton     239:  dodefer:
                    240: #ifdef DEBUG
                    241:   printf("%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
                    242: #endif
                    243:   cfa = *(Xt *)PFA1(cfa);
                    244:   NEXT1;
                    245: 
1.1       anton     246:  dodoes:
                    247:   /* this assumes the following structure:
                    248:      defining-word:
                    249:      
                    250:      ...
                    251:      DOES>
                    252:      (possible padding)
                    253:      possibly handler: jmp dodoes
                    254:      (possible branch delay slot(s))
                    255:      Forth code after DOES>
                    256:      
                    257:      defined word:
                    258:      
                    259:      cfa: address of or jump to handler OR
                    260:           address of or jump to dodoes, address of DOES-code
                    261:      pfa:
                    262:      
                    263:      */
                    264: #ifdef DEBUG
1.6       pazsan    265:   printf("%08x/%08x: does: %08x\n",(Cell)ip,(Cell)cfa,*(Cell)PFA(cfa));
                    266:   fflush(stdout);
1.1       anton     267: #endif
                    268:   *--rp = (Cell)ip;
                    269:   /* PFA1 might collide with DOES_CODE1 here, so we use PFA */
1.13      pazsan    270:   ip = DOES_CODE1(cfa);
1.1       anton     271: #ifdef USE_TOS
                    272:   *sp-- = TOS;
                    273:   TOS = (Cell)PFA(cfa);
                    274: #else
                    275:   *--sp = (Cell)PFA(cfa);
                    276: #endif
                    277:   NEXT;
                    278:   
                    279: #include "primitives.i"
                    280: }

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