aboutsummaryrefslogtreecommitdiff
path: root/lopcodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'lopcodes.h')
-rw-r--r--lopcodes.h219
1 files changed, 127 insertions, 92 deletions
diff --git a/lopcodes.h b/lopcodes.h
index 3b743880..5819c407 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.71 2001/03/07 13:22:55 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.72 2001/04/06 18:25:00 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -12,29 +12,55 @@
12 12
13/*=========================================================================== 13/*===========================================================================
14 We assume that instructions are unsigned numbers. 14 We assume that instructions are unsigned numbers.
15 All instructions have an opcode in the first 6 bits. Moreover, 15 All instructions have an opcode in the first 6 bits.
16 an instruction can have 0, 1, or 2 arguments. Instructions can 16 Instructions can have the following fields:
17 have the following types: 17 `A' : 8 bits (25-32)
18 type 0: no arguments 18 `B' : 8 bits (17-24)
19 type 1: 1 unsigned argument in the higher bits (called `U') 19 `C' : 10 bits (7-16)
20 type 2: 1 signed argument in the higher bits (`S') 20 `Bc' : 18 bits (`B' and `C' together)
21 type 3: 1st unsigned argument in the higher bits (`A') 21 `sBc' : signed Bc
22 2nd unsigned argument in the middle bits (`B')
23 22
24 A signed argument is represented in excess K; that is, the number 23 A signed argument is represented in excess K; that is, the number
25 value is the unsigned value minus K. K is exactly the maximum value 24 value is the unsigned value minus K. K is exactly the maximum value
26 for that argument (so that -max is represented by 0, and +max is 25 for that argument (so that -max is represented by 0, and +max is
27 represented by 2*max), which is half the maximum for the corresponding 26 represented by 2*max), which is half the maximum for the corresponding
28 unsigned argument. 27 unsigned argument.
29
30 The size of each argument is defined in `llimits.h'. The usual is an
31 instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
32 with 9 bits, and A arguments with 17 bits (32-6-9). For small
33 installations, the instruction size can be 16, so U has 10 bits,
34 and A and B have 5 bits each.
35===========================================================================*/ 28===========================================================================*/
36 29
37 30
31/*
32** size and position of opcode arguments.
33*/
34#define SIZE_C 10
35#define SIZE_B 8
36#define SIZE_Bc (SIZE_C + SIZE_B)
37#define SIZE_A 8
38
39#define SIZE_OP 6
40
41#define POS_C SIZE_OP
42#define POS_B (POS_C + SIZE_C)
43#define POS_Bc POS_C
44#define POS_A (POS_B + SIZE_B)
45
46
47/*
48** limits for opcode arguments.
49** we use (signed) int to manipulate most arguments,
50** so they must fit in BITS_INT-1 bits (-1 for sign)
51*/
52#if SIZE_Bc < BITS_INT-1
53#define MAXARG_Bc ((1<<SIZE_Bc)-1)
54#define MAXARG_sBc (MAXARG_Bc>>1) /* `sBc' is signed */
55#else
56#define MAXARG_Bc MAX_INT
57#define MAXARG_sBc MAX_INT
58#endif
59
60
61#define MAXARG_A ((1<<SIZE_A)-1)
62#define MAXARG_B ((1<<SIZE_B)-1)
63#define MAXARG_C ((1<<SIZE_C)-1)
38 64
39 65
40/* creates a mask with `n' 1 bits at position `p' */ 66/* creates a mask with `n' 1 bits at position `p' */
@@ -47,120 +73,129 @@
47** the following macros help to manipulate instructions 73** the following macros help to manipulate instructions
48*/ 74*/
49 75
50#define CREATE_0(o) ((Instruction)(o))
51#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0))) 76#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
52#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o))) 77#define SET_OPCODE(i,o) (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o))
53
54#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U))
55#define GETARG_U(i) ((int)((i)>>POS_U))
56#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
57 ((Instruction)(u)<<POS_U)))
58 78
59#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S)
60#define GETARG_S(i) (GETARG_U(i)-MAXARG_S)
61#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S)
62
63
64#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
65 | ((Instruction)(b)<<POS_B))
66#define GETARG_A(i) ((int)((i)>>POS_A)) 79#define GETARG_A(i) ((int)((i)>>POS_A))
67#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ 80#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
68 ((Instruction)(a)<<POS_A))) 81 ((Instruction)(u)<<POS_A)))
82
69#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0))) 83#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
70#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ 84#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
71 ((Instruction)(b)<<POS_B))) 85 ((Instruction)(b)<<POS_B)))
72 86
87#define GETARG_C(i) ((int)(((i)>>POS_C) & MASK1(SIZE_C,0)))
88#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
89 ((Instruction)(b)<<POS_C)))
90
91#define GETARG_Bc(i) ((int)(((i)>>POS_Bc) & MASK1(SIZE_Bc,0)))
92#define SETARG_Bc(i,b) ((i) = (((i)&MASK0(SIZE_Bc,POS_Bc)) | \
93 ((Instruction)(b)<<POS_Bc)))
94
95#define GETARG_sBc(i) (GETARG_Bc(i)-MAXARG_sBc)
96#define SETARG_sBc(i,b) SETARG_Bc((i),(b)+MAXARG_sBc)
97
98
99#define CREATE_ABC(o,a,b,c) ((Instruction)(o) \
100 | ((Instruction)(a)<<POS_A) \
101 | ((Instruction)(b)<<POS_B) \
102 | ((Instruction)(c)<<POS_C))
103
104#define CREATE_ABc(o,a,bc) ((Instruction)(o) \
105 | ((Instruction)(a)<<POS_A) \
106 | ((Instruction)(bc)<<POS_Bc))
107
108
109
73 110
74/* 111/*
75** K = U argument used as index to `kstr' 112** an invalid register that fits in 8 bits
76** J = S argument used as jump offset (relative to pc of next instruction) 113*/
77** L = unsigned argument used as index of local variable 114#define NO_REG MAXARG_A
78** N = U argument used as index to `knum' 115
116
117/*
118** R(x) - register
119** Kst(x) - constant (in constant table)
120** R/K(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
79*/ 121*/
80 122
81typedef enum { 123typedef enum {
82/*---------------------------------------------------------------------- 124/*----------------------------------------------------------------------
83name args stack before stack after side effects 125name args description
84------------------------------------------------------------------------*/ 126------------------------------------------------------------------------*/
85OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */ 127OP_MOVE,/* A B R(A) := R(B) */
86 128OP_LOADK,/* A Bc R(A) := Kst(Bc) */
87OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */ 129OP_LOADINT,/* A sBc R(A) := (Number)sBc */
88 130OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
89OP_PUSHNIL,/* U - nil_1-nil_u */ 131OP_LOADUPVAL,/* A Bc R(A) := UpValue[Bc] */
90OP_POP,/* U a_u-a_1 - */
91 132
92OP_PUSHINT,/* S - (lua_Number)s */ 133OP_GETGLOBAL,/* A Bc R(A) := Gbl[Kst(Bc)] */
93OP_PUSHSTRING,/* K - KSTR[k] */ 134OP_GETTABLE,/* A B C R(A) := R(B)[R/K(C)] */
94OP_PUSHNUM,/* N - KNUM[n] */
95OP_PUSHNEGNUM,/* N - -KNUM[n] */
96 135
97OP_PUSHUPVALUE,/* U - Closure[u] */ 136OP_SETGLOBAL,/* A Bc Gbl[Kst(Bc)] := R(A) */
137OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */
98 138
99OP_GETLOCAL,/* L - LOC[l] */ 139OP_NEWTABLE,/* A Bc R(A) := {} (size = Bc) */
100OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
101 140
102OP_GETTABLE,/* - i t t[i] */ 141OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[R/K(C)] */
103OP_GETDOTTED,/* K t t[KSTR[k]] */
104OP_GETINDEXED,/* L t t[LOC[l]] */
105OP_PUSHSELF,/* K t t t[KSTR[k]] */
106 142
107OP_CREATETABLE,/* U - newarray(size = u) */ 143OP_ADD,/* A B C R(A) := R(B) + R/K(C) */
144OP_SUB,/* A B C R(A) := R(B) - R/K(C) */
145OP_MUL,/* A B C R(A) := R(B) * R/K(C) */
146OP_DIV,/* A B C R(A) := R(B) / R/K(C) */
147OP_POW,/* A B C R(A) := R(B) ^ R/K(C) */
148OP_UNM,/* A B R(A) := -R(B) */
149OP_NOT,/* A B R(A) := not R(B) */
108 150
109OP_SETLOCAL,/* L x - LOC[l]=x */ 151OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
110OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
111OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
112 152
113OP_SETLIST,/* A B v_n-v_1 v_b v_b v_b[i+a*FPF]=v_i */ 153OP_JMP,/* sBc PC += sBc */
114OP_SETMAP,/* U v_n k_n - v_1 k_1 v_u v_u v_u[k_i]=v_i */ 154OP_CJMP,/* sBc if test then PC += sBc (see (1)) */
115 155
116OP_ADD,/* - y x x+y */ 156OP_TESTEQ,/* B C test := (R(B) == R/K(C)) */
117OP_ADDI,/* S x x+s */ 157OP_TESTNE,/* B C test := (R(B) ~= R/K(C)) */
118OP_SUB,/* - y x x-y */ 158OP_TESTLT,/* B C test := (R(B) < R/K(C)) */
119OP_MULT,/* - y x x*y */ 159OP_TESTLE,/* B C test := (R(B) <= R/K(C)) */
120OP_DIV,/* - y x x/y */ 160OP_TESTGT,/* B C test := (R(B) > R/K(C)) */
121OP_POW,/* - y x x^y */ 161OP_TESTGE,/* B C test := (R(B) >= R/K(C)) */
122OP_CONCAT,/* U v_u-v_1 v1..-..v_u */
123OP_MINUS,/* - x -x */
124OP_NOT,/* - x (x==nil)? 1 : nil */
125 162
126OP_JMPNE,/* J y x - (x~=y)? PC+=s */ 163OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */
127OP_JMPEQ,/* J y x - (x==y)? PC+=s */ 164OP_TESTF,/* A B test := not R(B); if (test) R(A) := nil */
128OP_JMPLT,/* J y x - (x<y)? PC+=s */
129OP_JMPLE,/* J y x - (x<y)? PC+=s */
130OP_JMPGT,/* J y x - (x>y)? PC+=s */
131OP_JMPGE,/* J y x - (x>=y)? PC+=s */
132 165
133OP_JMPT,/* J x - (x~=nil)? PC+=s */ 166OP_NILJMP,/* A R(A) := nil; PC++; */
134OP_JMPF,/* J x - (x==nil)? PC+=s */
135OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */
136OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */
137OP_JMP,/* J - - PC+=s */
138 167
139OP_PUSHNILJMP,/* - - nil PC++; */ 168OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(B-1))*/
169OP_RETURN,/* A B return R(A), ... ,R(B-1) (see (3)) */
140 170
141OP_FORPREP,/* J */ 171OP_FORPREP,/* A sBc */
142OP_FORLOOP,/* J */ 172OP_FORLOOP,/* A sBc */
143 173
144OP_LFORPREP,/* J */ 174OP_TFORPREP,/* A sBc */
145OP_LFORLOOP,/* J */ 175OP_TFORLOOP,/* A sBc */
146 176
147OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ 177OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */
178OP_SETLISTO,/* A Bc */
148 179
180OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */
149} OpCode; 181} OpCode;
150 182
183
151#define NUM_OPCODES ((int)OP_CLOSURE+1) 184#define NUM_OPCODES ((int)OP_CLOSURE+1)
152 185
153 186
154#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
155 187
188/*===========================================================================
189 Notes:
190 (1) In the current implementation there is no `test' variable;
191 instructions OP_TEST* and OP_CJMP must always occur together.
156 192
193 (2) In OP_CALL, if (B == NO_REG) then B = top. C is the number of returns,
194 and can be NO_REG. OP_CALL always set "top" to last_result+1, so
195 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use "top".
157 196
158/* special code to fit a LUA_MULTRET inside an argB */ 197 (3) In OP_RETURN, if (B == NO_REG) then B = top.
159#define MULT_RET 255 /* (<=MAXARG_B) */ 198===========================================================================*/
160#if MULT_RET>MAXARG_B
161#undef MULT_RET
162#define MULT_RET MAXARG_B
163#endif
164 199
165 200
166#endif 201#endif