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)) |
