[8833] | 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)))) |
---|
| 54 | define_operator(duplicate, 0, ((, (SI), (SI, SI)))) |
---|
| 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. |
---|
| 289 | define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) |
---|
| 290 | define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) |
---|
| 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)))) |
---|