[gforth] / gforth / Attic / threading.h  

gforth: gforth/Attic/threading.h


1 : pazsan 1.1 /* This file defines a number of threading schemes.
2 : anton 1.2
3 : anton 1.4 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
4 : anton 1.2
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 :    
21 :    
22 : anton 1.4 This files defines macros for threading. Many sets of macros are
23 :     defined. Functionally they have only one difference: Some implement
24 :     direct threading, some indirect threading. The other differences are
25 :     just variations to help GCC generate faster code for various
26 :     machines.
27 :    
28 :     (Well, to tell the truth, there actually is another functional
29 :     difference in some pathological cases: e.g., a '!' stores into the
30 :     cell where the next executed word comes from; or, the next word
31 :     executed comes from the top-of-stack. These differences are one of
32 :     the reasons why GCC cannot produce the right variation by itself. We
33 :     chose disallowing such practices and using the added implementation
34 :     freedom to achieve a significant speedup, because these practices
35 :     are not common in Forth (I have never heard of or seen anyone using
36 :     them), and it is easy to circumvent problems: A control flow change
37 :     will flush any prefetched words; you may want to do a "0
38 :     drop" before that to write back the top-of-stack cache.)
39 :    
40 :     These macro sets are used in the following ways: After translation
41 :     to C a typical primitive looks like
42 :    
43 :     ...
44 :     {
45 :     DEF_CA
46 :     other declarations
47 :     NEXT_P0;
48 :     main part of the primitive
49 :     NEXT_P1;
50 :     store results to stack
51 :     NEXT_P2;
52 :     }
53 :    
54 :     DEF_CA and all the NEXT_P* together must implement NEXT; In the main
55 :     part the instruction pointer can be read with IP, changed with
56 :     INC_IP(const_inc), and the cell right behind the presently executing
57 :     word (i.e. the value of *IP) is accessed with NEXT_INST.
58 :    
59 :     If a primitive does not fall through the main part, it has to do the
60 :     rest by itself. If it changes ip, it has to redo NEXT_P0 (perhaps we
61 :     should define a macro SET_IP).
62 :    
63 :     Some primitives (execute, dodefer) do not end with NEXT, but with
64 :     EXEC(.). If NEXT_P0 has been called earlier, it has to perform
65 :     "ip=IP;" to ensure that ip has the right value (NEXT_P0 may change
66 :     it).
67 :    
68 :     Finally, there is NEXT1_P1 and NEXT1_P2, which are parts of EXEC
69 :     (EXEC(XT) could be defined as "cfa=XT; NEXT1_P1; NEXT1_P2;" (is this
70 :     true?)) and are used for making docol faster.
71 :    
72 :     We can define the ways in which these macros are used with a regular
73 :     expression:
74 :    
75 :     For a primitive
76 :    
77 :     DEF_CA NEXT_P0 ( IP | INC_IP | NEXT_INST | ip=...; NEXT_P0 ) * ( NEXT_P1 NEXT_P2 | EXEC(...) )
78 :    
79 :     For a run-time routine, e.g., docol:
80 :     PFA1(cfa) ( NEXT_P0 NEXT | cfa=...; NEXT1_P1; NEXT1_P2 | EXEC(...) )
81 :    
82 :     This comment does not yet describe all the dependences that the
83 :     macros have to satisfy.
84 :    
85 : anton 1.2 To organize the former ifdef chaos, each path is separated
86 :     This gives a quite impressive number of paths, but you clearly
87 :     find things that go together.
88 : anton 1.4
89 :     It should be possible to organize the whole thing in a way that
90 :     contains less redundancy and allows a simpler description.
91 :    
92 : anton 1.2 */
93 : pazsan 1.1
94 :     #ifndef GETCFA
95 :     # define CFA_NEXT
96 :     #endif
97 :    
98 : anton 1.5 #ifdef DOUBLY_INDIRECT
99 :     # define NEXT_P0 ({cfa=*ip;})
100 :     # define IP (ip)
101 :     # define NEXT_INST (cfa)
102 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
103 :     # define DEF_CA Label ca;
104 :     # define NEXT_P1 ({ip++; ca=**cfa;})
105 :     # define NEXT_P2 ({goto *ca;})
106 :     # define EXEC(XT) ({DEF_CA cfa=(XT); ca=**cfa; goto *ca;})
107 :     # define NEXT1_P1 ({ca = **cfa;})
108 :     # define NEXT1_P2 ({goto *ca;})
109 :    
110 :     #else /* !defined(DOUBLY_INDIRECT) */
111 :    
112 : pazsan 1.1 #if defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
113 :     && defined(LONG_LATENCY) && defined(CFA_NEXT)
114 :     #warning scheme 1
115 :     # define NEXT_P0 ({cfa=*ip++;})
116 :     # define IP (ip-1)
117 :     # define NEXT_INST (cfa)
118 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
119 :     # define DEF_CA
120 :     # define NEXT_P1
121 :     # define NEXT_P2 ({goto *cfa;})
122 :     # define EXEC(XT) ({cfa=(XT); goto *cfa;})
123 :     #endif
124 :    
125 :     #if defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
126 :     && defined(LONG_LATENCY) && !defined(CFA_NEXT)
127 :     #warning scheme 2
128 :     # define NEXT_P0 (ip++)
129 :     # define IP (ip-1)
130 :     # define NEXT_INST (*(ip-1))
131 :     # define INC_IP(const_inc) ({ ip+=(const_inc);})
132 :     # define DEF_CA
133 :     # define NEXT_P1
134 :     # define NEXT_P2 ({goto **(ip-1);})
135 :     # define EXEC(XT) ({goto *(XT);})
136 :     #endif
137 :    
138 :    
139 :     #if defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
140 :     && !defined(LONG_LATENCY) && defined(CFA_NEXT)
141 :     #warning scheme 3
142 :     # define NEXT_P0
143 :     # define IP (ip)
144 :     # define NEXT_INST (*ip)
145 :     # define INC_IP(const_inc) ({ip+=(const_inc);})
146 :     # define DEF_CA
147 :     # define NEXT_P1 ({cfa=*ip++;})
148 :     # define NEXT_P2 ({goto *cfa;})
149 :     # define EXEC(XT) ({cfa=(XT); goto *cfa;})
150 :     #endif
151 :    
152 :     #if defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
153 :     && !defined(LONG_LATENCY) && !defined(CFA_NEXT)
154 :     #warning scheme 4
155 :     # define NEXT_P0
156 :     # define IP (ip)
157 :     # define NEXT_INST (*ip)
158 :     # define INC_IP(const_inc) ({ ip+=(const_inc);})
159 :     # define DEF_CA
160 :     # define NEXT_P1
161 :     # define NEXT_P2 ({goto **(ip++);})
162 :     # define EXEC(XT) ({goto *(XT);})
163 :     #endif
164 :    
165 :     /* without autoincrement */
166 :    
167 :     #if defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
168 :     && defined(LONG_LATENCY) && defined(CFA_NEXT)
169 :     #warning scheme 5
170 :     # define NEXT_P0 ({cfa=*ip;})
171 :     # define IP (ip)
172 :     # define NEXT_INST (cfa)
173 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
174 :     # define DEF_CA
175 :     # define NEXT_P1 (ip++)
176 :     # define NEXT_P2 ({goto *cfa;})
177 :     # define EXEC(XT) ({cfa=(XT); goto *cfa;})
178 :     #endif
179 :    
180 :     #if defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
181 :     && defined(LONG_LATENCY) && !defined(CFA_NEXT)
182 :     #warning scheme 6
183 :     # define NEXT_P0
184 :     # define IP (ip)
185 :     # define NEXT_INST (*ip)
186 : anton 1.2 # define INC_IP(const_inc) ({ip+=(const_inc);})
187 : pazsan 1.1 # define DEF_CA
188 :     # define NEXT_P1 (ip++)
189 :     # define NEXT_P2 ({goto **(ip-1);})
190 :     # define EXEC(XT) ({goto *(XT);})
191 :     #endif
192 :    
193 :    
194 :     #if defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
195 :     && !defined(LONG_LATENCY) && defined(CFA_NEXT)
196 :     #warning scheme 7
197 :     # define NEXT_P0
198 :     # define IP (ip)
199 :     # define NEXT_INST (*ip)
200 :     # define INC_IP(const_inc) ({ip+=(const_inc);})
201 :     # define DEF_CA
202 :     # define NEXT_P1 ({cfa=*ip++;})
203 :     # define NEXT_P2 ({goto *cfa;})
204 :     # define EXEC(XT) ({cfa=(XT); goto *cfa;})
205 :     #endif
206 :    
207 :     #if defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
208 :     && !defined(LONG_LATENCY) && !defined(CFA_NEXT)
209 :     #warning scheme 8
210 :     # define NEXT_P0
211 :     # define IP (ip)
212 :     # define NEXT_INST (*IP)
213 :     # define INC_IP(const_inc) ({ ip+=(const_inc);})
214 :     # define DEF_CA
215 :     # define NEXT_P1 (ip++)
216 :     # define NEXT_P2 ({goto **(ip-1);})
217 :     # define EXEC(XT) ({goto *(XT);})
218 :     #endif
219 :    
220 :     /* common settings for direct THREADED */
221 :    
222 :    
223 :     /* indirect THREADED */
224 :    
225 :     #if !defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
226 :     && defined(LONG_LATENCY) && defined(CISC_NEXT)
227 :     # define NEXT_P0 ({cfa=*ip++;})
228 :     # define IP (ip-1)
229 :     # define NEXT_INST (cfa)
230 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
231 :     # define DEF_CA
232 :     # define NEXT_P1
233 :     # define NEXT_P2 ({goto **cfa;})
234 :     # define EXEC(XT) ({cfa=(XT); goto **cfa;})
235 :     #endif
236 :    
237 :     #if !defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
238 :     && defined(LONG_LATENCY) && !defined(CISC_NEXT)
239 :     # define NEXT_P0 ({cfa=*ip++;})
240 :     # define IP (ip-1)
241 :     # define NEXT_INST (cfa)
242 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
243 :     # define DEF_CA Label ca;
244 :     # define NEXT_P1 ({ca=*cfa;})
245 :     # define NEXT_P2 ({goto *ca;})
246 :     # define EXEC(XT) ({DEF_CA cfa=(XT); ca=*cfa; goto *ca;})
247 :     #endif
248 :    
249 :    
250 :     #if !defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
251 :     && !defined(LONG_LATENCY) && defined(CISC_NEXT)
252 :     # define NEXT_P0
253 :     # define IP (ip)
254 :     # define NEXT_INST (*ip)
255 :     # define INC_IP(const_inc) ({ip+=(const_inc);})
256 :     # define DEF_CA
257 : pazsan 1.3 # define NEXT_P1
258 :     # define NEXT_P2 ({cfa=*ip++; goto **cfa;})
259 : pazsan 1.1 # define EXEC(XT) ({cfa=(XT); goto **cfa;})
260 :     #endif
261 :    
262 :     #if !defined(DIRECT_THREADED) && defined(AUTO_INCREMENT)\
263 :     && !defined(LONG_LATENCY) && !defined(CISC_NEXT)
264 :     # define NEXT_P0 ({cfa=*ip++;})
265 :     # define IP (ip-1)
266 :     # define NEXT_INST (cfa)
267 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
268 :     # define DEF_CA Label ca;
269 :     # define NEXT_P1 ({ca=*cfa;})
270 :     # define NEXT_P2 ({goto *ca;})
271 :     # define EXEC(XT) ({DEF_CA cfa=(XT); ca=*cfa; goto *ca;})
272 :     #endif
273 :    
274 :    
275 :     /* without autoincrement */
276 :    
277 :     #if !defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
278 :     && defined(LONG_LATENCY) && defined(CISC_NEXT)
279 :     # define NEXT_P0 ({cfa=*ip;})
280 :     # define IP (ip)
281 :     # define NEXT_INST (cfa)
282 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
283 :     # define DEF_CA
284 :     # define NEXT_P1 (ip++)
285 :     # define NEXT_P2 ({goto **cfa;})
286 :     # define EXEC(XT) ({cfa=(XT); goto **cfa;})
287 :     #endif
288 :    
289 :     #if !defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
290 :     && defined(LONG_LATENCY) && !defined(CISC_NEXT)
291 :     # define NEXT_P0 ({cfa=*ip;})
292 :     # define IP (ip)
293 :     # define NEXT_INST (cfa)
294 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
295 :     # define DEF_CA Label ca;
296 :     # define NEXT_P1 ({ip++; ca=*cfa;})
297 :     # define NEXT_P2 ({goto *ca;})
298 :     # define EXEC(XT) ({DEF_CA cfa=(XT); ca=*cfa; goto *ca;})
299 :     #endif
300 :    
301 :    
302 :     #if !defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
303 :     && !defined(LONG_LATENCY) && defined(CISC_NEXT)
304 :     # define NEXT_P0
305 :     # define IP (ip)
306 :     # define NEXT_INST (*ip)
307 :     # define INC_IP(const_inc) ({ip+=(const_inc);})
308 :     # define DEF_CA
309 : pazsan 1.3 # define NEXT_P1
310 :     # define NEXT_P2 ({cfa=*ip++; goto **cfa;})
311 : pazsan 1.1 # define EXEC(XT) ({cfa=(XT); goto **cfa;})
312 :     #endif
313 :    
314 :     #if !defined(DIRECT_THREADED) && !defined(AUTO_INCREMENT)\
315 :     && !defined(LONG_LATENCY) && !defined(CISC_NEXT)
316 :     # define NEXT_P0 ({cfa=*ip;})
317 :     # define IP (ip)
318 :     # define NEXT_INST (cfa)
319 :     # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
320 :     # define DEF_CA Label ca;
321 :     # define NEXT_P1 ({ip++; ca=*cfa;})
322 :     # define NEXT_P2 ({goto *ca;})
323 :     # define EXEC(XT) ({DEF_CA cfa=(XT); ca=*cfa; goto *ca;})
324 :     #endif
325 :    
326 :     #if defined(CISC_NEXT) && !defined(LONG_LATENCY)
327 :     # define NEXT1_P1
328 :     # ifdef DIRECT_THREADED
329 :     # define NEXT1_P2 ({goto *cfa;})
330 :     # else
331 :     # define NEXT1_P2 ({goto **cfa;})
332 :     # endif /* DIRECT_THREADED */
333 : anton 1.5 #else /* !defined(CISC_NEXT) || defined(LONG_LATENCY) */
334 : pazsan 1.1 # ifdef DIRECT_THREADED
335 :     # define NEXT1_P1
336 :     # define NEXT1_P2 ({goto *cfa;})
337 : anton 1.5 # else /* !DIRECT_THREADED */
338 : pazsan 1.1 # define NEXT1_P1 ({ca = *cfa;})
339 :     # define NEXT1_P2 ({goto *ca;})
340 : anton 1.5 # endif /* !DIRECT_THREADED */
341 :     #endif /* !defined(CISC_NEXT) || defined(LONG_LATENCY) */
342 :    
343 :     #endif /* !defined(DOUBLY_INDIRECT) */
344 :    
345 :     #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
346 :    

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help