/source/Opcodes.ooc
Unknown | 374 lines | 304 code | 70 blank | 0 comment | 0 complexity | bc1fb972ad7b99df8a1004458af0dd1f MD5 | raw file
1 2include stdint 3 4 5/*=========================================================================== 6 We assume that instructions are unsigned numbers. 7 All instructions have an opcode in the first 6 bits. 8 Instructions can have the following fields: 9 `A' : 8 bits 10 `B' : 9 bits 11 `C' : 9 bits 12 'Ax' : 26 bits ('A', 'B', and 'C' together) 13 `Bx' : 18 bits (`B' and `C' together) 14 `sBx' : signed Bx 15 16 A signed argument is represented in excess K; that is, the number 17 value is the unsigned value minus K. K is exactly the maximum value 18 for that argument (so that -max is represented by 0, and +max is 19 represented by 2*max), which is half the maximum for the corresponding 20 unsigned argument. 21===========================================================================*/ 22 23 24OpMode: enum { /* basic instruction format */ 25 iABC, 26 iABx, 27 iAsBx, 28 iAx 29} 30 31 32/* 33** size and position of opcode arguments. 34*/ 35SIZE_C := const 9 36SIZE_B := const 9 37SIZE_Bx := const SIZE_C + SIZE_B 38SIZE_A := const 8 39SIZE_Ax := const SIZE_C + SIZE_B + SIZE_A 40 41SIZE_OP := const 6 42 43POS_OP := const 0 44POS_A := const POS_OP + SIZE_OP 45POS_C := const POS_A + SIZE_A 46POS_B := const POS_C + SIZE_C 47POS_Bx := const POS_C 48POS_Ax := const POS_A 49 50 51/* 52** limits for opcode arguments. 53** we use (signed) int to manipulate most arguments, 54** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) 55*/ 56MAXARG_Bx := const (1 << SIZE_Bx) - 1 57MAXARG_sBx := const MAXARG_Bx >> 1 /* `sBx' is signed */ 58MAXARG_Ax := const (1 << SIZE_Ax) - 1 59MAXARG_A := const (1 << SIZE_A) - 1 60MAXARG_B := const (1 << SIZE_B) - 1 61MAXARG_C := const (1 << SIZE_C) - 1 62 63 64Instruction: cover from uint32_t { 65 createABC: static inline func(o: OpCode, a, b, c: UInt) -> This { 66 return (o as UInt << POS_OP | a << POS_A | b << POS_B | c << POS_C) as Instruction 67 } 68 69 createABx: static inline func(o: OpCode, a, bc: UInt) -> This { 70 return (o as UInt << POS_OP | a << POS_A | bc << POS_Bx) as Instruction 71 } 72 73 createAx: static inline func(o: OpCode, a: UInt) -> This { 74 return (o as UInt << POS_OP | a << POS_Ax) as Instruction 75 } 76 77 getOpcode: inline func -> OpCode { 78 return ((this >> POS_OP) & ~(~0 << SIZE_OP)) as OpCode 79 } 80 81 setOpcode: inline func(o: OpCode) -> Instruction { 82 return (this & ~(~(~0 << SIZE_OP) << POS_OP)) | ((o << POS_OP) & (~(~0 << SIZE_OP)) << POS_OP) 83 } 84 85 getarg_A: inline func -> Int { 86 return ((this >> POS_A) & ~(~0 << SIZE_A)) as Int 87 } 88 89 setarg_A: inline func(a: UInt) -> Instruction { 90 return (this & ~(~(~0 << SIZE_A) << POS_A)) | ((a << POS_A) & (~(~0 << SIZE_A)) << POS_A) 91 } 92 93 getarg_B: inline func -> Int { 94 return ((this >> POS_B) & ~(~0 << SIZE_B)) as Int 95 } 96 97 setarg_B: inline func(b: UInt) -> Instruction { 98 return (this & ~(~(~0 << SIZE_B) << POS_B)) | ((b << POS_B) & (~(~0 << SIZE_B)) << POS_B) 99 } 100 101 getarg_C: inline func -> Int { 102 return ((this >> POS_C) & ~(~0 << SIZE_C)) as Int 103 } 104 105 setarg_C: inline func(c: UInt) -> Instruction { 106 return (this & ~(~(~0 << SIZE_C) << POS_C)) | ((c << POS_C) & (~(~0 << SIZE_C)) << POS_C) 107 } 108 109 getarg_Bx: inline func -> Int { 110 return ((this >> POS_Bx) & ~(~0 << SIZE_Bx)) as Int 111 } 112 113 setarg_Bx: inline func(b: UInt) -> Instruction { 114 return (this & ~(~(~0 << SIZE_Bx) << POS_Bx)) | ((b << POS_Bx) & (~(~0 << SIZE_Bx)) << POS_Bx) 115 } 116 117 getarg_Ax: inline func -> Int { 118 return ((this >> POS_Ax) & ~(~0 << SIZE_Ax)) as Int 119 } 120 121 setarg_Ax: inline func(a: UInt) -> Instruction { 122 return (this & ~(~(~0 << SIZE_Ax) << POS_Ax)) | ((a << POS_Ax) & (~(~0 << SIZE_Ax)) << POS_Ax) 123 } 124 125 getarg_sBx: inline func -> Int { 126 return (((this >> POS_Bx) & ~(~0 << SIZE_Bx)) - MAXARG_sBx) as Int 127 } 128 129 setarg_sBx: inline func(b: Int) -> Instruction { 130 return (this & ~(~(~0 << SIZE_Bx) << POS_Bx)) | (((b + MAXARG_sBx) << POS_Bx) & (~(~0 << SIZE_Bx)) << POS_Bx) 131 } 132} 133 134 135/* this bit 1 means constant (0 means register) */ 136BITRK := const 1 << (SIZE_B - 1) 137MAXINDEXRK := const BITRK - 1 138 139 140/* 141** invalid register that fits in 8 bits 142*/ 143NO_REG := const MAXARG_A 144 145 146/* 147** R(x) - register 148** Kst(x) - constant (in constant table) 149** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) 150*/ 151 152/* 153** grep "ORDER OP" if you change these enums 154*/ 155 156OpCode: enum { 157 /*---------------------------------------------------------------------- 158 name args description 159 ------------------------------------------------------------------------*/ 160 OP_MOVE,/* A B R(A) := R(B) */ 161 OP_LOADK,/* A Bx R(A) := Kst(Bx - 1) */ 162 OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ 163 OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ 164 OP_GETUPVAL,/* A B R(A) := UpValue[B] */ 165 166 OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ 167 OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ 168 169 OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */ 170 OP_SETUPVAL,/* A B UpValue[B] := R(A) */ 171 OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ 172 173 OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ 174 175 OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ 176 177 OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ 178 OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ 179 OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ 180 OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ 181 OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ 182 OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ 183 OP_UNM,/* A B R(A) := -R(B) */ 184 OP_NOT,/* A B R(A) := not R(B) */ 185 OP_LEN,/* A B R(A) := length of R(B) */ 186 187 OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ 188 189 OP_JMP,/* sBx pc+=sBx */ 190 191 OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ 192 OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ 193 OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ 194 195 OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ 196 OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 197 198 OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 199 OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 200 OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 201 202 OP_FORLOOP,/* A sBx R(A)+=R(A+2); 203 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ 204 OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ 205 206 OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ 207 OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ 208 209 OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ 210 211 OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ 212 OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ 213 214 OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ 215 216 OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ 217 218 getOpMode: inline func -> OpMode { 219 return (OP_MODES[this] & 3) as OpMode 220 } 221 222 getBMode: inline func -> OpArgMask { 223 return ((OP_MODES[this] >> 4) & 3) as OpArgMask 224 } 225 226 getCMode: inline func -> OpArgMask { 227 return ((OP_MODES[this] >> 2) & 3) as OpArgMask 228 } 229 230 testAMode: inline func -> Bool { 231 return (OP_MODES[this] & (1 << 6)) != 0 232 } 233 234 testTMode: inline func -> Bool { 235 return (OP_MODES[this] & (1 << 7)) != 0 236 } 237} 238 239 240OP_NAMES := const [ 241 "MOVE", 242 "LOADK", 243 "LOADBOOL", 244 "LOADNIL", 245 "GETUPVAL", 246 "GETTABUP", 247 "GETTABLE", 248 "SETTABUP", 249 "SETUPVAL", 250 "SETTABLE", 251 "NEWTABLE", 252 "SELF", 253 "ADD", 254 "SUB", 255 "MUL", 256 "DIV", 257 "MOD", 258 "POW", 259 "UNM", 260 "NOT", 261 "LEN", 262 "CONCAT", 263 "JMP", 264 "EQ", 265 "LT", 266 "LE", 267 "TEST", 268 "TESTSET", 269 "CALL", 270 "TAILCALL", 271 "RETURN", 272 "FORLOOP", 273 "FORPREP", 274 "TFORCALL", 275 "TFORLOOP", 276 "SETLIST", 277 "CLOSE", 278 "CLOSURE", 279 "VARARG", 280 "EXTRAARG" 281] 282 283/* 284** masks for instruction properties. The format is: 285** bits 0-1: op mode 286** bits 2-3: C arg mode 287** bits 4-5: B arg mode 288** bit 6: instruction set register A 289** bit 7: operator is a test (next instruction must be a jump) 290*/ 291 292OpArgMask: enum { 293 OpArgN, /* argument is not used */ 294 OpArgU, /* argument is used */ 295 OpArgR, /* argument is a register or a jump offset */ 296 OpArgK /* argument is a constant or register/constant */ 297} 298 299OP_MODES := const [ 300/* T A B C mode opcode */ 301 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_MOVE */ 302 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgN<<2) | OpMode iABx, /* OP_LOADK */ 303 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_LOADBOOL */ 304 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_LOADNIL */ 305 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_GETUPVAL */ 306 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_GETTABUP */ 307 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_GETTABLE */ 308 (0<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SETTABUP */ 309 (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_SETUPVAL */ 310 (0<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SETTABLE */ 311 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_NEWTABLE */ 312 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SELF */ 313 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_ADD */ 314 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SUB */ 315 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_MUL */ 316 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_DIV */ 317 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_MOD */ 318 (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_POW */ 319 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_UNM */ 320 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_NOT */ 321 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_LEN */ 322 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgR<<2) | OpMode iABC, /* OP_CONCAT */ 323 (0<<7) | (0<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_JMP */ 324 (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_EQ */ 325 (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_LT */ 326 (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_LE */ 327 (1<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TEST */ 328 (1<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TESTSET */ 329 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_CALL */ 330 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TAILCALL */ 331 (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_RETURN */ 332 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_FORLOOP */ 333 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_FORPREP */ 334 (0<<7) | (0<<6) | (OpArgMask OpArgN<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TFORCALL */ 335 (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_TFORLOOP */ 336 (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_SETLIST */ 337 (0<<7) | (0<<6) | (OpArgMask OpArgN<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_CLOSE */ 338 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABx, /* OP_CLOSURE */ 339 (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_VARARG */ 340 (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iAx, /* OP_EXTRAARG */ 341] 342 343/* number of list items to accumulate before a SETLIST instruction */ 344LFIELDS_PER_FLUSH := const 50 345 346/* option for multiple returns in 'lua_pcall' and 'lua_call' */ 347LUA_MULTRET := const -1 348 349 350/* 351** converts an integer to a "floating point byte", represented as 352** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if 353** eeeee != 0 and (xxx) otherwise. 354*/ 355int2fb: func(x: UInt32) -> Int { 356 e := 0 /* exponent */ 357 if (x < 8) 358 return x 359 while (x >= 0x10) { 360 x = (x+1) >> 1 361 e += 1 362 } 363 return ((e+1) << 3) | (x as Int - 8) 364} 365 366/* converts back */ 367fb2int: func(x: Int) -> Int { 368 e := (x >> 3) & 0x1f 369 if (e == 0) 370 return x 371 else 372 return ((x & 7) + 8) << (e - 1) 373} 374