|
|
1.1 ! root 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))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.