src/Opcodes.tbl
author David Anderson <dvander@alliedmods.net>
Sat Aug 04 23:26:49 2012 -0700 (2012-08-04)
changeset 152 153d0cafc1fd
parent 147 9c544823d090
child 157 b760e8cb29a8
permissions -rw-r--r--
Support assigning structs.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 // Opcode macros:
    20 //  NAME            NUMBER      TEXT                LENGTH  USES  DEFS   
    21 //
    22 // Type suffixes:
    23 //  I = 32-bit integer
    24 //  F = 32-bit IEEE-754 float
    25 //  O = object reference
    26 
    27 // No operation.
    28 OPDEF(OP_NOP,           0,          "nop",          1,      0,  0)
    29 
    30 // Pushes a signed integer immediate onto the stack.
    31 OPDEF(OP_INT,           1,          "int",          5,      0,  1)    
    32 
    33 // Returns from the current routine, propagating the value at the top of the
    34 // stack to the caller.
    35 OPDEF(OP_RETURN,        2,          "return",       1,      1,  0)
    36 
    37 // Stack transitions for these comparison ops:
    38 // rhs = pop()
    39 // lhs = pop()
    40 // if (lhs COMPARE rhs)
    41 //    goto target (immediate, relative to the beginning of the jump instruction)
    42 OPDEF(OP_JL,            3,          "jl",           5,      2,  0)
    43 OPDEF(OP_JLE,           4,          "jle",          5,      2,  0)
    44 OPDEF(OP_JG,            5,          "jg",           5,      2,  0)
    45 OPDEF(OP_JGE,           6,          "jge",          5,      2,  0)
    46 OPDEF(OP_JEQ,           7,          "jeq",          5,      2,  0)
    47 OPDEF(OP_JNE,           8,          "jne",          5,      2,  0)
    48 
    49 // value = pop()
    50 // if (value == [true, false])
    51 //    goto target
    52 OPDEF(OP_JT,            9,          "jt",           5,      1,  0)
    53 OPDEF(OP_JF,            10,         "jf",           5,      1,  0)
    54 
    55 OPDEF(OP_JL_F,          11,         "jl.f",         5,      2,  0)
    56 OPDEF(OP_JLE_F,         12,         "jle.f",        5,      2,  0)
    57 OPDEF(OP_JG_F,          13,         "jg.f",         5,      2,  0)
    58 OPDEF(OP_JGE_F,         14,         "jge.f",        5,      2,  0)
    59 OPDEF(OP_JEQ_F,         15,         "jeq.f",        5,      2,  0)
    60 OPDEF(OP_JNE_F,         16,         "jne.f",        5,      2,  0)
    61 OPDEF(OP_JT_F,          17,         "jt.f",         5,      1,  0)
    62 OPDEF(OP_JF_F,          18,         "jf.f",         5,      1,  0)
    63 
    64 // Unconditional jump.
    65 OPDEF(OP_JUMP,          19,         "jump",         5,      0,  0)
    66 
    67 // Gets or sets the value of a local variable onto the stack. The local
    68 // variable is given by an immediate index.
    69 OPDEF(OP_GETLOCAL,      20,         "getlocal",     5,      0,  1)
    70 OPDEF(OP_SETLOCAL,      21,         "setlocal",     5,      1,  1)
    71 
    72 // Stack transitions for these binary operators:
    73 // rhs = pop()
    74 // lhs = pop()
    75 // push(lhs OP rhs)
    76 OPDEF(OP_ADD,           22,         "add",          1,      2,  1)
    77 OPDEF(OP_SUB,           23,         "sub",          1,      2,  1)
    78 OPDEF(OP_MUL,           24,         "mul",          1,      2,  1)
    79 OPDEF(OP_DIV,           25,         "div",          1,      2,  1)
    80 OPDEF(OP_MOD,           26,         "mod",          1,      2,  1)
    81 
    82 OPDEF(OP_LT,            27,         "lt",           1,      2,  1)
    83 OPDEF(OP_LE,            28,         "le",           1,      2,  1)
    84 OPDEF(OP_GE,            29,         "ge",           1,      2,  1)
    85 OPDEF(OP_GT,            30,         "gt",           1,      2,  1)
    86 OPDEF(OP_EQ,            31,         "eq",           1,      2,  1)
    87 OPDEF(OP_NE,            32,         "ne",           1,      2,  1)
    88 
    89 OPDEF(OP_NOT,           33,         "not",          1,      1,  1)
    90 OPDEF(OP_NEG,           34,         "neg",          1,      1,  1)
    91 
    92 OPDEF(OP_POP,           35,         "pop",          1,      1,  0)
    93 
    94 // Unconditional terminator placed at the end of code. If a function returns
    95 // void, this acts as a RETURNVOID. Otherwise, it must be unreachable.
    96 OPDEF(OP_STOP,          36,         "stop",         1,      0,  0)
    97 
    98 // Call a function with N arguments. The target function must be the last item
    99 // on the stack.
   100 OPDEF(OP_CALL,          37,         "call",         1,      -1, 1)
   101 
   102 // Similar to GET/LOCAL, except for arguments.
   103 OPDEF(OP_GETARG,        38,         "getarg",       5,      0,  1)
   104 OPDEF(OP_SETARG,        39,         "setarg",       5,      1,  1)
   105 
   106 // Reads or writes an integer element to an unsafe array.
   107 //  index = pop()
   108 //  ref = pop()
   109 //  ref[index]
   110 //
   111 OPDEF(OP_GETARRAY_I,    40,         "getarray.i",   1,      2,  1)
   112 OPDEF(OP_SETARRAY_I,    41,         "setarray.i",   1,      3,  1)
   113 OPDEF(OP_GETARRAY_F,    42,         "getarray.f",   1,      2,  1)
   114 OPDEF(OP_SETARRAY_F,    43,         "setarray.f",   1,      3,  1)
   115 OPDEF(OP_GETARRAY_C,    44,         "getarray.c",   1,      2,  1)
   116 OPDEF(OP_SETARRAY_C,    45,         "setarray.c",   1,      3,  1)
   117 OPDEF(OP_GETARRAY_O,    46,         "getarray.o",   1,      2,  1)
   118 
   119 // Allocate an array. The HeapTenure is stored as a byte following pc. The
   120 // ArrayMap to use is specified as an index into the script's Map table.
   121 //
   122 // Format:
   123 //  [u8 op] [u32 index]
   124 OPDEF(OP_NEWARRAY,      47,         "newarray",     6,      0,  1)
   125 
   126 // Performs a bounds check on an unsafe array.
   127 //
   128 // index = pop()
   129 // array = pop()
   130 // push(array)
   131 // push(index)
   132 OPDEF(OP_BOUNDS,        48,         "bounds",       1,      2,  2)
   133 
   134 // Pushes a 32-bit IEEE-754 floating point immediate onto the stack.
   135 OPDEF(OP_FLOAT,         49,         "float",        5,      0,  1)
   136 
   137 // Converts an integer to a 32-bit IEEE-754 floating point immediate.
   138 OPDEF(OP_CVT_I2F,       50,         "cvt.i2f",      1,      1,  1)
   139 
   140 // Stack transitions for these binary operators:
   141 // rhs = pop()
   142 // lhs = pop()
   143 // push(lhs OP rhs)
   144 OPDEF(OP_ADD_F,         51,         "add.f",        1,      2,  1)
   145 OPDEF(OP_SUB_F,         52,         "sub.f",        1,      2,  1)
   146 OPDEF(OP_MUL_F,         53,         "mul.f",        1,      2,  1)
   147 OPDEF(OP_DIV_F,         54,         "div.f",        1,      2,  1)
   148 OPDEF(OP_UNUSED1,       55,         "unused0",      1,      0,  0)
   149 
   150 OPDEF(OP_LT_F,          56,         "lt.f",         1,      2,  1)
   151 OPDEF(OP_LE_F,          57,         "le.f",         1,      2,  1)
   152 OPDEF(OP_GE_F,          58,         "ge.f",         1,      2,  1)
   153 OPDEF(OP_GT_F,          59,         "gt.f",         1,      2,  1)
   154 OPDEF(OP_EQ_F,          60,         "eq.f",         1,      2,  1)
   155 OPDEF(OP_NE_F,          61,         "ne.f",         1,      2,  1)
   156 
   157 OPDEF(OP_NOT_F,         62,         "not.f",        1,      1,  1)
   158 OPDEF(OP_NEG_F,         63,         "neg.f",        1,      1,  1)
   159 
   160 // Bitwise operators.
   161 OPDEF(OP_SHL,           64,         "shl",          1,      2,  1)
   162 OPDEF(OP_SHR,           65,         "shr",          1,      2,  1)
   163 OPDEF(OP_USHR,          66,         "ushr",         1,      2,  1)
   164 OPDEF(OP_BITAND,        67,         "bitand",       1,      2,  1)
   165 OPDEF(OP_BITOR,         68,         "bitor",        1,      2,  1)
   166 OPDEF(OP_BITXOR,        69,         "bitxor",       1,      2,  1)
   167 OPDEF(OP_BITNOT,        70,         "bitnot",       1,      1,  1)
   168 
   169 // Saves or restores the position of the LIFO heap to/from a local slot.
   170 OPDEF(OP_SAVELIFO,      71,         "savelifo",     5,      0,  0)
   171 OPDEF(OP_UNWINDLIFO,    72,         "unwindlifo",   5,      0,  0)
   172 
   173 // Composes a variable reference to a stack slot or argument.
   174 OPDEF(OP_VARREF_LIFO,   73,         "varref.lifo",  5,      0,  1)
   175 OPDEF(OP_ARGREF_LIFO,   74,         "argref.lifo",  5,      0,  1)
   176 OPDEF(OP_SLOTREF_LIFO,  75,         "slotref.lifo", 1,      1,  1)
   177 OPDEF(OP_ARRAYREF_LIFO, 76,         "arrayref.lifo",1,      2,  1)
   178 OPDEF(OP_GETREF_I,      77,         "getref.i",     1,      1,  1)
   179 OPDEF(OP_SETREF_I,      78,         "setref.i",     1,      2,  1)
   180 OPDEF(OP_GETREF_F,      79,         "getref.f",     1,      1,  1)
   181 OPDEF(OP_SETREF_F,      80,         "setref.f",     1,      2,  1)
   182 
   183 // Pushes an object reference onto the stack.
   184 OPDEF(OP_OBJECT,        81,         "object",       5,      0,  1)
   185 
   186 // Performs an array-to-array assignment.
   187 //   Left = pop()
   188 //   Right = pop()
   189 //   copy(Left, Right)
   190 //   push(Left)
   191 OPDEF(OP_COPYARRAY,     82,         "arraycopy",    1,      2,  1)
   192 
   193 // Duplicates the top item on the stack.
   194 OPDEF(OP_DUP,           83,         "dup",          1,      1,  2)
   195 
   196 // Duplicates the top two items on the stack.
   197 OPDEF(OP_DUP2,          84,         "dup2",         1,      2,  4)
   198 
   199 // Swaps the two items at the top of the stack.
   200 OPDEF(OP_SWAP,          85,         "swap",         1,      2,  2)
   201 
   202 // Roll operation is the same as Forth. It steals a value on the stack,
   203 // shifting all stack values down, and then places the stolen value back at
   204 // the top of the stack.
   205 //
   206 //  p = sp[-3]
   207 //  sp[-3] = sp[-2]
   208 //  sp[-2] = sp[-1]
   209 //  sp[-1] = p
   210 OPDEF(OP_ROLL3,         86,         "roll3",        1,      3, 3)
   211 
   212 // Pick operation is the same as Forth. It pushes a copy of a slot at a
   213 // specific depth.
   214 //
   215 // push(sp[-n])
   216 OPDEF(OP_PICK2,         87,         "pick2",        1,      2, 3)
   217 OPDEF(OP_PICK3,         88,         "pick3",        1,      3, 4)
   218 
   219 // Calls a native function. During the course of calling a native, arguments
   220 // on the stack are re-pushed to match the cell-based native calling
   221 // convention expected by ISourcePawnEngine.
   222 //
   223 // Unlike the normal CALL instruction, natives take truly variadic arguments
   224 // and so we must specify the number of arguments. The format is:
   225 //
   226 // [u8 Opcode] [u32 Index] [u32 ArgCount]
   227 //
   228 OPDEF(OP_CALLNATIVE,    89,         "callnative",   9,      -1, 1)
   229 
   230 // Returns from a function that does return a value.
   231 OPDEF(OP_RETURNVOID,    90,         "returnvoid",   1,      0, 0)
   232 
   233 // Loads the module of the running function.
   234 OPDEF(OP_MODULE,        91,         "module",       1,      0, 1)
   235 
   236 // Loads a function from a module object. The operand is the slot number
   237 // in the module.
   238 OPDEF(OP_GETMODULE_FN,  92,         "getmodule.fn", 5,      1, 1)
   239 
   240 // Opcodes for accessing an environment slot in the global scope.
   241 OPDEF(OP_SETGLOBAL_I,   93,         "setglobal.i",  5,      1, 1)
   242 OPDEF(OP_SETGLOBAL_F,   94,         "setglobal.f",  5,      1, 1)
   243 OPDEF(OP_SETGLOBAL_O,   95,         "setglobal.o",  5,      1, 1)
   244 OPDEF(OP_GETGLOBAL_I,   96,         "getglobal.i",  5,      0, 1)
   245 OPDEF(OP_GETGLOBAL_F,   97,         "getglobal.f",  5,      0, 1)
   246 OPDEF(OP_GETGLOBAL_O,   98,         "getglobal.o",  5,      0, 1)
   247 
   248 // Reinterprets a 32-bit integer as a float, or vice-versa.
   249 OPDEF(OP_BITS_I2F,      99,         "bits.i2f",     1,      1, 1)
   250 OPDEF(OP_BITS_F2I,      100,        "bits.f2i",     1,      1, 1)
   251 
   252 // Pushes a boolean value.
   253 OPDEF(OP_TRUE,          101,        "true",         1,      0, 1)
   254 OPDEF(OP_FALSE,         102,        "false",        1,      0, 1)
   255 
   256 // Allocate a struct. The HeapTenure is stored as a byte following pc. The
   257 // StructMap to use is specified as an index into the script's Map table.
   258 //
   259 // Format:
   260 //  [u8 op] [u32 index]
   261 OPDEF(OP_NEWSTRUCT,     103,        "newstruct",    6,      0, 1)
   262 
   263 // Sets or gets a property in a struct. The index of the field is specified as
   264 // a 32-bit integer. Note that these opcodes follow a new style of deriving
   265 // their types at runtime.
   266 OPDEF(OP_GETFIELD,      104,        "getfield",     5,      1, 1)
   267 OPDEF(OP_SETFIELD,      105,        "setfield",     5,      2, 1)
   268 
   269 // Performs a struct-to-struct assignment.
   270 //   Left = pop()
   271 //   Right = pop()
   272 //   copy(Left, Right)
   273 //   push(Left)
   274 OPDEF(OP_COPYSTRUCT,    106,        "structcopy",   1,      2, 1)
   275