diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-10-04 12:49:24 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-10-04 12:49:24 -0300 |
commit | 8fbe9e3470295e3b70273fa32ef56459cc0b5201 (patch) | |
tree | 21fcdfc75c622f5b015a1fcd131eef1b7701cc5d /lcode.c | |
parent | 9ed9f40f1e3674f9ed7ffbe73c0c9718782fe6cd (diff) | |
download | lua-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.c | 71 |
1 files changed, 52 insertions, 19 deletions
@@ -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 | */ |
1172 | static void codebinexpval (FuncState *fs, OpCode op, | 1172 | static 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 | */ | ||
1188 | static 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 | */ | ||
1210 | static 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)) |