From 212095a601ee68e99065b553f7b6bc216056d82e Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 21 Feb 2018 12:49:32 -0300 Subject: [PATCH] new opcodes OP_GTI/OP_GEI --- lcode.c | 30 ++++++++++++------------------ lopcodes.c | 6 +++++- lopcodes.h | 9 +++------ ltm.c | 5 ++--- lvm.c | 45 ++++++++++++++++++++++++++++----------------- 5 files changed, 50 insertions(+), 45 deletions(-) diff --git a/lcode.c b/lcode.c index c182794e..30bf13d8 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.155 2018/02/17 19:20:00 roberto Exp roberto $ +** $Id: lcode.c,v 2.156 2018/02/21 12:54:26 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -171,8 +171,8 @@ void luaK_ret (FuncState *fs, int first, int nret) { ** Code a "conditional jump", that is, a test or comparison opcode ** followed by a jump. Return jump position. */ -static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { - luaK_codeABCk(fs, op, A, B, C, k); +static int condjump (FuncState *fs, OpCode op, int A, int B, int k) { + luaK_codeABCk(fs, op, A, B, 0, k); return luaK_jump(fs); } @@ -979,13 +979,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { Instruction ie = getinstruction(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ - return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); } /* else go through */ } discharge2anyreg(fs, e); freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); } @@ -1338,16 +1338,12 @@ static void codeshift (FuncState *fs, OpCode op, /* ** Emit code for order comparisons. -** When the first operand is an integral value in the proper range, -** change (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) so that -** it can use an immediate operand. In this case, C indicates this -** change, for cases that cannot assume a total order (NaN and -** metamethods). +** When the first operand A is an integral value in the proper range, +** change (A < B) to (B > A) and (A <= B) to (B >= A) so that +** it can use an immediate operand. */ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { int r1, r2; - int cond = 1; - int C = 0; lua_Integer im; if (isSCnumber(e2, &im)) { /* use immediate operand */ @@ -1356,19 +1352,17 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { op = cast(OpCode, (op - OP_LT) + OP_LTI); } else if (isSCnumber(e1, &im)) { - /* transform (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) */ + /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ r1 = luaK_exp2anyreg(fs, e2); r2 = cast_int(im); - op = (op == OP_LT) ? OP_LEI : OP_LTI; - cond = 0; /* negate original test */ - C = 1; /* indication that it used the transformations */ + op = (op == OP_LT) ? OP_GTI : OP_GEI; } else { /* regular case, compare two registers */ r1 = luaK_exp2anyreg(fs, e1); r2 = luaK_exp2anyreg(fs, e2); } freeexps(fs, e1, e2); - e1->u.info = condjump(fs, op, r1, r2, C, cond); + e1->u.info = condjump(fs, op, r1, r2, 1); e1->k = VJMP; } @@ -1399,7 +1393,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { r2 = luaK_exp2anyreg(fs, e2); } freeexps(fs, e1, e2); - e1->u.info = condjump(fs, op, r1, r2, 0, (opr == OPR_EQ)); + e1->u.info = condjump(fs, op, r1, r2, (opr == OPR_EQ)); e1->k = VJMP; } diff --git a/lopcodes.c b/lopcodes.c index aa3055be..79d77cc1 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.77 2018/02/09 15:16:06 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.78 2018/02/15 15:34:29 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -75,6 +75,8 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { "EQI", "LTI", "LEI", + "GTI", + "GEI", "TEST", "TESTSET", "CALL", @@ -156,6 +158,8 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 0, 1, 0, iABC) /* OP_EQI */ ,opmode(0, 0, 1, 0, iABC) /* OP_LTI */ ,opmode(0, 0, 1, 0, iABC) /* OP_LEI */ + ,opmode(0, 0, 1, 0, iABC) /* OP_GTI */ + ,opmode(0, 0, 1, 0, iABC) /* OP_GEI */ ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */ ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */ ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ diff --git a/lopcodes.h b/lopcodes.h index b2e22c27..be7359e9 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.187 2018/02/09 15:16:06 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.188 2018/02/15 15:34:29 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -260,6 +260,8 @@ OP_EQK,/* A B if ((R(A) == K(B)) ~= k) then pc++ */ OP_EQI,/* A sB if ((R(A) == sB) ~= k) then pc++ */ OP_LTI,/* A sB if ((R(A) < sB) ~= k) then pc++ */ OP_LEI,/* A sB if ((R(A) <= sB) ~= k) then pc++ */ +OP_GTI,/* A sB if ((R(A) > sB) ~= k) then pc++ */ +OP_GEI,/* A sB if ((R(A) >= sB) ~= k) then pc++ */ OP_TEST,/* A if (not R(A) == k) then pc++ */ OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */ @@ -317,11 +319,6 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ (*) For comparisons, k specifies what condition the test should accept (true or false). - (*) For OP_LTI/OP_LEI, C indicates that the transformations - (A (!(B<=A)) or (A<=B) => (!(Btop - 1)); L->top--; if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ - lua_assert(op == OP_LE || - (op == OP_LTI && GETARG_C(inst)) || - (op == OP_LEI && !GETARG_C(inst))); ci->callstatus ^= CIST_LEQ; /* clear mark */ res = !res; /* negate result */ } lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); - if (GETARG_C(inst)) res = !res; if (res != GETARG_k(inst)) /* condition failed? */ ci->u.l.savedpc++; /* skip jump instruction */ break; @@ -1473,26 +1470,40 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int im = GETARG_sB(i); if (ttisinteger(vra)) cond = (ivalue(vra) < im); - else if (ttisfloat(vra)) { - lua_Number f = fltvalue(vra); - cond = (!luai_numisnan(f)) ? luai_numlt(f, cast_num(im)) - : GETARG_C(i); /* NaN */ - } + else if (ttisfloat(vra)) + cond = luai_numlt(fltvalue(vra), cast_num(im)); else - Protect(cond = luaT_callorderiTM(L, vra, im, GETARG_C(i), TM_LT)); + Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LT)); goto condjump; } vmcase(OP_LEI) { int im = GETARG_sB(i); if (ttisinteger(vra)) cond = (ivalue(vra) <= im); - else if (ttisfloat(vra)) { - lua_Number f = fltvalue(vra); - cond = (!luai_numisnan(f)) ? luai_numle(f, cast_num(im)) - : GETARG_C(i); /* NaN? */ - } + else if (ttisfloat(vra)) + cond = luai_numle(fltvalue(vra), cast_num(im)); else - Protect(cond = luaT_callorderiTM(L, vra, im, GETARG_C(i), TM_LE)); + Protect(cond = luaT_callorderiTM(L, vra, im, 0, TM_LE)); + goto condjump; + } + vmcase(OP_GTI) { + int im = GETARG_sB(i); + if (ttisinteger(vra)) + cond = (im < ivalue(vra)); + else if (ttisfloat(vra)) + cond = luai_numlt(cast_num(im), fltvalue(vra)); + else + Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LT)); + goto condjump; + } + vmcase(OP_GEI) { + int im = GETARG_sB(i); + if (ttisinteger(vra)) + cond = (im <= ivalue(vra)); + else if (ttisfloat(vra)) + cond = luai_numle(cast_num(im), fltvalue(vra)); + else + Protect(cond = luaT_callorderiTM(L, vra, im, 1, TM_LE)); goto condjump; } vmcase(OP_TEST) {