aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-28 10:58:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-28 10:58:18 -0200
commitff5fe5104413cf2a5156f86479d4b9b130bad7a6 (patch)
tree7ab4b89eafe1d39962c1aca42d47b40159416854 /lcode.c
parentdfd188ba12f22db8d31cb80426d568e97345e1e2 (diff)
downloadlua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.tar.gz
lua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.tar.bz2
lua-ff5fe5104413cf2a5156f86479d4b9b130bad7a6.zip
using register 'k' for conditions in tests (we only need one bit there)
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/lcode.c b/lcode.c
index 7b50f3cf..04d7b9e0 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.135 2017/11/22 19:15:44 roberto Exp roberto $ 2** $Id: lcode.c,v 2.136 2017/11/23 19:29:04 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -160,8 +160,8 @@ void luaK_ret (FuncState *fs, int first, int nret) {
160** Code a "conditional jump", that is, a test or comparison opcode 160** Code a "conditional jump", that is, a test or comparison opcode
161** followed by a jump. Return jump position. 161** followed by a jump. Return jump position.
162*/ 162*/
163static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { 163static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) {
164 luaK_codeABC(fs, op, A, B, C); 164 luaK_codeABCk(fs, op, A, B, C, k);
165 return luaK_jump(fs); 165 return luaK_jump(fs);
166} 166}
167 167
@@ -206,7 +206,7 @@ static int patchtestreg (FuncState *fs, int node, int reg) {
206 else { 206 else {
207 /* no register to put value or register already has the value; 207 /* no register to put value or register already has the value;
208 change instruction to simple test */ 208 change instruction to simple test */
209 *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i), 0); 209 *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i));
210 } 210 }
211 return 1; 211 return 1;
212} 212}
@@ -969,7 +969,7 @@ static void negatecondition (FuncState *fs, expdesc *e) {
969 Instruction *pc = getjumpcontrol(fs, e->u.info); 969 Instruction *pc = getjumpcontrol(fs, e->u.info);
970 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && 970 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
971 GET_OPCODE(*pc) != OP_TEST); 971 GET_OPCODE(*pc) != OP_TEST);
972 SETARG_B(*pc, !(GETARG_B(*pc))); 972 SETARG_k(*pc, (GETARG_k(*pc) ^ 1));
973} 973}
974 974
975 975
@@ -984,13 +984,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
984 Instruction ie = getinstruction(fs, e); 984 Instruction ie = getinstruction(fs, e);
985 if (GET_OPCODE(ie) == OP_NOT) { 985 if (GET_OPCODE(ie) == OP_NOT) {
986 fs->pc--; /* remove previous OP_NOT */ 986 fs->pc--; /* remove previous OP_NOT */
987 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 987 return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond);
988 } 988 }
989 /* else go through */ 989 /* else go through */
990 } 990 }
991 discharge2anyreg(fs, e); 991 discharge2anyreg(fs, e);
992 freeexp(fs, e); 992 freeexp(fs, e);
993 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); 993 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond);
994} 994}
995 995
996 996
@@ -1276,25 +1276,37 @@ static void codecommutative (FuncState *fs, OpCode op,
1276 1276
1277/* 1277/*
1278** Emit code for order comparisons. 1278** Emit code for order comparisons.
1279** 'e1' was already put in register by 'luaK_infix'. 1279** When the first operand is an integral value in the proper range,
1280** change (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) so that
1281** it can use an immediate operand. In this case, C indicates this
1282** change, for cases that cannot assume a total order (NaN and
1283** metamethods).
1280*/ 1284*/
1281static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { 1285static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1282 int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); 1286 int r1, r2;
1283 int rk2 = luaK_exp2anyreg(fs, e2); 1287 int cond = 1;
1284 freeexps(fs, e1, e2); 1288 int C = 0;
1285 switch (opr) { 1289 lua_Integer im;
1286 case OPR_GT: case OPR_GE: { 1290 if (isSCnumber(e2, &im)) {
1287 /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ 1291 /* use immediate operand */
1288 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); 1292 r1 = luaK_exp2anyreg(fs, e1);
1289 e1->u.info = condjump(fs, op, rk2, 1, rk1); /* invert operands */ 1293 r2 = cast_int(im);
1290 break; 1294 op = cast(OpCode, (op - OP_LT) + OP_LTI);
1291 } 1295 }
1292 default: { /* '==', '<', '<=' use their own opcodes */ 1296 else if (isSCnumber(e1, &im)) {
1293 OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); 1297 /* transform (A < B) to (!(B <= A)) and (A <= B) to (!(B < A)) */
1294 e1->u.info = condjump(fs, op, rk1, 1, rk2); 1298 r1 = luaK_exp2anyreg(fs, e2);
1295 break; 1299 r2 = cast_int(im);
1296 } 1300 op = (op == OP_LT) ? OP_LEI : OP_LTI;
1301 cond = 0; /* negate original test */
1302 C = 1; /* indication that it used the transformations */
1297 } 1303 }
1304 else { /* regular case, compare two registers */
1305 r1 = luaK_exp2anyreg(fs, e1);
1306 r2 = luaK_exp2anyreg(fs, e2);
1307 }
1308 freeexps(fs, e1, e2);
1309 e1->u.info = condjump(fs, op, r1, r2, C, cond);
1298 e1->k = VJMP; 1310 e1->k = VJMP;
1299} 1311}
1300 1312
@@ -1325,7 +1337,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1325 r2 = luaK_exp2anyreg(fs, e2); 1337 r2 = luaK_exp2anyreg(fs, e2);
1326 } 1338 }
1327 freeexps(fs, e1, e2); 1339 freeexps(fs, e1, e2);
1328 e1->u.info = condjump(fs, op, r1, (opr == OPR_EQ), r2); 1340 e1->u.info = condjump(fs, op, r1, r2, 0, (opr == OPR_EQ));
1329 e1->k = VJMP; 1341 e1->k = VJMP;
1330} 1342}
1331 1343
@@ -1385,7 +1397,10 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1385 } 1397 }
1386 case OPR_LT: case OPR_LE: 1398 case OPR_LT: case OPR_LE:
1387 case OPR_GT: case OPR_GE: { 1399 case OPR_GT: case OPR_GE: {
1388 luaK_exp2anyreg(fs, v); 1400 lua_Integer dummy;
1401 if (!isSCnumber(v, &dummy))
1402 luaK_exp2RK(fs, v);
1403 /* else keep numeral, which may be an immediate operand */
1389 break; 1404 break;
1390 } 1405 }
1391 default: lua_assert(0); 1406 default: lua_assert(0);
@@ -1399,9 +1414,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1399** concatenation is right associative), merge second CONCAT into first 1414** concatenation is right associative), merge second CONCAT into first
1400** one. 1415** one.
1401*/ 1416*/
1402void luaK_posfix (FuncState *fs, BinOpr op, 1417void luaK_posfix (FuncState *fs, BinOpr opr,
1403 expdesc *e1, expdesc *e2, int line) { 1418 expdesc *e1, expdesc *e2, int line) {
1404 switch (op) { 1419 switch (opr) {
1405 case OPR_AND: { 1420 case OPR_AND: {
1406 lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ 1421 lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */
1407 luaK_dischargevars(fs, e2); 1422 luaK_dischargevars(fs, e2);
@@ -1432,28 +1447,35 @@ void luaK_posfix (FuncState *fs, BinOpr op,
1432 break; 1447 break;
1433 } 1448 }
1434 case OPR_ADD: case OPR_MUL: { 1449 case OPR_ADD: case OPR_MUL: {
1435 if (!constfolding(fs, op + LUA_OPADD, e1, e2)) 1450 if (!constfolding(fs, opr + LUA_OPADD, e1, e2))
1436 codecommutative(fs, cast(OpCode, op + OP_ADD), e1, e2, line); 1451 codecommutative(fs, cast(OpCode, opr + OP_ADD), e1, e2, line);
1437 break; 1452 break;
1438 } 1453 }
1439 case OPR_SUB: case OPR_DIV: 1454 case OPR_SUB: case OPR_DIV:
1440 case OPR_IDIV: case OPR_MOD: case OPR_POW: { 1455 case OPR_IDIV: case OPR_MOD: case OPR_POW: {
1441 if (!constfolding(fs, op + LUA_OPADD, e1, e2)) 1456 if (!constfolding(fs, opr + LUA_OPADD, e1, e2))
1442 codearith(fs, cast(OpCode, op + OP_ADD), e1, e2, 0, line); 1457 codearith(fs, cast(OpCode, opr + OP_ADD), e1, e2, 0, line);
1443 break; 1458 break;
1444 } 1459 }
1445 case OPR_BAND: case OPR_BOR: case OPR_BXOR: 1460 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1446 case OPR_SHL: case OPR_SHR: { 1461 case OPR_SHL: case OPR_SHR: {
1447 if (!constfolding(fs, op + LUA_OPADD, e1, e2)) 1462 if (!constfolding(fs, opr + LUA_OPADD, e1, e2))
1448 codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); 1463 codebinexpval(fs, cast(OpCode, opr + OP_ADD), e1, e2, line);
1449 break; 1464 break;
1450 } 1465 }
1451 case OPR_EQ: case OPR_NE: { 1466 case OPR_EQ: case OPR_NE: {
1452 codeeq(fs, op, e1, e2); 1467 codeeq(fs, opr, e1, e2);
1468 break;
1469 }
1470 case OPR_LT: case OPR_LE: {
1471 OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
1472 codeorder(fs, op, e1, e2);
1453 break; 1473 break;
1454 } 1474 }
1455 case OPR_LT: case OPR_LE:
1456 case OPR_GT: case OPR_GE: { 1475 case OPR_GT: case OPR_GE: {
1476 /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */
1477 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
1478 swapexps(e1, e2);
1457 codeorder(fs, op, e1, e2); 1479 codeorder(fs, op, e1, e2);
1458 break; 1480 break;
1459 } 1481 }