Removed arithmetic opcodes with immediate operand

The difference in performance between immediate operands and K operands
does not seem to justify all those extra opcodes. We only keep OP_ADDI,
due to its ubiquity and because the difference is a little more relevant.
(Later, OP_SUBI will be implemented by OP_ADDI, negating the constant.)
This commit is contained in:
Roberto Ierusalimschy
2019-09-10 13:20:03 -03:00
parent 4518e5df24
commit 91dad09f65
7 changed files with 17 additions and 65 deletions

14
lcode.c
View File

@@ -1342,7 +1342,7 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
OpCode op, int v2, int flip, int line, OpCode op, int v2, int flip, int line,
OpCode mmop, TMS event) { OpCode mmop, TMS event) {
int v1 = luaK_exp2anyreg(fs, e1); int v1 = luaK_exp2anyreg(fs, e1);
int pc = luaK_codeABCk(fs, op, 0, v1, v2, flip); int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0);
freeexps(fs, e1, e2); freeexps(fs, e1, e2);
e1->u.info = pc; e1->u.info = pc;
e1->k = VRELOC; /* all those operations are relocatable */ e1->k = VRELOC; /* all those operations are relocatable */
@@ -1372,7 +1372,7 @@ static void codebinexpval (FuncState *fs, OpCode op,
/* /*
** Code binary operators ('+', '-', ...) with immediate operands. ** Code binary operators with immediate operands.
*/ */
static void codebini (FuncState *fs, OpCode op, static void codebini (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int flip, int line, expdesc *e1, expdesc *e2, int flip, int line,
@@ -1389,15 +1389,12 @@ static void swapexps (expdesc *e1, expdesc *e2) {
/* /*
** Code arithmetic operators ('+', '-', ...). If second operand is a ** Code arithmetic operators ('+', '-', ...). If second operand is a
** constant in the proper range, use variant opcodes with immediate ** constant in the proper range, use variant opcodes with K operands.
** operands or K operands.
*/ */
static void codearith (FuncState *fs, BinOpr opr, static void codearith (FuncState *fs, BinOpr opr,
expdesc *e1, expdesc *e2, int flip, int line) { expdesc *e1, expdesc *e2, int flip, int line) {
TMS event = cast(TMS, opr + TM_ADD); TMS event = cast(TMS, opr + TM_ADD);
if (isSCint(e2)) /* immediate operand? */ if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */
codebini(fs, cast(OpCode, opr + OP_ADDI), e1, e2, flip, line, event);
else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */
int v2 = e2->u.info; /* K index */ int v2 = e2->u.info; /* K index */
OpCode op = cast(OpCode, opr + OP_ADDK); OpCode op = cast(OpCode, opr + OP_ADDK);
finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
@@ -1423,6 +1420,9 @@ static void codecommutative (FuncState *fs, BinOpr op,
swapexps(e1, e2); /* change order */ swapexps(e1, e2); /* change order */
flip = 1; flip = 1;
} }
if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */
codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD);
else
codearith(fs, op, e1, e2, flip, line); codearith(fs, op, e1, e2, flip, line);
} }

View File

@@ -45,12 +45,6 @@ static void *disptab[NUM_OPCODES] = {
&&L_OP_NEWTABLE, &&L_OP_NEWTABLE,
&&L_OP_SELF, &&L_OP_SELF,
&&L_OP_ADDI, &&L_OP_ADDI,
&&L_OP_SUBI,
&&L_OP_MULI,
&&L_OP_MODI,
&&L_OP_POWI,
&&L_OP_DIVI,
&&L_OP_IDIVI,
&&L_OP_ADDK, &&L_OP_ADDK,
&&L_OP_SUBK, &&L_OP_SUBK,
&&L_OP_MULK, &&L_OP_MULK,

View File

@@ -39,12 +39,6 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVI */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */
,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */

View File

@@ -219,12 +219,6 @@ OP_NEWTABLE,/* A B C R(A) := {} */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C):string] */ OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C):string] */
OP_ADDI,/* A B sC R(A) := R(B) + C */ OP_ADDI,/* A B sC R(A) := R(B) + C */
OP_SUBI,/* A B sC R(A) := R(B) - C */
OP_MULI,/* A B sC R(A) := R(B) * C */
OP_MODI,/* A B sC R(A) := R(B) % C */
OP_POWI,/* A B sC R(A) := R(B) ^ C */
OP_DIVI,/* A B sC R(A) := R(B) / C */
OP_IDIVI,/* A B sC R(A) := R(B) // C */
OP_ADDK,/* A B C R(A) := R(B) + K(C) */ OP_ADDK,/* A B C R(A) := R(B) + K(C) */
OP_SUBK,/* A B C R(A) := R(B) - K(C) */ OP_SUBK,/* A B C R(A) := R(B) - K(C) */

View File

@@ -30,12 +30,6 @@ static const char *const opnames[] = {
"NEWTABLE", "NEWTABLE",
"SELF", "SELF",
"ADDI", "ADDI",
"SUBI",
"MULI",
"MODI",
"POWI",
"DIVI",
"IDIVI",
"ADDK", "ADDK",
"SUBK", "SUBK",
"MULK", "MULK",

24
lvm.c
View File

@@ -1271,30 +1271,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
op_arithI(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i)); op_arithI(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i));
vmbreak; vmbreak;
} }
vmcase(OP_SUBI) {
op_arithI(L, l_subi, luai_numsub, TM_SUB, 0);
vmbreak;
}
vmcase(OP_MULI) {
op_arithI(L, l_muli, luai_nummul, TM_MUL, GETARG_k(i));
vmbreak;
}
vmcase(OP_MODI) {
op_arithI(L, luaV_mod, luaV_modf, TM_MOD, 0);
vmbreak;
}
vmcase(OP_POWI) {
op_arithfI(L, luai_numpow, TM_POW);
vmbreak;
}
vmcase(OP_DIVI) {
op_arithfI(L, luai_numdiv, TM_DIV);
vmbreak;
}
vmcase(OP_IDIVI) {
op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0);
vmbreak;
}
vmcase(OP_ADDK) { vmcase(OP_ADDK) {
op_arithK(L, l_addi, luai_numadd, GETARG_k(i)); op_arithK(L, l_addi, luai_numadd, GETARG_k(i));
vmbreak; vmbreak;

View File

@@ -296,14 +296,14 @@ checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'MMBINI', 'RETURN1')
checkR(function (x) return 128 + x end, 0.0, 128.0, checkR(function (x) return 128 + x end, 0.0, 128.0,
'ADDI', 'MMBINI', 'RETURN1') 'ADDI', 'MMBINI', 'RETURN1')
checkR(function (x) return x * -127 end, -1.0, 127.0, checkR(function (x) return x * -127 end, -1.0, 127.0,
'MULI', 'MMBINI', 'RETURN1') 'MULK', 'MMBINK', 'RETURN1')
checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'MMBINI', 'RETURN1') checkR(function (x) return 20 * x end, 2, 40, 'MULK', 'MMBINK', 'RETURN1')
checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'MMBINI', 'RETURN1') checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWK', 'MMBINK', 'RETURN1')
checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'MMBINI', 'RETURN1') checkR(function (x) return x / 40 end, 40, 1.0, 'DIVK', 'MMBINK', 'RETURN1')
checkR(function (x) return x // 1 end, 10.0, 10.0, checkR(function (x) return x // 1 end, 10.0, 10.0,
'IDIVI', 'MMBINI', 'RETURN1') 'IDIVK', 'MMBINK', 'RETURN1')
checkR(function (x) return x % (100 - 10) end, 91, 1, checkR(function (x) return x % (100 - 10) end, 91, 1,
'MODI', 'MMBINI', 'RETURN1') 'MODK', 'MMBINK', 'RETURN1')
checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'MMBINI', 'RETURN1') checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'MMBINI', 'RETURN1')
checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'MMBINI', 'RETURN1') checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'MMBINI', 'RETURN1')
checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'MMBINI', 'RETURN1') checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'MMBINI', 'RETURN1')
@@ -326,9 +326,9 @@ checkR(function (x) return x % (100.0 - 10) end, 91, 1.0,
-- no foldings (and immediate operands) -- no foldings (and immediate operands)
check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
check(function () return k3/0 end, 'LOADI', 'DIVI', 'MMBINI', 'RETURN1') check(function () return k3/0 end, 'LOADI', 'DIVK', 'MMBINK', 'RETURN1')
check(function () return 0%0 end, 'LOADI', 'MODI', 'MMBINI', 'RETURN1') check(function () return 0%0 end, 'LOADI', 'MODK', 'MMBINK', 'RETURN1')
check(function () return -4//0 end, 'LOADI', 'IDIVI', 'MMBINI', 'RETURN1') check(function () return -4//0 end, 'LOADI', 'IDIVK', 'MMBINK', 'RETURN1')
check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'MMBIN', 'RETURN1') check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'MMBIN', 'RETURN1')
check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1') check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'MMBIN', 'RETURN1')