| | 1 | /* |
| | 2 | $Header: d:/cvsroot/tads/TADS2/OPC.H,v 1.2 1999/05/17 02:52:12 MJRoberts Exp $ |
| | 3 | */ |
| | 4 | |
| | 5 | /* |
| | 6 | * Copyright (c) 1991, 2002 Michael J. Roberts. All Rights Reserved. |
| | 7 | * |
| | 8 | * Please see the accompanying license file, LICENSE.TXT, for information |
| | 9 | * on using and copying this software. |
| | 10 | */ |
| | 11 | /* |
| | 12 | Name |
| | 13 | opc.h - opcode definitions |
| | 14 | Function |
| | 15 | Defines opcodes |
| | 16 | Notes |
| | 17 | Lifted largely from the old TADS, since the basic run-time interpreter's |
| | 18 | operation is essentially the same. |
| | 19 | Modified |
| | 20 | 09/23/91 MJRoberts - creation |
| | 21 | */ |
| | 22 | |
| | 23 | #ifndef OPC_INCLUDED |
| | 24 | #define OPC_INCLUDED |
| | 25 | |
| | 26 | |
| | 27 | #define OPCPUSHNUM 1 /* push a constant numeric value */ |
| | 28 | #define OPCPUSHOBJ 2 /* push an object */ |
| | 29 | #define OPCNEG 3 /* unary negation */ |
| | 30 | #define OPCNOT 4 /* logical negation */ |
| | 31 | #define OPCADD 5 /* addition/list concatenation */ |
| | 32 | #define OPCSUB 6 /* subtraction/list difference */ |
| | 33 | #define OPCMUL 7 /* multiplication */ |
| | 34 | #define OPCDIV 8 /* division */ |
| | 35 | #define OPCAND 9 /* logical AND */ |
| | 36 | #define OPCOR 10 /* logical OR */ |
| | 37 | #define OPCEQ 11 /* equality */ |
| | 38 | #define OPCNE 12 /* inequality */ |
| | 39 | #define OPCGT 13 /* greater than */ |
| | 40 | #define OPCGE 14 /* greater or equal */ |
| | 41 | #define OPCLT 15 /* less than */ |
| | 42 | #define OPCLE 16 /* less or equal */ |
| | 43 | #define OPCCALL 17 /* call a function */ |
| | 44 | #define OPCGETP 18 /* get property */ |
| | 45 | #define OPCGETPDATA 19 /* get a property, allowing only data values */ |
| | 46 | #define OPCGETLCL 20 /* get a local variable's value */ |
| | 47 | #define OPCPTRGETPDATA 21 /* get property via pointer; only allow data */ |
| | 48 | #define OPCRETURN 22 /* return without a value */ |
| | 49 | #define OPCRETVAL 23 /* return a value */ |
| | 50 | #define OPCENTER 24 /* enter a function */ |
| | 51 | #define OPCDISCARD 25 /* discard top of stack */ |
| | 52 | #define OPCJMP 26 /* unconditional jump */ |
| | 53 | #define OPCJF 27 /* jump if false */ |
| | 54 | #define OPCPUSHSELF 28 /* push current object */ |
| | 55 | #define OPCSAY 29 /* implicit printout for doublequote strings */ |
| | 56 | #define OPCBUILTIN 30 /* call a built-in function */ |
| | 57 | #define OPCPUSHSTR 31 /* push a string */ |
| | 58 | #define OPCPUSHLST 32 /* push a list */ |
| | 59 | #define OPCPUSHNIL 33 /* push the NIL value */ |
| | 60 | #define OPCPUSHTRUE 34 /* push the TRUE value */ |
| | 61 | #define OPCPUSHFN 35 /* push the address of a function */ |
| | 62 | #define OPCGETPSELFDATA 36 /* push property of self; only allow data */ |
| | 63 | |
| | 64 | #define OPCPTRCALL 38 /* call function pointed to by top of stack */ |
| | 65 | #define OPCPTRINH 39 /* inherit pointer to property (stack=prop) */ |
| | 66 | #define OPCPTRGETP 40 /* get property by pointer (stack=obj,prop) */ |
| | 67 | |
| | 68 | #define OPCPASS 41 /* pass to inherited handler */ |
| | 69 | #define OPCEXIT 42 /* exit turn, but continue with fuses/daemons */ |
| | 70 | #define OPCABORT 43 /* abort turn, skipping fuses/daemons */ |
| | 71 | #define OPCASKDO 44 /* ask for a direct object */ |
| | 72 | #define OPCASKIO 45 /* ask for indirect object and set preposition */ |
| | 73 | |
| | 74 | /* explicit superclass inheritance opcodes */ |
| | 75 | #define OPCEXPINH 46 /* "inherited <superclass>.<property>" */ |
| | 76 | #define OPCEXPINHPTR 47 /* "inherited <superclass>.<prop-pointer>" */ |
| | 77 | |
| | 78 | /* |
| | 79 | * Special opcodes for peephole optimization. These are essentially |
| | 80 | * pairs of operations that occur frequently so have been collapsed into |
| | 81 | * a single instruction. |
| | 82 | */ |
| | 83 | #define OPCCALLD 48 /* call function and discard value */ |
| | 84 | #define OPCGETPD 49 /* evaluate property and discard any value */ |
| | 85 | #define OPCBUILTIND 50 /* call built-in function and discard value */ |
| | 86 | |
| | 87 | #define OPCJE 51 /* jump if equal */ |
| | 88 | #define OPCJNE 52 /* jump if not equal */ |
| | 89 | #define OPCJGT 53 /* jump if greater than */ |
| | 90 | #define OPCJGE 54 /* jump if greater or equal */ |
| | 91 | #define OPCJLT 55 /* jump if less than */ |
| | 92 | #define OPCJLE 56 /* jump if less or equal */ |
| | 93 | #define OPCJNAND 57 /* jump if not AND */ |
| | 94 | #define OPCJNOR 58 /* jump if not OR */ |
| | 95 | #define OPCJT 59 /* jump if true */ |
| | 96 | |
| | 97 | #define OPCGETPSELF 60 /* get property of the 'self' object */ |
| | 98 | #define OPCGETPSLFD 61 /* get property of 'self' and discard result */ |
| | 99 | #define OPCGETPOBJ 62 /* get property of a given object */ |
| | 100 | /* note: differs from GETP in that object is */ |
| | 101 | /* encoded into the instruction */ |
| | 102 | #define OPCGETPOBJD 63 /* get property of an object and discard result */ |
| | 103 | #define OPCINDEX 64 /* get an indexed entry from a list */ |
| | 104 | |
| | 105 | #define OPCPUSHPN 67 /* push a property number */ |
| | 106 | |
| | 107 | #define OPCJST 68 /* jump and save top-of-stack if true */ |
| | 108 | #define OPCJSF 69 /* jump and save top-of-stack if false */ |
| | 109 | #define OPCJMPD 70 /* discard stack and then jump unconditionally */ |
| | 110 | |
| | 111 | #define OPCINHERIT 71 /* inherit a property from superclass */ |
| | 112 | #define OPCCALLEXT 72 /* call external function */ |
| | 113 | #define OPCDBGRET 73 /* return to debugger (no stack frame leaving) */ |
| | 114 | |
| | 115 | #define OPCCONS 74 /* construct list from top two stack elements */ |
| | 116 | #define OPCSWITCH 75 /* switch statement */ |
| | 117 | |
| | 118 | #define OPCARGC 76 /* get argument count */ |
| | 119 | #define OPCCHKARGC 77 /* check actual arguments against formal count */ |
| | 120 | |
| | 121 | #define OPCLINE 78 /* line record */ |
| | 122 | #define OPCFRAME 79 /* local variable frame record */ |
| | 123 | #define OPCBP 80 /* breakpoint - replaces an OPCLINE instruction */ |
| | 124 | #define OPCGETDBLCL 81 /* get debugger local */ |
| | 125 | #define OPCGETPPTRSELF 82 /* get property pointer from self */ |
| | 126 | #define OPCMOD 83 /* modulo */ |
| | 127 | #define OPCBAND 84 /* binary AND */ |
| | 128 | #define OPCBOR 85 /* binary OR */ |
| | 129 | #define OPCXOR 86 /* binary XOR */ |
| | 130 | #define OPCBNOT 87 /* binary negation */ |
| | 131 | #define OPCSHL 88 /* bit shift left */ |
| | 132 | #define OPCSHR 89 /* bit shift right */ |
| | 133 | |
| | 134 | #define OPCNEW 90 /* create new object */ |
| | 135 | #define OPCDELETE 91 /* delete object */ |
| | 136 | |
| | 137 | |
| | 138 | /* ----- opcodes 192 and above are reserved for assignment operations ----- */ |
| | 139 | |
| | 140 | /* |
| | 141 | ASSIGNMENT OPERATIONS |
| | 142 | When (opcode & 0xc0 == 0xc0), we have an assignment operation. |
| | 143 | (Note that this means that opcodes from 0xc0 up are all reserved |
| | 144 | for assignment operations.) The low six bits of the opcode |
| | 145 | specify exactly what kind of operation is to be performed: |
| | 146 | |
| | 147 | bits 0-1: specifies destination type: |
| | 148 | 00 2-byte operand is local number |
| | 149 | 01 2-byte operand is property to set in obj at tos |
| | 150 | 10 tos is index, [sp-1] is list to be indexed and set |
| | 151 | 11 tos is property pointer, [sp-1] is object |
| | 152 | |
| | 153 | bits 2-4: specifies assignment operation: |
| | 154 | 000 := (direct assignment) |
| | 155 | 001 += (add tos to destination) |
| | 156 | 010 -= (subtract tos from destination) |
| | 157 | 011 *= (multiply destination by tos) |
| | 158 | 100 /= (divide destination by tos) |
| | 159 | 101 ++ (increment tos) |
| | 160 | 110 -- (decrement tos) |
| | 161 | 111 *reserved* |
| | 162 | |
| | 163 | bit 5: specifies what to do with value computed by assignment |
| | 164 | 0 leave on stack (implies pre increment/decrement) |
| | 165 | 1 discard (implies post increment/decrement) |
| | 166 | */ |
| | 167 | #define OPCASI_MASK 0xc0 /* assignment instruction */ |
| | 168 | |
| | 169 | #define OPCASIDEST_MASK 0x03 /* mask to get destination field */ |
| | 170 | #define OPCASILCL 0x00 /* assign to a local */ |
| | 171 | #define OPCASIPRP 0x01 /* assign to an object.property */ |
| | 172 | #define OPCASIIND 0x02 /* assign to an element of a list */ |
| | 173 | #define OPCASIPRPPTR 0x03 /* assign property via pointer */ |
| | 174 | |
| | 175 | #define OPCASITYP_MASK 0x1c /* mask to get assignment type field */ |
| | 176 | #define OPCASIDIR 0x00 /* direct assignment */ |
| | 177 | #define OPCASIADD 0x04 /* assign and add */ |
| | 178 | #define OPCASISUB 0x08 /* assign and subtract */ |
| | 179 | #define OPCASIMUL 0x0c /* assign and multiply */ |
| | 180 | #define OPCASIDIV 0x10 /* assign and divide */ |
| | 181 | #define OPCASIINC 0x14 /* increment */ |
| | 182 | #define OPCASIDEC 0x18 /* decrement */ |
| | 183 | #define OPCASIEXT 0x1c /* other - extension flag */ |
| | 184 | |
| | 185 | /* extended assignment flags - next byte when OPCASIEXT is used */ |
| | 186 | #define OPCASIMOD 1 /* modulo and assign */ |
| | 187 | #define OPCASIBAND 2 /* binary AND and assign */ |
| | 188 | #define OPCASIBOR 3 /* binary OR and assign */ |
| | 189 | #define OPCASIXOR 4 /* binary XOR and assign */ |
| | 190 | #define OPCASISHL 5 /* shift left and assign */ |
| | 191 | #define OPCASISHR 6 /* shift right and assign */ |
| | 192 | |
| | 193 | |
| | 194 | #define OPCASIPRE_MASK 0x20 /* mask for pre/post field */ |
| | 195 | #define OPCASIPOST 0x00 /* increment after push */ |
| | 196 | #define OPCASIPRE 0x20 /* increment before push */ |
| | 197 | |
| | 198 | /* some composite opcodes for convenience */ |
| | 199 | #define OPCSETLCL (OPCASI_MASK | OPCASILCL | OPCASIDIR) |
| | 200 | |
| | 201 | #endif /* OPC_INCLUDED */ |