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