File:
[gforth] /
gforth /
engine /
forth.h
Revision
1.33:
download - view:
text,
annotated -
select for diffs
Sun Nov 24 13:54:01 2002 UTC (21 years, 4 months ago) by
anton
Branches:
MAIN
CVS tags:
HEAD
new engine gforth-native (works on 386 arch only for now).
appropriate changes in control-flow instructions in prim
new primitives SET-NEXT-CODE and CALL2 (not necessary for the other engines)
new primitives COMPILE-PRIM1 and FINISH-CODE
prims2x.fs now produces IMMARG(...) macros for initializing immediate args
prims2x.fs: changes in some of the output-c-tail words (goes with the
changes in the control-flow words).
appropriate changes in engine.c
engine.c: rewrite of check_prims, support for gforth-native (NO_IP)
threaded.c: support for NO_IP
various kernel files: started to eliminate return stack manipulations for
embedding data (e.g. string literals); incomplete.
dynamic superinstructions now use LABEL2 instead of IS_NEXT_JUMP
FORCE_REG has no effect if DOUBLY_INDIRECT (gcc-2.95.1 crashes otherwise;
it's unclear which change provoked this).
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)||defined(INDIRECT_THREADED)||defined(VM_PROFILING)
28: #define NO_DYNAMIC
29: #endif
30:
31: #if defined(DOUBLY_INDIRECT)
32: # undef DIRECT_THREADED
33: # undef INDIRECT_THREADED
34: # define INDIRECT_THREADED
35: #endif
36:
37: #if defined(GFORTH_DEBUGGING)
38: # undef USE_TOS
39: # undef USE_FTOS
40: # define USE_NO_TOS
41: # define USE_NO_FTOS
42: #endif
43:
44: #include <limits.h>
45:
46: #if defined(NeXT)
47: # include <libc.h>
48: #endif /* NeXT */
49:
50: /* symbol indexed constants */
51:
52: #define DOCOL 0
53: #define DOCON 1
54: #define DOVAR 2
55: #define DOUSER 3
56: #define DODEFER 4
57: #define DOFIELD 5
58: #define DODOES 6
59: #define DOESJUMP 7
60:
61: /* the size of the DOESJUMP, which resides between DOES> and the does-code */
62: #define DOES_HANDLER_SIZE (2*sizeof(Cell))
63:
64: #include "machine.h"
65:
66: /* Forth data types */
67: /* Cell and UCell must be the same size as a pointer */
68: #define CELL_BITS (sizeof(Cell) * CHAR_BIT)
69: #define FLAG(b) (-(b))
70: #define FILEIO(error) (FLAG(error) & -37)
71: #define FILEEXIST(error) (FLAG(error) & -38)
72:
73: #define F_TRUE (FLAG(0==0))
74: #define F_FALSE (FLAG(0!=0))
75:
76: #ifdef BUGGY_LONG_LONG
77: typedef struct {
78: Cell hi;
79: UCell lo;
80: } DCell;
81:
82: typedef struct {
83: UCell hi;
84: UCell lo;
85: } UDCell;
86:
87: #define LONG2UD(l) ({UDCell _ud; _ud.hi=0; _ud.lo=(Cell)(l); _ud;})
88: #define UD2LONG(ud) ((long)(ud.lo))
89: #define DZERO ((DCell){0,0})
90:
91: #else /* ! defined(BUGGY_LONG_LONG) */
92:
93: /* DCell and UDCell must be twice as large as Cell */
94: typedef DOUBLE_CELL_TYPE DCell;
95: typedef unsigned DOUBLE_CELL_TYPE UDCell;
96:
97: #define LONG2UD(l) ((UDCell)(l))
98: #define UD2LONG(ud) ((long)(ud))
99: #define DZERO ((DCell)0)
100:
101: #endif /* ! defined(BUGGY_LONG_LONG) */
102:
103: typedef union {
104: struct {
105: #if defined(WORDS_BIGENDIAN)||defined(BUGGY_LONG_LONG)
106: Cell high;
107: UCell low;
108: #else
109: UCell low;
110: Cell high;
111: #endif
112: } cells;
113: DCell d;
114: UDCell ud;
115: } Double_Store;
116:
117: #define FETCH_DCELL_T(d_,lo,hi,t_) ({ \
118: Double_Store _d; \
119: _d.cells.low = (lo); \
120: _d.cells.high = (hi); \
121: (d_) = _d.t_; \
122: })
123:
124: #define STORE_DCELL_T(d_,lo,hi,t_) ({ \
125: Double_Store _d; \
126: _d.t_ = (d_); \
127: (lo) = _d.cells.low; \
128: (hi) = _d.cells.high; \
129: })
130:
131: #define vm_twoCell2d(lo,hi,d_) FETCH_DCELL_T(d_,lo,hi,d);
132: #define vm_twoCell2ud(lo,hi,d_) FETCH_DCELL_T(d_,lo,hi,ud);
133:
134: #define vm_d2twoCell(d_,lo,hi) STORE_DCELL_T(d_,lo,hi,d);
135: #define vm_ud2twoCell(d_,lo,hi) STORE_DCELL_T(d_,lo,hi,ud);
136:
137: typedef Label *Xt;
138:
139: /* PFA gives the parameter field address corresponding to a cfa */
140: #define PFA(cfa) (((Cell *)cfa)+2)
141: /* PFA1 is a special version for use just after a NEXT1 */
142: #define PFA1(cfa) PFA(cfa)
143: /* CODE_ADDRESS is the address of the code jumped to through the code field */
144: #define CODE_ADDRESS(cfa) (*(Xt)(cfa))
145:
146: /* DOES_CODE is the Forth code does jumps to */
147: #if !defined(DOUBLY_INDIRECT)
148: # define DOES_CA (symbols[DODOES])
149: #else /* defined(DOUBLY_INDIRECT) */
150: # define DOES_CA ((Label)&xts[DODOES])
151: #endif /* defined(DOUBLY_INDIRECT) */
152:
153:
154:
155: #define DOES_CODE(cfa) ({Xt _cfa=(Xt)(cfa); \
156: (Xt *)(_cfa[0]==DOES_CA ? _cfa[1] : NULL);})
157: #define DOES_CODE1(cfa) ((Xt *)(cfa[1]))
158: /* MAKE_CF creates an appropriate code field at the cfa;
159: ca is the code address */
160: #define MAKE_CF(cfa,ca) ((*(Label *)(cfa)) = ((Label)ca))
161: /* make a code field for a defining-word-defined word */
162: #define MAKE_DOES_CF(cfa,does_code) ({MAKE_CF(cfa,DOES_CA); \
163: ((Cell *)cfa)[1] = (Cell)(does_code);})
164: /* the does handler resides between DOES> and the following Forth code */
165: /* not needed in indirect threaded code */
166: #if defined(DOUBLY_INDIRECT)
167: #define MAKE_DOES_HANDLER(addr) MAKE_CF(addr, ((Label)&symbols[DOESJUMP]))
168: #else /* !defined(DOUBLY_INDIRECT) */
169: #define MAKE_DOES_HANDLER(addr) 0
170: #endif /* !defined(DOUBLY_INDIRECT) */
171:
172: #ifdef GFORTH_DEBUGGING
173: #define NAME(string) { saved_ip=ip; asm(""); }
174: /* the asm here is to avoid reordering of following stuff above the
175: assignment; this is an old-style asm (no operands), and therefore
176: is treated like "asm volatile ..."; i.e., it prevents most
177: reorderings across itself. We want the assignment above first,
178: because the stack loads may already cause a stack underflow. */
179: #elif DEBUG
180: # define NAME(string) fprintf(stderr,"%08lx: "string"\n",(Cell)ip);
181: #else
182: # define NAME(string)
183: #endif
184:
185: #define CF(const) (-const-2)
186:
187: #define CF_NIL -1
188:
189: #ifndef FLUSH_ICACHE
190: #warning flush-icache probably will not work (see manual)
191: # define FLUSH_ICACHE(addr,size)
192: #endif
193:
194: #ifdef USE_TOS
195: #define IF_spTOS(x) x
196: #else
197: #define IF_spTOS(x)
198: #define spTOS (sp[0])
199: #endif
200:
201: #ifdef USE_FTOS
202: #define IF_fpTOS(x) x
203: #else
204: #define IF_fpTOS(x)
205: #define fpTOS (fp[0])
206: #endif
207:
208: #define IF_rpTOS(x)
209: #define rpTOS (rp[0])
210:
211: typedef struct {
212: Address base; /* base address of image (0 if relocatable) */
213: UCell checksum; /* checksum of ca's to protect against some
214: incompatible binary/executable combinations
215: (0 if relocatable) */
216: UCell image_size; /* all sizes in bytes */
217: UCell dict_size;
218: UCell data_stack_size;
219: UCell fp_stack_size;
220: UCell return_stack_size;
221: UCell locals_stack_size;
222: Xt *boot_entry; /* initial ip for booting (in BOOT) */
223: Xt *throw_entry; /* ip after signal (in THROW) */
224: Cell unused1; /* possibly tib stack size */
225: Label *xt_base; /* base of DOUBLE_INDIRECT xts[], for comp-i.fs */
226: Address data_stack_base; /* this and the following fields are initialized by the loader */
227: Address fp_stack_base;
228: Address return_stack_base;
229: Address locals_stack_base;
230: } ImageHeader;
231: /* the image-header is created in main.fs */
232:
233: Label *engine(Xt *ip, Cell *sp, Cell *rp, Float *fp, Address lp);
234: Address my_alloc(Cell size);
235: char *tilde_cstr(Char *from, UCell size, int clear);
236:
237: /* dblsub routines */
238: DCell dnegate(DCell d1);
239: UDCell ummul (UCell a, UCell b);
240: DCell mmul (Cell a, Cell b);
241: UDCell umdiv (UDCell u, UCell v);
242: DCell smdiv (DCell num, Cell denom);
243: DCell fmdiv (DCell num, Cell denom);
244:
245: Cell memcasecmp(const Char *s1, const Char *s2, Cell n);
246:
247: /* peephole routines */
248:
249: Xt *primtable(Label symbols[], Cell size);
250: Cell prepare_peephole_table(Xt xts[]);
251: Xt peephole_opt(Xt xt1, Xt xt2, Cell peeptable);
252: void vm_print_profile(FILE *file);
253: void vm_count_block(Xt *ip);
254:
255: /* dynamic superinstruction stuff */
256: Label compile_prim(Label prim);
257: void compile_prim1(Cell *start);
258: void finish_code(void);
259:
260: extern int offset_image;
261: extern int die_on_signal;
262: extern UCell pagesize;
263: extern ImageHeader *gforth_header;
264: extern Label *vm_prims;
265: extern Label *xts;
266: extern Cell npriminfos;
267:
268: #ifdef HAS_DEBUG
269: extern int debug;
270: #else
271: # define debug 0
272: #endif
273:
274: #ifdef GFORTH_DEBUGGING
275: extern Xt *saved_ip;
276: extern Cell *rp;
277: #endif
278:
279: #ifdef PRINT_SUPER_LENGTHS
280: Cell prim_length(Cell prim);
281: void print_super_lengths();
282: #endif
283:
284: /* declare all the functions that are missing */
285: #ifndef HAVE_ATANH
286: extern double atanh(double r1);
287: extern double asinh(double r1);
288: extern double acosh(double r1);
289: #endif
290: #ifndef HAVE_ECVT
291: /* extern char* ecvt(double x, int len, int* exp, int* sign);*/
292: #endif
293: #ifndef HAVE_MEMMOVE
294: /* extern char *memmove(char *dest, const char *src, long n); */
295: #endif
296: #ifndef HAVE_POW10
297: extern double pow10(double x);
298: #endif
299: #ifndef HAVE_STRERROR
300: extern char *strerror(int err);
301: #endif
302: #ifndef HAVE_STRSIGNAL
303: extern char *strsignal(int sig);
304: #endif
305: #ifndef HAVE_STRTOUL
306: extern unsigned long int strtoul(const char *nptr, char **endptr, int base);
307: #endif
308:
309:
310: #define GROUP(x)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>