File:  [gforth] / gforth / engine / forth.h
Revision 1.27: download - view: text, annotated - select for diffs
Sun Feb 10 14:02:25 2002 UTC (22 years, 2 months ago) by anton
Branches: MAIN
CVS tags: HEAD
lit@ and lit+ are now defined as superinstructions
compile lit @ and lit + instead of lit@ and lit+
extended prims2x to support superinstructions with non-C-names
  (syntax: forth-name /c-name = ...)
support profiling of interpreters with superinstructions
  (with simple instructions in the output).
profile output with prefixes only (enable by editing profile.c).
optional reporting of static superinstruction lengths (compared to
  dynamic superinstructions); enable by compiling with -DPRINT_SUPER_LENGTHS

    1: /* common header file
    2: 
    3:   Copyright (C) 1995,1996,1997,1998,2000 Free Software Foundation, Inc.
    4: 
    5:   This file is part of Gforth.
    6: 
    7:   Gforth is free software; you can redistribute it and/or
    8:   modify it under the terms of the GNU General Public License
    9:   as published by the Free Software Foundation; either version 2
   10:   of the License, or (at your option) any later version.
   11: 
   12:   This program is distributed in the hope that it will be useful,
   13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:   GNU General Public License for more details.
   16: 
   17:   You should have received a copy of the GNU General Public License
   18:   along with this program; if not, write to the Free Software
   19:   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   20: */
   21: 
   22: #define _GNU_SOURCE
   23: 
   24: #include "config.h"
   25: #include <stdio.h>
   26: 
   27: #if defined(DOUBLY_INDIRECT)
   28: #  undef DIRECT_THREADED
   29: #  undef INDIRECT_THREADED
   30: #  define INDIRECT_THREADED
   31: #endif
   32: 
   33: #if defined(GFORTH_DEBUGGING)
   34: #  undef USE_TOS
   35: #  undef USE_FTOS
   36: #  define USE_NO_TOS
   37: #  define USE_NO_FTOS
   38: #endif
   39: 
   40: #include <limits.h>
   41: 
   42: #if defined(NeXT)
   43: #  include <libc.h>
   44: #endif /* NeXT */
   45: 
   46: /* symbol indexed constants */
   47: 
   48: #define DOCOL	0
   49: #define DOCON	1
   50: #define DOVAR	2
   51: #define DOUSER	3
   52: #define DODEFER	4
   53: #define DOFIELD	5
   54: #define DODOES	6
   55: #define DOESJUMP	7
   56: 
   57: /* the size of the DOESJUMP, which resides between DOES> and the does-code */
   58: #define DOES_HANDLER_SIZE	(2*sizeof(Cell))
   59: 
   60: #include "machine.h"
   61: 
   62: /* Forth data types */
   63: /* Cell and UCell must be the same size as a pointer */
   64: #define CELL_BITS	(sizeof(Cell) * CHAR_BIT)
   65: #define FLAG(b) (-(b))
   66: #define FILEIO(error)	(FLAG(error) & -37)
   67: #define FILEEXIST(error)	(FLAG(error) & -38)
   68: 
   69: #define F_TRUE (FLAG(0==0))
   70: #define F_FALSE (FLAG(0!=0))
   71: 
   72: #ifdef BUGGY_LONG_LONG
   73: typedef struct {
   74:   Cell hi;
   75:   UCell lo;
   76: } DCell;
   77: 
   78: typedef struct {
   79:   UCell hi;
   80:   UCell lo;
   81: } UDCell;
   82: 
   83: #define LONG2UD(l)	({UDCell _ud; _ud.hi=0; _ud.lo=(Cell)(l); _ud;})
   84: #define UD2LONG(ud)	((long)(ud.lo))
   85: #define DZERO		((DCell){0,0})
   86: 
   87: #else /* ! defined(BUGGY_LONG_LONG) */
   88: 
   89: /* DCell and UDCell must be twice as large as Cell */
   90: typedef DOUBLE_CELL_TYPE DCell;
   91: typedef unsigned DOUBLE_CELL_TYPE UDCell;
   92: 
   93: #define LONG2UD(l)	((UDCell)(l))
   94: #define UD2LONG(ud)	((long)(ud))
   95: #define DZERO		((DCell)0)
   96: 
   97: #endif /* ! defined(BUGGY_LONG_LONG) */
   98: 
   99: typedef union {
  100:   struct {
  101: #if defined(WORDS_BIGENDIAN)||defined(BUGGY_LONG_LONG)
  102:     Cell high;
  103:     UCell low;
  104: #else
  105:     UCell low;
  106:     Cell high;
  107: #endif
  108:   } cells;
  109:   DCell d;
  110:   UDCell ud;
  111: } Double_Store;
  112: 
  113: #define FETCH_DCELL_T(d_,lo,hi,t_)	({ \
  114: 				     Double_Store _d; \
  115: 				     _d.cells.low = (lo); \
  116: 				     _d.cells.high = (hi); \
  117: 				     (d_) = _d.t_; \
  118: 				 })
  119: 
  120: #define STORE_DCELL_T(d_,lo,hi,t_)	({ \
  121: 				     Double_Store _d; \
  122: 				     _d.t_ = (d_); \
  123: 				     (lo) = _d.cells.low; \
  124: 				     (hi) = _d.cells.high; \
  125: 				 })
  126: 
  127: #define vm_twoCell2d(d_,lo,hi)  FETCH_DCELL_T(d_,lo,hi,d)
  128: #define vm_twoCell2ud(d_,lo,hi) FETCH_DCELL_T(d_,lo,hi,ud)
  129: 
  130: #define vm_d2twoCell(d_,lo,hi)  STORE_DCELL_T(d_,lo,hi,d)
  131: #define vm_ud2twoCell(d_,lo,hi) STORE_DCELL_T(d_,lo,hi,ud)
  132: 
  133: typedef Label *Xt;
  134: 
  135: /* PFA gives the parameter field address corresponding to a cfa */
  136: #define PFA(cfa)	(((Cell *)cfa)+2)
  137: /* PFA1 is a special version for use just after a NEXT1 */
  138: #define PFA1(cfa)	PFA(cfa)
  139: /* CODE_ADDRESS is the address of the code jumped to through the code field */
  140: #define CODE_ADDRESS(cfa)	(*(Xt)(cfa))
  141: 
  142: /* DOES_CODE is the Forth code does jumps to */
  143: #if !defined(DOUBLY_INDIRECT)
  144: #  define DOES_CA (symbols[DODOES])
  145: #else /* defined(DOUBLY_INDIRECT) */
  146: #  define DOES_CA ((Label)&xts[DODOES])
  147: #endif /* defined(DOUBLY_INDIRECT) */
  148: 
  149: 
  150: 
  151: #define DOES_CODE(cfa)	({Xt _cfa=(Xt)(cfa); \
  152: 			  (Xt *)(_cfa[0]==DOES_CA ? _cfa[1] : NULL);})
  153: #define DOES_CODE1(cfa)	((Xt *)(cfa[1]))
  154: /* MAKE_CF creates an appropriate code field at the cfa;
  155:    ca is the code address */
  156: #define MAKE_CF(cfa,ca) ((*(Label *)(cfa)) = ((Label)ca))
  157: /* make a code field for a defining-word-defined word */
  158: #define MAKE_DOES_CF(cfa,does_code)  ({MAKE_CF(cfa,DOES_CA);	\
  159: 				       ((Cell *)cfa)[1] = (Cell)(does_code);})
  160: /* the does handler resides between DOES> and the following Forth code */
  161: /* not needed in indirect threaded code */
  162: #if defined(DOUBLY_INDIRECT)
  163: #define MAKE_DOES_HANDLER(addr)	MAKE_CF(addr, ((Label)&symbols[DOESJUMP]))
  164: #else /* !defined(DOUBLY_INDIRECT) */
  165: #define MAKE_DOES_HANDLER(addr)	0
  166: #endif /* !defined(DOUBLY_INDIRECT) */
  167: 
  168: #ifdef DEBUG
  169: #	define	NAME(string)	fprintf(stderr,"%08lx: "string"\n",(Cell)ip);
  170: #else
  171: #	define	NAME(string)
  172: #endif
  173: 
  174: #define CF(const)	(-const-2)
  175: 
  176: #define CF_NIL	-1
  177: 
  178: #ifndef FLUSH_ICACHE
  179: #warning flush-icache probably will not work (see manual)
  180: #	define FLUSH_ICACHE(addr,size)
  181: #endif
  182: 
  183: #ifdef USE_TOS
  184: #define IF_spTOS(x) x
  185: #else
  186: #define IF_spTOS(x)
  187: #define spTOS (sp[0])
  188: #endif
  189: 
  190: #ifdef USE_FTOS
  191: #define IF_fpTOS(x) x
  192: #else
  193: #define IF_fpTOS(x)
  194: #define fpTOS (fp[0])
  195: #endif
  196: 
  197: #define IF_rpTOS(x)
  198: #define rpTOS (rp[0])
  199: 
  200: typedef struct {
  201:   Address base;		/* base address of image (0 if relocatable) */
  202:   UCell checksum;	/* checksum of ca's to protect against some
  203: 			   incompatible	binary/executable combinations
  204: 			   (0 if relocatable) */
  205:   UCell image_size;	/* all sizes in bytes */
  206:   UCell dict_size;
  207:   UCell data_stack_size;
  208:   UCell fp_stack_size;
  209:   UCell return_stack_size;
  210:   UCell locals_stack_size;
  211:   Xt *boot_entry;	/* initial ip for booting (in BOOT) */
  212:   Xt *throw_entry;	/* ip after signal (in THROW) */
  213:   Cell unused1;		/* possibly tib stack size */
  214:   Label *xt_base;         /* base of DOUBLE_INDIRECT xts[], for comp-i.fs */
  215:   Address data_stack_base; /* this and the following fields are initialized by the loader */
  216:   Address fp_stack_base;
  217:   Address return_stack_base;
  218:   Address locals_stack_base;
  219: } ImageHeader;
  220: /* the image-header is created in main.fs */
  221: 
  222: Label *engine(Xt *ip, Cell *sp, Cell *rp, Float *fp, Address lp);
  223: Address my_alloc(Cell size);
  224: char *tilde_cstr(Char *from, UCell size, int clear);
  225: 
  226: /* dblsub routines */
  227: DCell dnegate(DCell d1);
  228: UDCell ummul (UCell a, UCell b);
  229: DCell mmul (Cell a, Cell b);
  230: UDCell umdiv (UDCell u, UCell v);
  231: DCell smdiv (DCell num, Cell denom);
  232: DCell fmdiv (DCell num, Cell denom);
  233: 
  234: Cell memcasecmp(const Char *s1, const Char *s2, Cell n);
  235: 
  236: /* peephole routines */
  237: 
  238: Xt *primtable(Label symbols[], Cell size);
  239: Cell prepare_peephole_table(Xt xts[]);
  240: Xt peephole_opt(Xt xt1, Xt xt2, Cell peeptable);
  241: void vm_print_profile(FILE *file);
  242: void vm_count_block(Xt *ip);
  243: 
  244: /* dynamic superinstruction stuff */
  245: Label compile_prim(Label prim);
  246: 
  247: extern int offset_image;
  248: extern int die_on_signal;
  249: extern UCell pagesize;
  250: extern ImageHeader *gforth_header;
  251: extern Label *vm_prims;
  252: extern Label *xts;
  253: extern Cell npriminfos;
  254: 
  255: #ifdef GFORTH_DEBUGGING
  256: extern Xt *ip;
  257: extern Cell *rp;
  258: #endif
  259: 
  260: #ifdef PRINT_SUPER_LENGTHS
  261: Cell prim_length(Cell prim);
  262: void print_super_lengths();
  263: #endif
  264: 
  265: /* declare all the functions that are missing */
  266: #ifndef HAVE_ATANH
  267: extern double atanh(double r1);
  268: extern double asinh(double r1);
  269: extern double acosh(double r1);
  270: #endif
  271: #ifndef HAVE_ECVT
  272: /* extern char* ecvt(double x, int len, int* exp, int* sign);*/
  273: #endif
  274: #ifndef HAVE_MEMMOVE
  275: /* extern char *memmove(char *dest, const char *src, long n); */
  276: #endif
  277: #ifndef HAVE_POW10
  278: extern double pow10(double x);
  279: #endif
  280: #ifndef HAVE_STRERROR
  281: extern char *strerror(int err);
  282: #endif
  283: #ifndef HAVE_STRSIGNAL
  284: extern char *strsignal(int sig);
  285: #endif
  286: #ifndef HAVE_STRTOUL
  287: extern unsigned long int strtoul(const char *nptr, char **endptr, int base);
  288: #endif
  289: 
  290: 
  291: #define GROUP(x)

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