1 // 2 // gravity_opcodes.h 3 // gravity 4 // 5 // Created by Marco Bambini on 24/09/14. 6 // Copyright (c) 2014 CreoLabs. All rights reserved. 7 // 8 9 #ifndef __GRAVITY_OPCODES__ 10 #define __GRAVITY_OPCODES__ 11 12 /* 13 Big-endian vs Little-endian machines 14 15 ARM architecture runs both little & big endianess, but the android, iOS, and windows phone platforms run little endian. 16 95% of modern desktop computers are little-endian. 17 All x86 desktops (which is nearly all desktops with the demise of the PowerPC-based Macs several years ago) are little-endian. 18 It's probably actually a lot more than 95% nowadays. PowerPC was the only non-x86 architecture that has been popular for desktop 19 computers in the last 20 years and Apple abandoned it in favor of x86. 20 Sparc, Alpha, and Itanium did exist, but they were all very rare in the desktop market. 21 */ 22 23 /* 24 Instructions are 32bit in length 25 26 // 2 registers and 1 register/constant 27 +------------------------------------+ 28 | OP | Ax | Bx | Cx/K | 29 +------------------------------------+ 30 31 // instructions with no parameters 32 +------------------------------------+ 33 | OP |0 | 34 +------------------------------------+ 35 36 // unconditional JUMP 37 +------------------------------------+ 38 | OP | N1 | 39 +------------------------------------+ 40 41 // LOADI and JUMPF 42 +------------------------------------+ 43 | OP | Ax |S| N2 | 44 +------------------------------------+ 45 46 OP => 6 bits 47 Ax => 8 bits 48 Bx => 8 bits 49 Cx/K => 8/10 bits 50 S => 1 bit 51 N1 => 26 bits 52 N2 => 17 bits 53 */ 54 55 typedef enum { 56 57 // *********************************************************************************************************** 58 // 56 OPCODE INSTRUCTIONS (for a register based virtual machine) 59 // opcode is a 6 bit value so at maximum 2^6 = 64 opcodes can be declared 60 // ************************************************************************************************************ 61 // 62 // MNEMONIC PARAMETERS DESCRIPTION OPERATION 63 // -------- ---------- ------------------------------------ ---------------------------- 64 // 65 // *** GENERAL COMMANDS (5) *** 66 RET0 = 0, // NONE // return nothing from a function MUST BE THE FIRST OPCODE (because an implicit 0 is added 67 // as a safeguard at the end of any bytecode 68 HALT, // NONE // stop VM execution 69 NOP, // NONE // NOP http://en.wikipedia.org/wiki/NOP 70 RET, // A // return from a function R(-1) = R(A) 71 CALL, // A, B, C // call a function R(A) = B(C0...Cn) B is callable object and C is num args 72 73 // *** LOAD/STORE OPERATIONS (11) *** 74 LOAD, // A, B, C // load C from B and store in A R(A) = R(B)[C] 75 LOADS, // A, B, C // load C from B and store in A R(A) = R(B)[C] (super variant) 76 LOADAT, // A, B, C // load C from B and store in A R(A) = R(B)[C] 77 LOADK, // A, B // load constant into register R(A) = K(B) 78 LOADG, // A, B // load global into register R(A) = G[K(B)] 79 LOADI, // A, B // load integer into register R(A) = I 80 LOADU, // A, B // load upvalue into register R(A) = U(B) 81 MOVE, // A, B // move registers R(A) = R(B) 82 STORE, // A, B, C // store A into R(B)[C] R(B)[C] = R(A) 83 STOREAT, // A, B, C // store A into R(B)[C] R(B)[C] = R(A) 84 STOREG, // A, B // store global G[K(B)] = R(A) 85 STOREU, // A, B // store upvalue U(B) = R(A) 86 87 // *** JUMP OPERATIONS (3) *** 88 JUMP, // A // unconditional jump PC += A 89 JUMPF, // A, B // jump if R(A) is false (R(A) == 0) ? PC += B : 0 90 SWITCH, // // switch statement 91 92 // *** MATH OPERATIONS (19) *** 93 ADD, // A, B, C // add operation R(A) = R(B) + R(C) 94 SUB, // A, B, C // sub operation R(A) = R(B) - R(C) 95 DIV, // A, B, C // div operation R(A) = R(B) / R(C) 96 MUL, // A, B, C // mul operation R(A) = R(B) * R(C) 97 REM, // A, B, C // rem operation R(A) = R(B) % R(C) 98 AND, // A, B, C // and operation R(A) = R(B) && R(C) 99 OR, // A, B, C // or operation R(A) = R(B) || R(C) 100 LT, // A, B, C // < comparison R(A) = R(B) < R(C) 101 GT, // A, B, C // > comparison R(A) = R(B) > R(C) 102 EQ, // A, B, C // == comparison R(A) = R(B) == R(C) 103 LEQ, // A, B, C // <= comparison R(A) = R(B) <= R(C) 104 GEQ, // A, B, C // >= comparison R(A) = R(B) >= R(C) 105 NEQ, // A, B, C // != comparison R(A) = R(B) != R(C) 106 EQQ, // A, B, C // === comparison R(A) = R(B) === R(C) 107 NEQQ, // A, B, C // !== comparison R(A) = R(B) !== R(C) 108 ISA, // A, B, C // isa comparison R(A) = R(A).class == R(B).class 109 MATCH, // A, B, C // =~ pattern match R(A) = R(B) =~ R(C) 110 NEG, // A, B // neg operation R(A) = -R(B) 111 NOT, // A, B // not operation R(A) = !R(B) 112 113 // *** BIT OPERATIONS (6) *** 114 LSHIFT, // A, B, C // shift left R(A) = R(B) << R(C) 115 RSHIFT, // A, B, C // shift right R(A) = R(B) >> R(C) 116 BAND, // A, B, C // bit and R(A) = R(B) & R(C) 117 BOR, // A, B, C // bit or R(A) = R(B) | R(C) 118 BXOR, // A, B, C // bit xor R(A) = R(B) ^ R(C) 119 BNOT, // A, B // bit not R(A) = ~R(B) 120 121 // *** ARRAY/MAP/RANGE OPERATIONS (4) *** 122 MAPNEW, // A, B // create a new map R(A) = Alloc a MAP(B) 123 LISTNEW, // A, B // create a new array R(A) = Alloc a LIST(B) 124 RANGENEW, // A, B, C, f // create a new range R(A) = Alloc a RANGE(B,C) f flag tells if B inclusive or exclusive 125 SETLIST, // A, B, C // set list/map items 126 127 // *** CLOSURES (2) *** 128 CLOSURE, // A, B // create a new closure R(A) = closure(K(B)) 129 CLOSE, // A // close all upvalues from R(A) 130 131 // *** UNUSED (6) *** 132 CHECK, // A // checkpoint for structs R(A) = R(A).clone (if A is a struct) 133 RESERVED2, // // reserved for future use 134 RESERVED3, // // reserved for future use 135 RESERVED4, // // reserved for future use 136 RESERVED5, // // reserved for future use 137 RESERVED6 // // reserved for future use 138 } opcode_t; 139 140 #define GRAVITY_LATEST_OPCODE RESERVED6 // used in some debug code so it is very useful to define the latest opcode here 141 142 typedef enum { 143 GRAVITY_NOTFOUND_INDEX = 0, 144 GRAVITY_ADD_INDEX, 145 GRAVITY_SUB_INDEX, 146 GRAVITY_DIV_INDEX, 147 GRAVITY_MUL_INDEX, 148 GRAVITY_REM_INDEX, 149 GRAVITY_AND_INDEX, 150 GRAVITY_OR_INDEX, 151 GRAVITY_CMP_INDEX, 152 GRAVITY_EQQ_INDEX, 153 GRAVITY_IS_INDEX, 154 GRAVITY_MATCH_INDEX, 155 GRAVITY_NEG_INDEX, 156 GRAVITY_NOT_INDEX, 157 GRAVITY_LSHIFT_INDEX, 158 GRAVITY_RSHIFT_INDEX, 159 GRAVITY_BAND_INDEX, 160 GRAVITY_BOR_INDEX, 161 GRAVITY_BXOR_INDEX, 162 GRAVITY_BNOT_INDEX, 163 GRAVITY_LOAD_INDEX, 164 GRAVITY_LOADS_INDEX, 165 GRAVITY_LOADAT_INDEX, 166 GRAVITY_STORE_INDEX, 167 GRAVITY_STOREAT_INDEX, 168 GRAVITY_INT_INDEX, 169 GRAVITY_FLOAT_INDEX, 170 GRAVITY_BOOL_INDEX, 171 GRAVITY_STRING_INDEX, 172 GRAVITY_EXEC_INDEX, 173 GRAVITY_VTABLE_SIZE // MUST BE LAST ENTRY IN THIS ENUM 174 } GRAVITY_VTABLE_INDEX; 175 176 #define GRAVITY_OPERATOR_ADD_NAME "+" 177 #define GRAVITY_OPERATOR_SUB_NAME "-" 178 #define GRAVITY_OPERATOR_DIV_NAME "/" 179 #define GRAVITY_OPERATOR_MUL_NAME "*" 180 #define GRAVITY_OPERATOR_REM_NAME "%" 181 #define GRAVITY_OPERATOR_AND_NAME "&&" 182 #define GRAVITY_OPERATOR_OR_NAME "||" 183 #define GRAVITY_OPERATOR_CMP_NAME "==" 184 #define GRAVITY_OPERATOR_EQQ_NAME "===" 185 #define GRAVITY_OPERATOR_NEQQ_NAME "!==" 186 #define GRAVITY_OPERATOR_IS_NAME "is" 187 #define GRAVITY_OPERATOR_MATCH_NAME "=~" 188 #define GRAVITY_OPERATOR_NEG_NAME "neg" 189 #define GRAVITY_OPERATOR_NOT_NAME "!" 190 #define GRAVITY_OPERATOR_LSHIFT_NAME "<<" 191 #define GRAVITY_OPERATOR_RSHIFT_NAME ">>" 192 #define GRAVITY_OPERATOR_BAND_NAME "&" 193 #define GRAVITY_OPERATOR_BOR_NAME "|" 194 #define GRAVITY_OPERATOR_BXOR_NAME "^" 195 #define GRAVITY_OPERATOR_BNOT_NAME "~" 196 #define GRAVITY_INTERNAL_LOAD_NAME "load" 197 #define GRAVITY_INTERNAL_LOADS_NAME "loads" 198 #define GRAVITY_INTERNAL_STORE_NAME "store" 199 #define GRAVITY_INTERNAL_LOADAT_NAME "loadat" 200 #define GRAVITY_INTERNAL_STOREAT_NAME "storeat" 201 #define GRAVITY_INTERNAL_NOTFOUND_NAME "notfound" 202 #define GRAVITY_INTERNAL_EXEC_NAME "exec" 203 #define GRAVITY_INTERNAL_LOOP_NAME "loop" 204 205 #define GRAVITY_CLASS_INT_NAME "Int" 206 #define GRAVITY_CLASS_FLOAT_NAME "Float" 207 #define GRAVITY_CLASS_BOOL_NAME "Bool" 208 #define GRAVITY_CLASS_STRING_NAME "String" 209 #define GRAVITY_CLASS_OBJECT_NAME "Object" 210 #define GRAVITY_CLASS_CLASS_NAME "Class" 211 #define GRAVITY_CLASS_NULL_NAME "Null" 212 #define GRAVITY_CLASS_FUNCTION_NAME "Func" 213 #define GRAVITY_CLASS_FIBER_NAME "Fiber" 214 #define GRAVITY_CLASS_INSTANCE_NAME "Instance" 215 #define GRAVITY_CLASS_CLOSURE_NAME "Closure" 216 #define GRAVITY_CLASS_LIST_NAME "List" 217 #define GRAVITY_CLASS_MAP_NAME "Map" 218 #define GRAVITY_CLASS_RANGE_NAME "Range" 219 #define GRAVITY_CLASS_UPVALUE_NAME "Upvalue" 220 221 #define GRAVITY_CLASS_SYSTEM_NAME "System" 222 #define GRAVITY_SYSTEM_PRINT_NAME "print" 223 #define GRAVITY_SYSTEM_PUT_NAME "put" 224 #define GRAVITY_SYSTEM_INPUT_NAME "input" 225 #define GRAVITY_SYSTEM_NANOTIME_NAME "nanotime" 226 227 #define GRAVITY_TOCLASS_NAME "toClass" 228 #define GRAVITY_TOSTRING_NAME "toString" 229 #define GRAVITY_TOINT_NAME "toInt" 230 #define GRAVITY_TOFLOAT_NAME "toFloat" 231 #define GRAVITY_TOBOOL_NAME "toBool" 232 233 #endif 234