//1// gravity_opcodes.h2// gravity3//4// Created by Marco Bambini on 24/09/14.5// Copyright (c) 2014 CreoLabs. All rights reserved.6//78#ifndef __GRAVITY_OPCODES__9#define __GRAVITY_OPCODES__1011/*12Big-endian vs Little-endian machines1314ARM architecture runs both little & big endianess, but the android, iO6, and windows phone platforms run little endian.1595% of modern desktop computers are little-endian.16All x86 desktops (which is nearly all desktops with the demise of the PowerPC-based Macs several years ago) are little-endian.17It's probably actually a lot more than 95% nowadays. PowerPC was the only non-x86 architecture that has been popular for desktop18computers in the last 20 years and Apple abandoned it in favor of x86.19Sparc, Alpha, and Itanium did exist, but they were all very rare in the desktop market.20*/2122/*23Instructions are 32bit in lenght2425// 2 registers and 1 register/constant26+------------------------------------+27| OP | Ax | Bx | Cx/K |28+------------------------------------+2930// instructions with no parameters31+------------------------------------+32| OP |0 |33+------------------------------------+3435// unconditional JUMP36+------------------------------------+37| OP | N1 |38+------------------------------------+3940// LOADI and JUMPF41+------------------------------------+42| OP | Ax |S| N2 |43+------------------------------------+4445OP => 6 bits46Ax => 8 bits47Bx => 8 bits48Cx/K => 8/10 bits49S => 1 bit50N1 => 26 bits51N2 => 17 bits52*/5354typedef enum {5556// ****************************************************************************************************57// 56 OPCODE INSTRUCTIONS (for a register based virtual machine)58// opcode is a 6 bit value so at maximum 2^6 = 64 opcodes can be declared59// ****************************************************************************************************60//61// MNEMONIC PARAMETERS DESCRIPTION OPERATION62// -------- ---------- ------------------------------------ ----------------------------63//64// *** GENERAL COMMANDS (5) ***65RET0 = 0, // NONE // return nothing from a function MUST BE THE FIRST OPCODE (because an implict 0 is added66// as a safeguard at the end of any bytecode67HALT, // NONE // stop VM execution68NOP, // NONE // NOP http://en.wikipedia.org/wiki/NOP69RET, // A // return from a function R(-1) = R(A)70CALL, // A, B, C // call a function R(A) = B(C0...Cn) B is callable object and C is num args7172// *** LOAD/STORE OPERATIONS (11) ***73LOAD, // A, B, C // load C from B and store in A R(A) = R(B)[C]74LOADS, // A, B, C // load C from B and store in A R(A) = R(B)[C] (super variant)75LOADAT, // A, B, C // load C from B and store in A R(A) = R(B)[C]76LOADK, // A, B // load constant into register R(A) = K(B)77LOADG, // A, B // load global into register R(A) = G[K(B)]78LOADI, // A, B // load integer into register R(A) = I79LOADU, // A, B // load upvalue into register R(A) = U(B)80MOVE, // A, B // move registers R(A) = R(B)81STORE, // A, B, C // store A into R(B)[C] R(B)[C] = R(A)82STOREAT, // A, B, C // store A into R(B)[C] R(B)[C] = R(A)83STOREG, // A, B // store global G[K(B)] = R(A)84STOREU, // A, B // store upvalue U(B) = R(A)8586// *** JUMP OPERATIONS (3) ***87JUMP, // A // unconditional jump PC += A88JUMPF, // A, B // jump if R(A) is false (R(A) == 0) ? PC += B : 089SWITCH, // // switch statement9091// *** MATH OPERATIONS (19) ***92ADD, // A, B, C // add operation R(A) = R(B) + R(C)93SUB, // A, B, C // sub operation R(A) = R(B) - R(C)94DIV, // A, B, C // div operation R(A) = R(B) / R(C)95MUL, // A, B, C // mul operation R(A) = R(B) * R(C)96REM, // A, B, C // rem operation R(A) = R(B) % R(C)97AND, // A, B, C // and operation R(A) = R(B) && R(C)98OR, // A, B, C // or operation R(A) = R(B) || R(C)99LT, // A, B, C // < comparison R(A) = R(B) < R(C)100GT, // A, B, C // > comparison R(A) = R(B) > R(C)101EQ, // A, B, C // == comparison R(A) = R(B) == R(C)102LEQ, // A, B, C // <= comparison R(A) = R(B) <= R(C)103GEQ, // A, B, C // >= comparison R(A) = R(B) >= R(C)104NEQ, // A, B, C // != comparison R(A) = R(B) != R(C)105EQQ, // A, B, C // === comparison R(A) = R(B) === R(C)106NEQQ, // A, B, C // !== comparison R(A) = R(B) !== R(C)107ISA, // A, B, C // isa comparison R(A) = R(A).class == R(B).class108MATCH, // A, B, C // =~ pattern match R(A) = R(B) =~ R(C)109NEG, // A, B // neg operation R(A) = -R(B)110NOT, // A, B // not operation R(A) = !R(B)111112// *** BIT OPERATIONS (6) ***113LSHIFT, // A, B, C // shift left R(A) = R(B) << R(C)114RSHIFT, // A, B, C // shift right R(A) = R(B) >> R(C)115BAND, // A, B, C // bit and R(A) = R(B) & R(C)116BOR, // A, B, C // bit or R(A) = R(B) | R(C)117BXOR, // A, B, C // bit xor R(A) = R(B) ^ R(C)118BNOT, // A, B // bit not R(A) = ~R(B)119120// *** ARRAY/MAP/RANGE OPERATIONS (4) ***121MAPNEW, // A, B // create a new map R(A) = Alloc a MAP(B)122LISTNEW, // A, B // create a new array R(A) = Alloc a LIST(B)123RANGENEW, // A, B, C, f // create a new range R(A) = Alloc a RANGE(B,C) f flag tells if B inclusive or exclusive124SETLIST, // A, B, C // set list/map items125126// *** CLOSURES (2) ***127CLOSURE, // A, B // create a new closure R(A) = closure(K(B))128CLOSE, // A // close all upvalues from R(A)129130// *** UNUSED (6) ***131RESERVED1, // // reserved for future use132RESERVED2, // // reserved for future use133RESERVED3, // // reserved for future use134RESERVED4, // // reserved for future use135RESERVED5, // // reserved for future use136RESERVED6 // // reserved for future use137} opcode_t;138139#define GRAVITY_LATEST_OPCODE RESERVED6 // used in some debug code so it is very useful to define the latest opcode here140141typedef enum {142GRAVITY_NOTFOUND_INDEX = 0,143GRAVITY_ADD_INDEX,144GRAVITY_SUB_INDEX,145GRAVITY_DIV_INDEX,146GRAVITY_MUL_INDEX,147GRAVITY_REM_INDEX,148GRAVITY_AND_INDEX,149GRAVITY_OR_INDEX,150GRAVITY_CMP_INDEX,151GRAVITY_EQQ_INDEX,152GRAVITY_ISA_INDEX,153GRAVITY_MATCH_INDEX,154GRAVITY_NEG_INDEX,155GRAVITY_NOT_INDEX,156GRAVITY_LSHIFT_INDEX,157GRAVITY_RSHIFT_INDEX,158GRAVITY_BAND_INDEX,159GRAVITY_BOR_INDEX,160GRAVITY_BXOR_INDEX,161GRAVITY_BNOT_INDEX,162GRAVITY_LOAD_INDEX,163GRAVITY_LOADS_INDEX,164GRAVITY_LOADAT_INDEX,165GRAVITY_STORE_INDEX,166GRAVITY_STOREAT_INDEX,167GRAVITY_INT_INDEX,168GRAVITY_FLOAT_INDEX,169GRAVITY_BOOL_INDEX,170GRAVITY_STRING_INDEX,171GRAVITY_EXEC_INDEX,172GRAVITY_VTABLE_SIZE // MUST BE LAST ENTRY IN THIS ENUM173} GRAVITY_VTABLE_INDEX;174175#define GRAVITY_OPERATOR_ADD_NAME "+"176#define GRAVITY_OPERATOR_SUB_NAME "-"177#define GRAVITY_OPERATOR_DIV_NAME "/"178#define GRAVITY_OPERATOR_MUL_NAME "*"179#define GRAVITY_OPERATOR_REM_NAME "%"180#define GRAVITY_OPERATOR_AND_NAME "&&"181#define GRAVITY_OPERATOR_OR_NAME "||"182#define GRAVITY_OPERATOR_CMP_NAME "=="183#define GRAVITY_OPERATOR_EQQ_NAME "==="184#define GRAVITY_OPERATOR_ISA_NAME "isa"185#define GRAVITY_OPERATOR_MATCH_NAME "=~"186#define GRAVITY_OPERATOR_NEG_NAME "neg"187#define GRAVITY_OPERATOR_NOT_NAME "!"188#define GRAVITY_OPERATOR_LSHIFT_NAME "<<"189#define GRAVITY_OPERATOR_RSHIFT_NAME ">>"190#define GRAVITY_OPERATOR_BAND_NAME "&"191#define GRAVITY_OPERATOR_BOR_NAME "|"192#define GRAVITY_OPERATOR_BXOR_NAME "^"193#define GRAVITY_OPERATOR_BNOT_NAME "~"194#define GRAVITY_INTERNAL_LOAD_NAME "load"195#define GRAVITY_INTERNAL_LOADS_NAME "loads"196#define GRAVITY_INTERNAL_STORE_NAME "store"197#define GRAVITY_INTERNAL_LOADAT_NAME "loadat"198#define GRAVITY_INTERNAL_STOREAT_NAME "storeat"199#define GRAVITY_INTERNAL_NOTFOUND_NAME "notfound"200#define GRAVITY_INTERNAL_EXEC_NAME "exec"201#define GRAVITY_INTERNAL_LOOP_NAME "loop"202203#define GRAVITY_CLASS_INT_NAME "Int"204#define GRAVITY_CLASS_FLOAT_NAME "Float"205#define GRAVITY_CLASS_BOOL_NAME "Bool"206#define GRAVITY_CLASS_STRING_NAME "String"207#define GRAVITY_CLASS_OBJECT_NAME "Object"208#define GRAVITY_CLASS_CLASS_NAME "Class"209#define GRAVITY_CLASS_NULL_NAME "Null"210#define GRAVITY_CLASS_FUNCTION_NAME "Function"211#define GRAVITY_CLASS_FIBER_NAME "Fiber"212#define GRAVITY_CLASS_INSTANCE_NAME "Instance"213#define GRAVITY_CLASS_CLOSURE_NAME "Closure"214#define GRAVITY_CLASS_LIST_NAME "List"215#define GRAVITY_CLASS_MAP_NAME "Map"216#define GRAVITY_CLASS_RANGE_NAME "Range"217#define GRAVITY_CLASS_UPVALUE_NAME "Upvalue"218219#define GRAVITY_CLASS_SYSTEM_NAME "System"220#define GRAVITY_SYSTEM_PRINT_NAME "print"221#define GRAVITY_SYSTEM_PUT_NAME "put"222#define GRAVITY_SYSTEM_NANOTIME_NAME "nanotime"223224#endif225226227