[gforth] / gforth / Attic / engine.c  

gforth: gforth/Attic/engine.c


1 : anton 1.1 /*
2 : anton 1.15 $Id: engine.c,v 1.14 1994/09/08 17:20:05 anton 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 :     if (ip == NULL)
184 :     return symbols;
185 : anton 1.10
186 : anton 1.1 IF_TOS(TOS = sp[0]);
187 :     IF_FTOS(FTOS = fp[0]);
188 :     prep_terminal();
189 :     NEXT;
190 :    
191 :     docol:
192 :     #ifdef DEBUG
193 : pazsan 1.6 printf("%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
194 : anton 1.1 #endif
195 : anton 1.15 #ifdef CISC_NEXT
196 : anton 1.1 /* this is the simple version */
197 :     *--rp = (Cell)ip;
198 :     ip = (Xt *)PFA1(cfa);
199 :     NEXT;
200 : anton 1.15 #else
201 : anton 1.1 /* this one is important, so we help the compiler optimizing
202 :     The following version may be better (for scheduling), but probably has
203 :     problems with code fields employing calls and delay slots
204 :     */
205 :     {
206 : pazsan 1.4 DEF_CA
207 : anton 1.1 Xt *current_ip = (Xt *)PFA1(cfa);
208 :     cfa = *current_ip;
209 :     NEXT1_P1;
210 :     *--rp = (Cell)ip;
211 :     ip = current_ip+1;
212 : pazsan 1.3 NEXT1_P2;
213 : anton 1.1 }
214 : anton 1.15 #endif
215 : anton 1.1
216 :     docon:
217 :     #ifdef DEBUG
218 : pazsan 1.6 printf("%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));
219 : anton 1.1 #endif
220 :     #ifdef USE_TOS
221 :     *sp-- = TOS;
222 :     TOS = *(Cell *)PFA1(cfa);
223 :     #else
224 :     *--sp = *(Cell *)PFA1(cfa);
225 :     #endif
226 :     NEXT;
227 :    
228 :     dovar:
229 :     #ifdef DEBUG
230 : pazsan 1.6 printf("%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
231 : anton 1.1 #endif
232 :     #ifdef USE_TOS
233 :     *sp-- = TOS;
234 :     TOS = (Cell)PFA1(cfa);
235 :     #else
236 :     *--sp = (Cell)PFA1(cfa);
237 :     #endif
238 :     NEXT;
239 :    
240 :     /* !! user? */
241 :    
242 : pazsan 1.4 douser:
243 :     #ifdef DEBUG
244 : pazsan 1.6 printf("%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
245 : pazsan 1.4 #endif
246 :     #ifdef USE_TOS
247 :     *sp-- = TOS;
248 : anton 1.5 TOS = (Cell)(up+*(Cell*)PFA1(cfa));
249 : pazsan 1.4 #else
250 : anton 1.5 *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
251 : pazsan 1.4 #endif
252 :     NEXT;
253 :    
254 : anton 1.12 dodefer:
255 :     #ifdef DEBUG
256 :     printf("%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));
257 :     #endif
258 :     cfa = *(Xt *)PFA1(cfa);
259 :     NEXT1;
260 :    
261 : anton 1.1 dodoes:
262 :     /* this assumes the following structure:
263 :     defining-word:
264 :    
265 :     ...
266 :     DOES>
267 :     (possible padding)
268 :     possibly handler: jmp dodoes
269 :     (possible branch delay slot(s))
270 :     Forth code after DOES>
271 :    
272 :     defined word:
273 :    
274 :     cfa: address of or jump to handler OR
275 :     address of or jump to dodoes, address of DOES-code
276 :     pfa:
277 :    
278 :     */
279 :     #ifdef DEBUG
280 : pazsan 1.6 printf("%08x/%08x: does: %08x\n",(Cell)ip,(Cell)cfa,*(Cell)PFA(cfa));
281 :     fflush(stdout);
282 : anton 1.1 #endif
283 :     *--rp = (Cell)ip;
284 :     /* PFA1 might collide with DOES_CODE1 here, so we use PFA */
285 : pazsan 1.13 ip = DOES_CODE1(cfa);
286 : anton 1.1 #ifdef USE_TOS
287 :     *sp-- = TOS;
288 :     TOS = (Cell)PFA(cfa);
289 :     #else
290 :     *--sp = (Cell)PFA(cfa);
291 :     #endif
292 :     NEXT;
293 :    
294 :     #include "primitives.i"
295 :     }

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help