Annotation of gforth/engine/threaded.h, revision 1.2
1.1 anton 1: /* This file defines a number of threading schemes.
2:
1.2 ! anton 3: Copyright (C) 1995, 1996,1997 Free Software Foundation, Inc.
1.1 anton 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., 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21:
22: 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: 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:
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: */
93:
94: #ifndef GETCFA
95: # define CFA_NEXT
96: #endif
97:
98: #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: #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: # define INC_IP(const_inc) ({ip+=(const_inc);})
187: # 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: # define NEXT_P1
258: # define NEXT_P2 ({cfa=*ip++; goto **cfa;})
259: # 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: # define NEXT_P1
310: # define NEXT_P2 ({cfa=*ip++; goto **cfa;})
311: # 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: #else /* !defined(CISC_NEXT) || defined(LONG_LATENCY) */
334: # ifdef DIRECT_THREADED
335: # define NEXT1_P1
336: # define NEXT1_P2 ({goto *cfa;})
337: # else /* !DIRECT_THREADED */
338: # define NEXT1_P1 ({ca = *cfa;})
339: # define NEXT1_P2 ({goto *ca;})
340: # 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>