[gforth] / gforth / Attic / engine.c  

gforth: gforth/Attic/engine.c


1 : anton 1.1 /*
2 : anton 1.17 $Id: engine.c,v 1.16 1994/09/26 20:31:10 pazsan Exp $
3 : anton 1.1 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 : pazsan 1.2 #include <time.h>
16 : pazsan 1.6 #include <sys/time.h>
17 : anton 1.1 #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 : anton 1.14 /* 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
50 : anton 1.1 #ifdef DIRECT_THREADED
51 : anton 1.14 #define NEXT1_P2 ({goto *cfa;})
52 : anton 1.1 #else
53 : anton 1.14 #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 */
69 : anton 1.1
70 : anton 1.14 #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})
71 :     #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
72 : anton 1.1
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 :    
90 : anton 1.14 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 :     }
118 : pazsan 1.13
119 : anton 1.1 #define NEWLINE '\n'
120 :    
121 : pazsan 1.13
122 : anton 1.1 static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};
123 : pazsan 1.6
124 : pazsan 1.11 static Address up0=NULL;
125 :    
126 : anton 1.15 /* if machine.h has not defined explicit registers, define them as implicit */
127 :     #ifndef IPREG
128 :     #define IPREG
129 :     #endif
130 :     #ifndef SPREG
131 :     #define SPREG
132 :     #endif
133 :     #ifndef RPREG
134 :     #define RPREG
135 :     #endif
136 :     #ifndef FPREG
137 :     #define FPREG
138 :     #endif
139 :     #ifndef LPREG
140 :     #define LPREG
141 :     #endif
142 :     #ifndef CFAREG
143 :     #define CFAREG
144 :     #endif
145 :     #ifndef UPREG
146 :     #define UPREG
147 :     #endif
148 :     #ifndef TOSREG
149 :     #define TOSREG
150 :     #endif
151 :     #ifndef FTOSREG
152 :     #define FTOSREG
153 :     #endif
154 : pazsan 1.13
155 : anton 1.15 Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0)
156 : anton 1.1 /* executes code at ip, if ip!=NULL
157 :     returns array of machine code labels (for use in a loader), if ip==NULL
158 :     */
159 : anton 1.15 {
160 :     register Xt *ip IPREG = ip0;
161 :     register Cell *sp SPREG = sp0;
162 :     register Cell *rp RPREG = rp0;
163 :     register Float *fp FPREG = fp0;
164 :     register Address lp LPREG = lp0;
165 :     register Xt cfa CFAREG;
166 :     register Address up UPREG = up0;
167 :     IF_TOS(register Cell TOS TOSREG;)
168 :     IF_FTOS(register Float FTOS FTOSREG;)
169 : anton 1.1 static Label symbols[]= {
170 :     &&docol,
171 :     &&docon,
172 :     &&dovar,
173 : pazsan 1.4 &&douser,
174 : anton 1.12 &&dodefer,
175 : anton 1.1 &&dodoes,
176 : pazsan 1.6 &&dodoes, /* dummy for does handler address */
177 : anton 1.1 #include "prim_labels.i"
178 :     };
179 :     #ifdef CPU_DEP
180 :     CPU_DEP;
181 :     #endif
182 :    
183 : pazsan 1.16 #ifdef DEBUG
184 :     fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n",
185 :     ip,sp,rp,fp,lp,up);
186 :     #endif
187 :    
188 : anton 1.1 if (ip == NULL)
189 :     return symbols;
190 : anton 1.10
191 : anton 1.1 IF_TOS(TOS = sp[0]);
192 :     IF_FTOS(FTOS = fp[0]);
193 :     prep_terminal();
194 :     NEXT;
195 :    
196 :     docol:
197 :     #ifdef DEBUG
198 : pazsan 1.16 fprintf(stderr,"%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
199 : anton 1.1 #endif
200 : anton 1.15 #ifdef CISC_NEXT
201 : anton 1.1 /* this is the simple version */
202 :     *--rp = (Cell)ip;
203 :     ip = (Xt *)PFA1(cfa);
204 :     NEXT;
205 : anton 1.15 #else
206 : anton 1.1 /* this one is important, so we help the compiler optimizing
207 :     The following version may be better (for scheduling), but probably has
208 :     problems with code fields employing calls and delay slots
209 :     */
210 :     {
211 : pazsan 1.4 DEF_CA
212 : anton 1.1 Xt *current_ip = (Xt *)PFA1(cfa);
213 :     cfa = *current_ip;
214 :     NEXT1_P1;
215 :     *--rp = (Cell)ip;
216 :     ip = current_ip+1;
217 : pazsan 1.3 NEXT1_P2;
218 : anton 1.1 }
219 : anton 1.15 #endif
220 : anton 1.1
221 :     docon:
222 :     #ifdef DEBUG
223 : pazsan 1.16 fprintf(stderr,"%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));
224 : anton 1.1 #endif
225 :     #ifdef USE_TOS
226 :     *sp-- = TOS;
227 :     TOS = *(Cell *)PFA1(cfa);
228 :     #else
229 :     *--sp = *(Cell *)PFA1(cfa);
230 :     #endif
231 :     NEXT;
232 :    
233 :     dovar:
234 :     #ifdef DEBUG
235 : pazsan 1.16 fprintf(stderr,"%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
236 : anton 1.1 #endif
237 :     #ifdef USE_TOS
238 :     *sp-- = TOS;
239 :     TOS = (Cell)PFA1(cfa);
240 :     #else
241 :     *--sp = (Cell)PFA1(cfa);
242 :     #endif
243 :     NEXT;
244 :    
245 :     /* !! user? */
246 :    
247 : pazsan 1.4 douser:
248 :     #ifdef DEBUG
249 : pazsan 1.16 fprintf(stderr,"%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
250 : pazsan 1.4 #endif
251 :     #ifdef USE_TOS
252 :     *sp-- = TOS;
253 : anton 1.5 TOS = (Cell)(up+*(Cell*)PFA1(cfa));
254 : pazsan 1.4 #else
255 : anton 1.5 *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
256 : pazsan 1.4 #endif
257 :     NEXT;
258 :    
259 : anton 1.12 dodefer:
260 :     #ifdef DEBUG
261 : pazsan 1.16 fprintf(stderr,"%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
262 : anton 1.12 #endif
263 :     cfa = *(Xt *)PFA1(cfa);
264 :     NEXT1;
265 :    
266 : anton 1.1 dodoes:
267 :     /* this assumes the following structure:
268 :     defining-word:
269 :    
270 :     ...
271 :     DOES>
272 :     (possible padding)
273 :     possibly handler: jmp dodoes
274 :     (possible branch delay slot(s))
275 :     Forth code after DOES>
276 :    
277 :     defined word:
278 :    
279 :     cfa: address of or jump to handler OR
280 :     address of or jump to dodoes, address of DOES-code
281 :     pfa:
282 :    
283 :     */
284 :     #ifdef DEBUG
285 : anton 1.17 fprintf(stderr,"%08x/%08x: does: %08x\n",(Cell)ip,(Cell)PFA(cfa),(Cell)DOES_CODE1(cfa));
286 : pazsan 1.16 fflush(stderr);
287 : anton 1.1 #endif
288 :     *--rp = (Cell)ip;
289 :     /* PFA1 might collide with DOES_CODE1 here, so we use PFA */
290 : pazsan 1.13 ip = DOES_CODE1(cfa);
291 : anton 1.1 #ifdef USE_TOS
292 :     *sp-- = TOS;
293 :     TOS = (Cell)PFA(cfa);
294 :     #else
295 :     *--sp = (Cell)PFA(cfa);
296 :     #endif
297 :     NEXT;
298 : pazsan 1.16
299 : anton 1.1 #include "primitives.i"
300 :     }

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help