]>
Commit | Line | Data |
---|---|---|
538d56bb JB |
1 | # -*- C -*- |
2 | # bytecode.def - definitions of bytecodes for the stack machine. | |
3 | ||
4 | # The production of the bytecode interpreter and compiler is | |
5 | # heavily automated by using this file creatively. | |
6 | ||
7 | # Various elementary data types are understood by the bytecode interpreter. | |
8 | # Q[IU] - quarter word (byte) signed and unsigned integers (char). | |
9 | # H[IU] - half word signed and unsigned integers (short int, maybe int). | |
10 | # S[IU] - single word signed and unsigned integers (maybe int, long int). | |
11 | # D[IU] - double word signed and unsigned integers (long long int). | |
12 | # SF - single precision floating point (float). | |
13 | # DF - double precision floating point (double). | |
14 | # XF - extended precision floating point (long double). | |
15 | # P - pointer type for address arithmetic and other purposes. | |
16 | ||
17 | # The bytecode specification consists of a series of define_operator | |
18 | # forms, that are parsed by preprocessors to automatically build | |
19 | # various switch statements. | |
20 | # define_operator(name, | |
21 | # <C prototype code for implementing the operator>, | |
22 | # <list of variations>) | |
23 | # The <C prototype> is self explanatory. | |
24 | # The <list of variations> consists of a (parenthesized list) of | |
25 | # variation items, each of which is in itself a list. A variation | |
26 | # item consists of a name suffix, the types of the input arguments | |
27 | # expected on the stack (shallowest item first) and (optionally) the | |
28 | # types of the output arguments (similarly ordered). Finally, the | |
29 | # types of the literal arguments (if any) may appear. | |
30 | ||
31 | # Substitution in the C prototype code is as follows: | |
32 | # Substitution happens only after a dollar sign. To get a literal | |
33 | # dollar sign (why would you ever want one anyway?) use $$. | |
34 | # $R1 means "result 1" $TR1 means "type name of result one" | |
35 | # $S1 means "source 1" and similarly with $TS1. | |
36 | # $L1 means "literal (inline) argument 1" and $TL1 means type thereof. | |
37 | # | |
38 | ||
39 | # Notice that the number following $R doesn't affect the push order; | |
40 | # it's used only for clarity and orthogonality, although it's checked | |
41 | # to make sure it doesn't exceed the number of outputs. A $R reference | |
42 | # results in a push, and represents the result lvalue. E.g. | |
43 | ||
44 | # $R1 = 2\, $R2 = 17 | |
45 | # will expand to: | |
46 | # INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17 | |
47 | # | |
48 | ||
49 | # Opcode 0 should never happen. | |
50 | define_operator(neverneverland, abort\(\), (())) | |
51 | ||
52 | # Stack manipulations. | |
53 | define_operator(drop, 0, ((, (SI)))) | |
61ccad3f | 54 | define_operator(duplicate, 0, ((, (SI), (SI, SI)))) |
538d56bb JB |
55 | define_operator(over, 0, ((, (SI), (SI, SI)))) |
56 | ||
57 | # Adjust stack pointer | |
58 | ||
59 | define_operator(setstack, 0, ((SI,,,(SI)))) | |
60 | define_operator(adjstack, 0, ((SI,,,(SI)))) | |
61 | ||
62 | # Constants, loads, and stores. | |
63 | define_operator(const, | |
64 | $R1 = $L1, | |
65 | ((QI,, (QI), (QI)), (HI,, (HI), (HI)), | |
66 | (SI,, (SI), (SI)), (DI,, (DI), (DI)), | |
67 | (SF,, (SF), (SF)), (DF,, (DF), (DF)), | |
68 | (XF,, (XF), (XF)), (P,, (P), (P)))) | |
69 | define_operator(load, | |
70 | $R1 = *\($TR1 *\) $S1, | |
71 | ((QI, (P), (QI)), (HI, (P), (HI)), | |
72 | (SI, (P), (SI)), (DI, (P), (DI)), | |
73 | (SF, (P), (SF)), (DF, (P), (DF)), | |
74 | (XF, (P), (XF)), (P, (P), (P)))) | |
75 | define_operator(store, | |
76 | *\($TS2 *\) $S1 = $S2, | |
77 | ((QI, (P, QI)), (HI, (P, HI)), | |
78 | (SI, (P, SI)), (DI, (P, DI)), | |
79 | (SF, (P, SF)), (DF, (P, DF)), | |
80 | (XF, (P, XF)), (P, (P, P)), | |
81 | (BLK, (SI, BLK, BLK)))) | |
82 | ||
83 | # Clear memory block | |
84 | ||
85 | define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK)))) | |
86 | ||
87 | ||
88 | # Advance pointer by SI constant | |
89 | ||
90 | define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI)))) | |
91 | ||
92 | ||
93 | # newlocalSI is used for creating variable-sized storage during function | |
94 | # initialization. | |
95 | ||
96 | # Create local space, return pointer to block | |
97 | ||
98 | define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P)))) | |
99 | ||
100 | ||
101 | # Push the address of a local variable. | |
102 | define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI)))) | |
103 | ||
104 | # Push the address of an argument variable. | |
105 | define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI)))) | |
106 | ||
107 | # Arithmetic conversions. | |
108 | define_operator(convert, | |
109 | $R1 = \($TR1\) $S1, | |
110 | (# Signed integral promotions (sign extensions). | |
111 | (QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)), | |
112 | (QISI, (QI), (SI)), | |
113 | # Unsigned integral promotions (zero extensions). | |
114 | (QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)), | |
115 | (QUSU, (QU), (SU)), | |
116 | # Floating promotions. | |
117 | (SFDF, (SF), (DF)), (DFXF, (DF), (XF)), | |
118 | # Integral truncation. | |
119 | (HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)), | |
120 | (SIQI, (SI), (QI)), | |
121 | # Unsigned truncation. | |
122 | (SUQU, (SU), (QU)), | |
123 | # Floating truncation. | |
124 | (DFSF, (DF), (SF)), (XFDF, (XF), (DF)), | |
125 | # Integral conversions to floating types. | |
126 | (SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)), | |
127 | (SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)), | |
128 | (DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)), | |
129 | (DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)), | |
130 | # Floating conversions to integral types. | |
131 | (SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)), | |
132 | (SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)), | |
133 | (SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)), | |
134 | (SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)), | |
135 | # Pointer/integer conversions. | |
136 | (PSI, (P), (SI)), (SIP, (SI), (P)))) | |
137 | ||
138 | # Truth value conversion. These are necessary because conversions of, e.g., | |
139 | # floating types to integers may not function correctly for large values. | |
140 | define_operator(convert, | |
141 | $R1 = !!$S1, | |
142 | ((SIT, (SI), (T)), (DIT, (DI), (T)), | |
143 | (SFT, (SF), (T)), (DFT, (DF), (T)), | |
144 | (XFT, (XF), (T)), (PT, (P), (T)))) | |
145 | ||
146 | # Bit field load/store. | |
147 | ||
148 | # Load and zero-extend bitfield | |
149 | ||
150 | define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU)))) | |
151 | ||
152 | # Load and sign-extend bitfield | |
153 | ||
154 | define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI)))) | |
155 | ||
156 | # Store integer in bitfield | |
157 | ||
158 | define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI)))) | |
159 | ||
160 | ||
161 | # Binary operations. | |
162 | define_operator(add, | |
163 | $R1 = $S1 + $S2, | |
164 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), | |
165 | (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), | |
166 | (XF, (XF, XF), (XF)), | |
167 | (PSI, (P, SI), (P)))) | |
168 | define_operator(sub, | |
169 | $R1 = $S1 - $S2, | |
170 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), | |
171 | (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), | |
172 | (XF, (XF, XF), (XF)), | |
173 | (PP, (P, P), (SI)))) | |
174 | define_operator(mul, | |
175 | $R1 = $S1 * $S2, | |
176 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), | |
177 | (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), | |
178 | (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), | |
179 | (XF, (XF, XF), (XF)))) | |
180 | define_operator(div, | |
181 | $R1 = $S1 / $S2, | |
182 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), | |
183 | (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), | |
184 | (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), | |
185 | (XF, (XF, XF), (XF)))) | |
186 | define_operator(mod, | |
187 | $R1 = $S1 % $S2, | |
188 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), | |
189 | (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)))) | |
190 | define_operator(and, | |
191 | $R1 = $S1 & $S2, | |
192 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) | |
193 | define_operator(ior, | |
194 | $R1 = $S1 | $S2, | |
195 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) | |
196 | define_operator(xor, | |
197 | $R1 = $S1 ^ $S2, | |
198 | ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) | |
199 | define_operator(lshift, | |
200 | $R1 = $S1 << $S2, | |
201 | ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), | |
202 | (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) | |
203 | define_operator(rshift, | |
204 | $R1 = $S1 >> $S2, | |
205 | ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), | |
206 | (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) | |
207 | define_operator(lt, | |
208 | $R1 = $S1 < $S2, | |
209 | ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), | |
210 | (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), | |
211 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
212 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
213 | define_operator(le, | |
214 | $R1 = $S1 <= $S2, | |
215 | ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), | |
216 | (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), | |
217 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
218 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
219 | define_operator(ge, | |
220 | $R1 = $S1 >= $S2, | |
221 | ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), | |
222 | (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), | |
223 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
224 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
225 | define_operator(gt, | |
226 | $R1 = $S1 > $S2, | |
227 | ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), | |
228 | (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), | |
229 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
230 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
231 | define_operator(eq, | |
232 | $R1 = $S1 == $S2, | |
233 | ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), | |
234 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
235 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
236 | define_operator(ne, | |
237 | $R1 = $S1 != $S2, | |
238 | ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), | |
239 | (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), | |
240 | (XF, (XF, XF), (T)), (P, (P, P), (T)))) | |
241 | ||
242 | # Unary operations. | |
243 | define_operator(neg, | |
244 | $R1 = -$S1, | |
245 | ((SI, (SI), (SI)), (DI, (DI), (DI)), | |
246 | (SF, (SF), (SF)), (DF, (DF), (DF)), | |
247 | (XF, (XF), (XF)))) | |
248 | define_operator(not, | |
249 | $R1 = ~$S1, | |
250 | ((SI, (SI), (SI)), (DI, (DI), (DI)))) | |
251 | define_operator(not, | |
252 | $R1 = !$S1, | |
253 | ((T, (SI), (SI)))) | |
254 | ||
255 | # Increment operations. | |
256 | define_operator(predec, | |
257 | $R1 = *\($TR1 *\) $S1 -= $S2, | |
258 | ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), | |
259 | (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), | |
260 | (P, (P, SI), (P)), (SF, (P, SF), (SF)), | |
261 | (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), | |
262 | (BI, (SU, SU, P, SI), (SI)))) | |
263 | ||
264 | define_operator(preinc, | |
265 | $R1 = *\($TR1 *\) $S1 += $S2, | |
266 | ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), | |
267 | (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), | |
268 | (P, (P, SI), (P)), (SF, (P, SF), (SF)), | |
269 | (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), | |
270 | (BI, (SU, SU, P, SI), (SI)))) | |
271 | ||
272 | define_operator(postdec, | |
273 | $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2, | |
274 | ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), | |
275 | (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), | |
276 | (P, (P, SI), (P)), (SF, (P, SF), (SF)), | |
277 | (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), | |
278 | (BI, (SU, SU, P, SI), (SI)))) | |
279 | ||
280 | define_operator(postinc, | |
281 | $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2, | |
282 | ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), | |
283 | (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), | |
284 | (P, (P, SI), (P)), (SF, (P, SF), (SF)), | |
285 | (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), | |
286 | (BI, (SU, SU, P, SI), (SI)))) | |
287 | ||
288 | # Jumps. | |
2f2c485a JB |
289 | define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) |
290 | define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) | |
538d56bb JB |
291 | define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI)))) |
292 | ||
293 | # This is for GCC2. It jumps to the address on the stack. | |
294 | define_operator(jump, pc = \(void *\) $S1, ((P,,))) | |
295 | ||
296 | # Switches. In order to (eventually) support ranges we provide four different | |
297 | # varieties of switches. Arguments are the switch index from the stack, the | |
298 | # bytecode offset of the switch table, the size of the switch table, and | |
299 | # the default label. | |
300 | define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI)))) | |
301 | define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI)))) | |
302 | define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI)))) | |
303 | define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI)))) | |
304 | ||
305 | # Procedure call. | |
306 | # Stack arguments are (deepest first): | |
307 | # procedure arguments in reverse order. | |
308 | # pointer to the place to hold the return value. | |
309 | # address of the call description vector. | |
310 | # pointer to the procedure to be called. | |
311 | define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P)))) | |
312 | ||
313 | # Procedure return. | |
314 | # Pushes on interpreter stack: | |
315 | # value of retptr (pointer to return value storage slot) | |
316 | define_operator(return, $R1 = retptr, ((P,,(P)))) | |
317 | ||
318 | # Really return. | |
319 | define_operator(ret, return, (())) | |
320 | ||
321 | # Print an obnoxious line number. | |
322 | define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI)))) |