# lopcodes.h (4.0.1)

```/*
** \$Id: lopcodes.h,v 1.68 2000/10/24 16:05:59 roberto Exp \$
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/

#ifndef lopcodes_h
#define lopcodes_h

#include "llimits.h"

/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits. Moreover,
an instruction can have 0, 1, or 2 arguments. Instructions can
have the following types:
type 0: no arguments
type 1: 1 unsigned argument in the higher bits (called `U')
type 2: 1 signed argument in the higher bits          (`S')
type 3: 1st unsigned argument in the higher bits      (`A')
2nd unsigned argument in the middle bits      (`B')

A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.

The size of each argument is defined in `llimits.h'. The usual is an
instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
with 9 bits, and A arguments with 17 bits (32-6-9). For small
installations, the instruction size can be 16, so U has 10 bits,
and A and B have 5 bits each.
===========================================================================*/

/* creates a mask with `n' 1 bits at position `p' */

/* creates a mask with `n' 0 bits at position `p' */

/*
** the following macros help to manipulate instructions
*/

#define CREATE_0(o)      ((Instruction)(o))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)))

#define CREATE_U(o,u)    ((Instruction)(o) | ((Instruction)(u)<<POS_U))
#define GETARG_U(i)     ((int)((i)>>POS_U))
#define SETARG_U(i,u)   ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
((Instruction)(u)<<POS_U)))

#define CREATE_S(o,s)   CREATE_U((o),(s)+MAXARG_S)
#define GETARG_S(i)     (GETARG_U(i)-MAXARG_S)
#define SETARG_S(i,s)   SETARG_U((i),(s)+MAXARG_S)

#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
|  ((Instruction)(b)<<POS_B))
#define GETARG_A(i)     ((int)((i)>>POS_A))
#define SETARG_A(i,a)   ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
((Instruction)(a)<<POS_A)))
#define SETARG_B(i,b)   ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
((Instruction)(b)<<POS_B)))

/*
** K = U argument used as index to `kstr'
** J = S argument used as jump offset (relative to pc of next instruction)
** L = unsigned argument used as index of local variable
** N = U argument used as index to `knum'
*/

typedef enum {
/*----------------------------------------------------------------------
name            args    stack before    stack after     side effects
------------------------------------------------------------------------*/
OP_RETURN,/*    U       v_n-v_x(at u)   (return)        returns v_x-v_n */

OP_CALL,/*      A B     v_n-v_1 f(at a) r_b-r_1         f(v1,...,v_n)   */
OP_TAILCALL,/*  A B     v_n-v_1 f(at a) (return)        f(v1,...,v_n)   */

OP_PUSHNIL,/*   U       -               nil_1-nil_u                     */
OP_POP,/*       U       a_u-a_1         -                               */

OP_PUSHINT,/*   S       -               (Number)s                       */
OP_PUSHSTRING,/* K      -               KSTR[k]                         */
OP_PUSHNUM,/*   N       -               KNUM[n]                         */
OP_PUSHNEGNUM,/* N      -               -KNUM[n]                        */

OP_PUSHUPVALUE,/* U     -               Closure[u]                      */

OP_GETLOCAL,/*  L       -               LOC[l]                          */
OP_GETGLOBAL,/* K       -               VAR[KSTR[k]]                    */

OP_GETTABLE,/*  -       i t             t[i]                            */
OP_GETDOTTED,/* K       t               t[KSTR[k]]                      */
OP_GETINDEXED,/* L      t               t[LOC[l]]                       */
OP_PUSHSELF,/*  K       t               t t[KSTR[k]]                    */

OP_CREATETABLE,/* U     -               newarray(size = u)              */

OP_SETLOCAL,/*  L       x               -               LOC[l]=x        */
OP_SETGLOBAL,/* K       x               -               VAR[KSTR[k]]=x  */
OP_SETTABLE,/*  A B     v a_a-a_1 i t   (pops b values) t[i]=v          */

OP_SETLIST,/*   A B     v_b-v_1 t       t               t[i+a*FPF]=v_i  */
OP_SETMAP,/*    U       v_u k_u - v_1 k_1 t     t       t[k_i]=v_i      */

OP_ADD,/*       -       y x             x+y                             */
OP_SUB,/*       -       y x             x-y                             */
OP_MULT,/*      -       y x             x*y                             */
OP_DIV,/*       -       y x             x/y                             */
OP_POW,/*       -       y x             x^y                             */
OP_CONCAT,/*    U       v_u-v_1         v1..-..v_u                      */
OP_MINUS,/*     -       x               -x                              */
OP_NOT,/*       -       x               (x==nil)? 1 : nil               */

OP_JMPNE,/*     J       y x             -               (x~=y)? PC+=s   */
OP_JMPEQ,/*     J       y x             -               (x==y)? PC+=s   */
OP_JMPLT,/*     J       y x             -               (x<y)? PC+=s    */
OP_JMPLE,/*     J       y x             -               (x<y)? PC+=s    */
OP_JMPGT,/*     J       y x             -               (x>y)? PC+=s    */
OP_JMPGE,/*     J       y x             -               (x>=y)? PC+=s   */

OP_JMPT,/*      J       x               -               (x~=nil)? PC+=s */
OP_JMPF,/*      J       x               -               (x==nil)? PC+=s */
OP_JMPONT,/*    J       x               (x~=nil)? x : - (x~=nil)? PC+=s */
OP_JMPONF,/*    J       x               (x==nil)? x : - (x==nil)? PC+=s */
OP_JMP,/*       J       -               -               PC+=s           */

OP_PUSHNILJMP,/* -      -               nil             PC++;           */

OP_FORPREP,/*   J                                                       */
OP_FORLOOP,/*   J                                                       */

OP_LFORPREP,/*  J                                                       */
OP_LFORLOOP,/*  J                                                       */

OP_CLOSURE/*    A B     v_b-v_1         closure(KPROTO[a], v_1-v_b)     */

} OpCode;

#define NUM_OPCODES     ((int)OP_CLOSURE+1)

#define ISJUMP(o)       (OP_JMPNE <= (o) && (o) <= OP_JMP)

/* special code to fit a LUA_MULTRET inside an argB */
#define MULT_RET        255     /* (<=MAXARG_B) */
#if MULT_RET>MAXARG_B
#undef MULT_RET
#define MULT_RET        MAXARG_B
#endif

#endif
```