Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/lua/lopcodes.h @ 2660

Last change on this file since 2660 was 1810, checked in by rgrieder, 16 years ago

merged ceguilua branch back to trunk

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1/*
2** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lopcodes_h
8#define lopcodes_h
9
10#include "llimits.h"
11
12
13/*===========================================================================
14  We assume that instructions are unsigned numbers.
15  All instructions have an opcode in the first 6 bits.
16  Instructions can have the following fields:
17        `A' : 8 bits
18        `B' : 9 bits
19        `C' : 9 bits
20        `Bx' : 18 bits (`B' and `C' together)
21        `sBx' : signed Bx
22
23  A signed argument is represented in excess K; that is, the number
24  value is the unsigned value minus K. K is exactly the maximum value
25  for that argument (so that -max is represented by 0, and +max is
26  represented by 2*max), which is half the maximum for the corresponding
27  unsigned argument.
28===========================================================================*/
29
30
31enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
32
33
34/*
35** size and position of opcode arguments.
36*/
37#define SIZE_C          9
38#define SIZE_B          9
39#define SIZE_Bx         (SIZE_C + SIZE_B)
40#define SIZE_A          8
41
42#define SIZE_OP         6
43
44#define POS_OP          0
45#define POS_A           (POS_OP + SIZE_OP)
46#define POS_C           (POS_A + SIZE_A)
47#define POS_B           (POS_C + SIZE_C)
48#define POS_Bx          POS_C
49
50
51/*
52** limits for opcode arguments.
53** we use (signed) int to manipulate most arguments,
54** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
55*/
56#if SIZE_Bx < LUAI_BITSINT-1
57#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
58#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
59#else
60#define MAXARG_Bx        MAX_INT
61#define MAXARG_sBx        MAX_INT
62#endif
63
64
65#define MAXARG_A        ((1<<SIZE_A)-1)
66#define MAXARG_B        ((1<<SIZE_B)-1)
67#define MAXARG_C        ((1<<SIZE_C)-1)
68
69
70/* creates a mask with `n' 1 bits at position `p' */
71#define MASK1(n,p)      ((~((~(Instruction)0)<<n))<<p)
72
73/* creates a mask with `n' 0 bits at position `p' */
74#define MASK0(n,p)      (~MASK1(n,p))
75
76/*
77** the following macros help to manipulate instructions
78*/
79
80#define GET_OPCODE(i)   (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
81#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82                ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
83
84#define GETARG_A(i)     (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
85#define SETARG_A(i,u)   ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
86                ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
87
88#define GETARG_B(i)     (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
89#define SETARG_B(i,b)   ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
90                ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
91
92#define GETARG_C(i)     (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
93#define SETARG_C(i,b)   ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
94                ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
95
96#define GETARG_Bx(i)    (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
97#define SETARG_Bx(i,b)  ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
98                ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
99
100#define GETARG_sBx(i)   (GETARG_Bx(i)-MAXARG_sBx)
101#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
102
103
104#define CREATE_ABC(o,a,b,c)     ((cast(Instruction, o)<<POS_OP) \
105                        | (cast(Instruction, a)<<POS_A) \
106                        | (cast(Instruction, b)<<POS_B) \
107                        | (cast(Instruction, c)<<POS_C))
108
109#define CREATE_ABx(o,a,bc)      ((cast(Instruction, o)<<POS_OP) \
110                        | (cast(Instruction, a)<<POS_A) \
111                        | (cast(Instruction, bc)<<POS_Bx))
112
113
114/*
115** Macros to operate RK indices
116*/
117
118/* this bit 1 means constant (0 means register) */
119#define BITRK           (1 << (SIZE_B - 1))
120
121/* test whether value is a constant */
122#define ISK(x)          ((x) & BITRK)
123
124/* gets the index of the constant */
125#define INDEXK(r)       ((int)(r) & ~BITRK)
126
127#define MAXINDEXRK      (BITRK - 1)
128
129/* code a constant index as a RK value */
130#define RKASK(x)        ((x) | BITRK)
131
132
133/*
134** invalid register that fits in 8 bits
135*/
136#define NO_REG          MAXARG_A
137
138
139/*
140** R(x) - register
141** Kst(x) - constant (in constant table)
142** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
143*/
144
145
146/*
147** grep "ORDER OP" if you change these enums
148*/
149
150typedef enum {
151/*----------------------------------------------------------------------
152name            args    description
153------------------------------------------------------------------------*/
154OP_MOVE,/*      A B     R(A) := R(B)                                    */
155OP_LOADK,/*     A Bx    R(A) := Kst(Bx)                                 */
156OP_LOADBOOL,/*  A B C   R(A) := (Bool)B; if (C) pc++                    */
157OP_LOADNIL,/*   A B     R(A) := ... := R(B) := nil                      */
158OP_GETUPVAL,/*  A B     R(A) := UpValue[B]                              */
159
160OP_GETGLOBAL,/* A Bx    R(A) := Gbl[Kst(Bx)]                            */
161OP_GETTABLE,/*  A B C   R(A) := R(B)[RK(C)]                             */
162
163OP_SETGLOBAL,/* A Bx    Gbl[Kst(Bx)] := R(A)                            */
164OP_SETUPVAL,/*  A B     UpValue[B] := R(A)                              */
165OP_SETTABLE,/*  A B C   R(A)[RK(B)] := RK(C)                            */
166
167OP_NEWTABLE,/*  A B C   R(A) := {} (size = B,C)                         */
168
169OP_SELF,/*      A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]             */
170
171OP_ADD,/*       A B C   R(A) := RK(B) + RK(C)                           */
172OP_SUB,/*       A B C   R(A) := RK(B) - RK(C)                           */
173OP_MUL,/*       A B C   R(A) := RK(B) * RK(C)                           */
174OP_DIV,/*       A B C   R(A) := RK(B) / RK(C)                           */
175OP_MOD,/*       A B C   R(A) := RK(B) % RK(C)                           */
176OP_POW,/*       A B C   R(A) := RK(B) ^ RK(C)                           */
177OP_UNM,/*       A B     R(A) := -R(B)                                   */
178OP_NOT,/*       A B     R(A) := not R(B)                                */
179OP_LEN,/*       A B     R(A) := length of R(B)                          */
180
181OP_CONCAT,/*    A B C   R(A) := R(B).. ... ..R(C)                       */
182
183OP_JMP,/*       sBx     pc+=sBx                                 */
184
185OP_EQ,/*        A B C   if ((RK(B) == RK(C)) ~= A) then pc++            */
186OP_LT,/*        A B C   if ((RK(B) <  RK(C)) ~= A) then pc++            */
187OP_LE,/*        A B C   if ((RK(B) <= RK(C)) ~= A) then pc++            */
188
189OP_TEST,/*      A C     if not (R(A) <=> C) then pc++                   */ 
190OP_TESTSET,/*   A B C   if (R(B) <=> C) then R(A) := R(B) else pc++     */ 
191
192OP_CALL,/*      A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193OP_TAILCALL,/*  A B C   return R(A)(R(A+1), ... ,R(A+B-1))              */
194OP_RETURN,/*    A B     return R(A), ... ,R(A+B-2)      (see note)      */
195
196OP_FORLOOP,/*   A sBx   R(A)+=R(A+2);
197                        if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198OP_FORPREP,/*   A sBx   R(A)-=R(A+2); pc+=sBx                           */
199
200OP_TFORLOOP,/*  A C     R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
201                        if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++   */ 
202OP_SETLIST,/*   A B C   R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B        */
203
204OP_CLOSE,/*     A       close all variables in the stack up to (>=) R(A)*/
205OP_CLOSURE,/*   A Bx    R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))  */
206
207OP_VARARG/*     A B     R(A), R(A+1), ..., R(A+B-1) = vararg            */
208} OpCode;
209
210
211#define NUM_OPCODES     (cast(int, OP_VARARG) + 1)
212
213
214
215/*===========================================================================
216  Notes:
217  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
218      and can be 0: OP_CALL then sets `top' to last_result+1, so
219      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220
221  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222      set top (like in OP_CALL with C == 0).
223
224  (*) In OP_RETURN, if (B == 0) then return up to `top'
225
226  (*) In OP_SETLIST, if (B == 0) then B = `top';
227      if (C == 0) then next `instruction' is real C
228
229  (*) For comparisons, A specifies what condition the test should accept
230      (true or false).
231
232  (*) All `skips' (pc++) assume that next instruction is a jump
233===========================================================================*/
234
235
236/*
237** masks for instruction properties. The format is:
238** bits 0-1: op mode
239** bits 2-3: C arg mode
240** bits 4-5: B arg mode
241** bit 6: instruction set register A
242** bit 7: operator is a test
243*/ 
244
245enum OpArgMask {
246  OpArgN,  /* argument is not used */
247  OpArgU,  /* argument is used */
248  OpArgR,  /* argument is a register or a jump offset */
249  OpArgK   /* argument is a constant or register/constant */
250};
251
252LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
253
254#define getOpMode(m)    (cast(enum OpMode, luaP_opmodes[m] & 3))
255#define getBMode(m)     (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
256#define getCMode(m)     (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
257#define testAMode(m)    (luaP_opmodes[m] & (1 << 6))
258#define testTMode(m)    (luaP_opmodes[m] & (1 << 7))
259
260
261LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
262
263
264/* number of list items to accumulate before a SETLIST instruction */
265#define LFIELDS_PER_FLUSH       50
266
267
268#endif
Note: See TracBrowser for help on using the repository browser.