aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-10-04 12:49:24 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-10-04 12:49:24 -0300
commit8fbe9e3470295e3b70273fa32ef56459cc0b5201 (patch)
tree21fcdfc75c622f5b015a1fcd131eef1b7701cc5d /lcode.c
parent9ed9f40f1e3674f9ed7ffbe73c0c9718782fe6cd (diff)
downloadlua-8fbe9e3470295e3b70273fa32ef56459cc0b5201.tar.gz
lua-8fbe9e3470295e3b70273fa32ef56459cc0b5201.tar.bz2
lua-8fbe9e3470295e3b70273fa32ef56459cc0b5201.zip
new opcodes with immediate integer operand for all arithmetic operations
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/lcode.c b/lcode.c
index 82bcdcbb..786fd342 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.127 2017/10/01 19:13:43 roberto Exp roberto $ 2** $Id: lcode.c,v 2.128 2017/10/02 22:50:57 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*/
@@ -1171,22 +1171,8 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1171*/ 1171*/
1172static void codebinexpval (FuncState *fs, OpCode op, 1172static void codebinexpval (FuncState *fs, OpCode op,
1173 expdesc *e1, expdesc *e2, int line) { 1173 expdesc *e1, expdesc *e2, int line) {
1174 int v1, v2; 1174 int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */
1175 if (op == OP_ADD && (isKint(e1) || isKint(e2))) { 1175 int v1 = luaK_exp2anyreg(fs, e1);
1176 if (isKint(e2)) {
1177 v2 = cast_int(e2->u.ival);
1178 v1 = luaK_exp2anyreg(fs, e1);
1179 }
1180 else { /* exchange operands to make 2nd one a constant */
1181 v2 = cast_int(e1->u.ival) | BITRK; /* K bit signal the exchange */
1182 v1 = luaK_exp2anyreg(fs, e2);
1183 }
1184 op = OP_ADDI;
1185 }
1186 else {
1187 v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */
1188 v1 = luaK_exp2anyreg(fs, e1);
1189 }
1190 freeexps(fs, e1, e2); 1176 freeexps(fs, e1, e2);
1191 e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ 1177 e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */
1192 e1->k = VRELOCABLE; /* all those operations are relocatable */ 1178 e1->k = VRELOCABLE; /* all those operations are relocatable */
@@ -1195,6 +1181,44 @@ static void codebinexpval (FuncState *fs, OpCode op,
1195 1181
1196 1182
1197/* 1183/*
1184** Code arithmetic operators ('+', '-', ...). If second operand is a
1185** constant in the proper range, use variant opcodes with immediate
1186** operands.
1187*/
1188static void codearith (FuncState *fs, OpCode op,
1189 expdesc *e1, expdesc *e2, int flip, int line) {
1190 if (!isKint(e2))
1191 codebinexpval(fs, op, e1, e2, line); /* use standard operators */
1192 else { /* use immediate operators */
1193 int v2 = cast_int(e2->u.ival); /* immediate operand */
1194 int v1 = luaK_exp2anyreg(fs, e1);
1195 if (flip)
1196 v2 |= BITRK; /* signal that operands were flipped */
1197 op = cast(OpCode, op - OP_ADD + OP_ADDI);
1198 freeexp(fs, e1);
1199 e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */
1200 e1->k = VRELOCABLE; /* all those operations are relocatable */
1201 luaK_fixline(fs, line);
1202 }
1203}
1204
1205
1206/*
1207** Code commutative operators ('+', '*'). If first operand is a
1208** constant, change order of operands to use immediate operator.
1209*/
1210static void codecommutative (FuncState *fs, OpCode op,
1211 expdesc *e1, expdesc *e2, int line) {
1212 int flip = 0;
1213 if (isKint(e1)) {
1214 expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */
1215 flip = 1;
1216 }
1217 codearith(fs, op, e1, e2, flip, line);
1218}
1219
1220
1221/*
1198** Emit code for comparisons. 1222** Emit code for comparisons.
1199** 'e1' was already put in register by 'luaK_infix'. 1223** 'e1' was already put in register by 'luaK_infix'.
1200*/ 1224*/
@@ -1318,8 +1342,17 @@ void luaK_posfix (FuncState *fs, BinOpr op,
1318 } 1342 }
1319 break; 1343 break;
1320 } 1344 }
1321 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 1345 case OPR_ADD: case OPR_MUL: {
1322 case OPR_IDIV: case OPR_MOD: case OPR_POW: 1346 if (!constfolding(fs, op + LUA_OPADD, e1, e2))
1347 codecommutative(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
1348 break;
1349 }
1350 case OPR_SUB: case OPR_DIV:
1351 case OPR_IDIV: case OPR_MOD: case OPR_POW: {
1352 if (!constfolding(fs, op + LUA_OPADD, e1, e2))
1353 codearith(fs, cast(OpCode, op + OP_ADD), e1, e2, 0, line);
1354 break;
1355 }
1323 case OPR_BAND: case OPR_BOR: case OPR_BXOR: 1356 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1324 case OPR_SHL: case OPR_SHR: { 1357 case OPR_SHL: case OPR_SHR: {
1325 if (!constfolding(fs, op + LUA_OPADD, e1, e2)) 1358 if (!constfolding(fs, op + LUA_OPADD, e1, e2))