From 762d059a13d83eb367238a6115bbb4f5f13fcb49 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 5 Jun 2001 15:17:01 -0300 Subject: new implementation for the Virtual Machine --- lopcodes.h | 219 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 127 insertions(+), 92 deletions(-) (limited to 'lopcodes.h') diff --git a/lopcodes.h b/lopcodes.h index 3b743880..5819c407 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.71 2001/03/07 13:22:55 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.72 2001/04/06 18:25:00 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -12,29 +12,55 @@ /*=========================================================================== 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') + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits (25-32) + `B' : 8 bits (17-24) + `C' : 10 bits (7-16) + `Bc' : 18 bits (`B' and `C' together) + `sBc' : signed Bc 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. ===========================================================================*/ +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 10 +#define SIZE_B 8 +#define SIZE_Bc (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_C SIZE_OP +#define POS_B (POS_C + SIZE_C) +#define POS_Bc POS_C +#define POS_A (POS_B + SIZE_B) + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in BITS_INT-1 bits (-1 for sign) +*/ +#if SIZE_Bc < BITS_INT-1 +#define MAXARG_Bc ((1<>1) /* `sBc' is signed */ +#else +#define MAXARG_Bc MAX_INT +#define MAXARG_sBc MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_U)) -#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \ - ((Instruction)(u)<>POS_A)) -#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ - ((Instruction)(a)<>POS_B) & MASK1(SIZE_B,0))) #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ ((Instruction)(b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((Instruction)(b)<>POS_Bc) & MASK1(SIZE_Bc,0))) +#define SETARG_Bc(i,b) ((i) = (((i)&MASK0(SIZE_Bc,POS_Bc)) | \ + ((Instruction)(b)< R/K(C)) */ +OP_TESTGE,/* B C test := (R(B) >= R/K(C)) */ -OP_JMPNE,/* J y x - (x~=y)? PC+=s */ -OP_JMPEQ,/* J y x - (x==y)? PC+=s */ -OP_JMPLT,/* J y x - (xy)? PC+=s */ -OP_JMPGE,/* J y x - (x>=y)? PC+=s */ +OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ +OP_TESTF,/* A B test := not R(B); if (test) R(A) := nil */ -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_NILJMP,/* A R(A) := nil; PC++; */ -OP_PUSHNILJMP,/* - - nil PC++; */ +OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(B-1))*/ +OP_RETURN,/* A B return R(A), ... ,R(B-1) (see (3)) */ -OP_FORPREP,/* J */ -OP_FORLOOP,/* J */ +OP_FORPREP,/* A sBc */ +OP_FORLOOP,/* A sBc */ -OP_LFORPREP,/* J */ -OP_LFORLOOP,/* J */ +OP_TFORPREP,/* A sBc */ +OP_TFORLOOP,/* A sBc */ -OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ +OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ +OP_SETLISTO,/* A Bc */ +OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ } OpCode; + #define NUM_OPCODES ((int)OP_CLOSURE+1) -#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) +/*=========================================================================== + Notes: + (1) In the current implementation there is no `test' variable; + instructions OP_TEST* and OP_CJMP must always occur together. + (2) In OP_CALL, if (B == NO_REG) then B = top. C is the number of returns, + and can be NO_REG. OP_CALL always set "top" to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use "top". -/* 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 + (3) In OP_RETURN, if (B == NO_REG) then B = top. +===========================================================================*/ #endif -- cgit v1.2.3-55-g6feb