Added opcodes for arithmetic with K operands

Added opcodes for all seven arithmetic operators with K operands
(that is, operands that are numbers in the array of constants of
the function). They cover the cases of constant float operands
(e.g., 'x + .0.0', 'x^0.5') and large integer operands (e.g.,
'x % 10000').
diff --git a/lcode.c b/lcode.c
index 054b28f..1872ede 100644
--- a/lcode.c
+++ b/lcode.c
@@ -371,10 +371,6 @@
 }
 
 
-#define codeABsC(fs,o,a,b,c,k)	luaK_codeABCk(fs,o,a,b,((c) + OFFSET_sC),k)
-
-
-
 /*
 ** Format and emit an 'iABx' instruction.
 */
@@ -885,30 +881,45 @@
 
 
 /*
+** Try to make 'e' a K expression with an index in the range of R/K
+** indices. Return true iff succeeded.
+*/
+static int luaK_exp2K (FuncState *fs, expdesc *e) {
+  if (!hasjumps(e)) {
+    int info;
+    switch (e->k) {  /* move constants to 'k' */
+      case VTRUE: info = boolK(fs, 1); break;
+      case VFALSE: info = boolK(fs, 0); break;
+      case VNIL: info = nilK(fs); break;
+      case VKINT: info = luaK_intK(fs, e->u.ival); break;
+      case VKFLT: info = luaK_numberK(fs, e->u.nval); break;
+      case VK: info = e->u.info; break;
+      default: return 0;  /* not a constant */
+    }
+    if (info <= MAXINDEXRK) {  /* does constant fit in 'argC'? */
+      e->k = VK;  /* make expression a 'K' expression */
+      e->u.info = info;
+      return 1;
+    }
+  }
+  /* else, expression doesn't fit; leave it unchanged */
+  return 0;
+}
+
+
+/*
 ** Ensures final expression result is in a valid R/K index
 ** (that is, it is either in a register or in 'k' with an index
 ** in the range of R/K indices).
-** Returns 1 if expression is K, 0 otherwise.
+** Returns 1 iff expression is K.
 */
 int luaK_exp2RK (FuncState *fs, expdesc *e) {
-  luaK_exp2val(fs, e);
-  switch (e->k) {  /* move constants to 'k' */
-    case VTRUE: e->u.info = boolK(fs, 1); goto vk;
-    case VFALSE: e->u.info = boolK(fs, 0); goto vk;
-    case VNIL: e->u.info = nilK(fs); goto vk;
-    case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
-    case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
-    case VK:
-     vk:
-      e->k = VK;
-      if (e->u.info <= MAXINDEXRK)  /* constant fits in 'argC'? */
-        return 1;
-      else break;
-    default: break;
+  if (luaK_exp2K(fs, e))
+    return 1;
+  else {  /* not a constant in the right range: put it in a register */
+    luaK_exp2anyreg(fs, e);
+    return 0;
   }
-  /* not a constant in the right range: put it in a register */
-  luaK_exp2anyreg(fs, e);
-  return 0;
 }
 
 
@@ -1232,15 +1243,6 @@
 }
 
 
-static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
-                             int pc, int line) {
-  freeexps(fs, e1, e2);
-  e1->u.info = pc;
-  e1->k = VRELOC;  /* all those operations are relocatable */
-  luaK_fixline(fs, line);
-}
-
-
 /*
 ** Emit code for binary expressions that "produce values"
 ** (everything but logical operators 'and'/'or' and comparison
@@ -1250,12 +1252,25 @@
 ** in "stack order" (that is, first on 'e2', which may have more
 ** recent registers to be released).
 */
+static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
+                             OpCode op, int v2, int k, int line) {
+  int v1 = luaK_exp2anyreg(fs, e1);
+  int pc = luaK_codeABCk(fs, op, 0, v1, v2, k);
+  freeexps(fs, e1, e2);
+  e1->u.info = pc;
+  e1->k = VRELOC;  /* all those operations are relocatable */
+  luaK_fixline(fs, line);
+}
+
+
+/*
+** Emit code for binary expressions that "produce values" over
+** two registers.
+*/
 static void codebinexpval (FuncState *fs, OpCode op,
                            expdesc *e1, expdesc *e2, int line) {
   int v2 = luaK_exp2anyreg(fs, e2);  /* both operands are in registers */
-  int v1 = luaK_exp2anyreg(fs, e1);
-  int pc = luaK_codeABC(fs, op, 0, v1, v2);  /* generate opcode */
-  finishbinexpval(fs, e1, e2, pc, line);
+  finishbinexpval(fs, e1, e2, op, v2, 0, line);
 }
 
 
@@ -1264,24 +1279,8 @@
 */
 static void codebini (FuncState *fs, OpCode op,
                        expdesc *e1, expdesc *e2, int k, int line) {
-  int v2 = cast_int(e2->u.ival);  /* immediate operand */
-  int v1 = luaK_exp2anyreg(fs, e1);
-  int pc = codeABsC(fs, op, 0, v1, v2, k);  /* generate opcode */
-  finishbinexpval(fs, e1, e2, pc, line);
-}
-
-
-/*
-** Code arithmetic operators ('+', '-', ...). If second operand is a
-** constant in the proper range, use variant opcodes with immediate
-** operands.
-*/
-static void codearith (FuncState *fs, OpCode op,
-                       expdesc *e1, expdesc *e2, int flip, int line) {
-  if (!isSCint(e2))
-    codebinexpval(fs, op, e1, e2, line);  /* use standard operators */
-  else  /* use immediate operators */
-    codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line);
+  int v2 = cast_int(e2->u.ival) + OFFSET_sC;  /* immediate operand */
+  finishbinexpval(fs, e1, e2, op, v2, k, line);
 }
 
 
@@ -1291,14 +1290,37 @@
 
 
 /*
+** Code arithmetic operators ('+', '-', ...). If second operand is a
+** constant in the proper range, use variant opcodes with immediate
+** operands or K operands.
+*/
+static void codearith (FuncState *fs, OpCode op,
+                       expdesc *e1, expdesc *e2, int flip, int line) {
+  if (isSCint(e2))  /* immediate operand? */
+    codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line);
+  else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) {  /* K operand? */
+    int v2 = e2->u.info;  /* K index */
+    op = cast(OpCode, op - OP_ADD + OP_ADDK);
+    finishbinexpval(fs, e1, e2, op, v2, flip, line);
+  }
+  else {  /* 'e2' is neither an immediate nor a K operand */
+    if (flip)
+      swapexps(e1, e2);  /* back to original order */
+    codebinexpval(fs, op, e1, e2, line);  /* use standard operators */
+  }
+}
+
+
+/*
 ** Code commutative operators ('+', '*'). If first operand is a
-** constant, change order of operands to use immediate operator.
+** numeric constant, change order of operands to try to use an
+** immediate or K operator.
 */
 static void codecommutative (FuncState *fs, OpCode op,
                              expdesc *e1, expdesc *e2, int line) {
   int flip = 0;
-  if (isSCint(e1)) {
-    swapexps(e1, e2);
+  if (tonumeral(e1, NULL)) {  /* is first operand a numeric constant? */
+    swapexps(e1, e2);  /* change order */
     flip = 1;
   }
   codearith(fs, op, e1, e2, flip, line);
@@ -1312,7 +1334,7 @@
 static void codebitwise (FuncState *fs, BinOpr opr,
                          expdesc *e1, expdesc *e2, int line) {
   int inv = 0;
-  int v1, v2, pc;
+  int v2;
   OpCode op;
   if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
     swapexps(e1, e2);  /* 'e2' will be the constant operand */
@@ -1323,12 +1345,10 @@
     codebinexpval(fs, op, e1, e2, line);  /* all-register opcodes */
     return;
   }
-  v1 = luaK_exp2anyreg(fs, e1);
   v2 = e2->u.info;  /* index in K array */
   op = cast(OpCode, opr - OPR_BAND + OP_BANDK);
   lua_assert(ttisinteger(&fs->f->k[v2]));
-  pc = luaK_codeABCk(fs, op, 0, v1, v2, inv);
-  finishbinexpval(fs, e1, e2, pc, line);
+  finishbinexpval(fs, e1, e2, op, v2, inv, line);
 }
 
 
diff --git a/ldebug.c b/ldebug.c
index ee1b87d..766a523 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -610,12 +610,18 @@
       tm = TM_NEWINDEX;
       break;
     case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI:
-    case OP_POWI: case OP_DIVI: case OP_IDIVI:
-    case OP_BANDK: case OP_BORK: case OP_BXORK: {
+    case OP_POWI: case OP_DIVI: case OP_IDIVI: {
       int offset = GET_OPCODE(i) - OP_ADDI;  /* ORDER OP */
       tm = cast(TMS, offset + TM_ADD);  /* ORDER TM */
       break;
     }
+    case OP_ADDK: case OP_SUBK: case OP_MULK: case OP_MODK:
+    case OP_POWK: case OP_DIVK: case OP_IDIVK:
+    case OP_BANDK: case OP_BORK: case OP_BXORK: {
+      int offset = GET_OPCODE(i) - OP_ADDK;  /* ORDER OP */
+      tm = cast(TMS, offset + TM_ADD);  /* ORDER TM */
+      break;
+    }
     case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
     case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
     case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
diff --git a/ljumptab.h b/ljumptab.h
index 6767e95..0af997d 100644
--- a/ljumptab.h
+++ b/ljumptab.h
@@ -51,6 +51,13 @@
 &&L_OP_POWI,
 &&L_OP_DIVI,
 &&L_OP_IDIVI,
+&&L_OP_ADDK,
+&&L_OP_SUBK,
+&&L_OP_MULK,
+&&L_OP_MODK,
+&&L_OP_POWK,
+&&L_OP_DIVK,
+&&L_OP_IDIVK,
 &&L_OP_BANDK,
 &&L_OP_BORK,
 &&L_OP_BXORK,
diff --git a/lopcodes.c b/lopcodes.c
index 11a73c2..3f0d551 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -45,6 +45,13 @@
  ,opmode(0, 0, 0, 1, iABC)		/* OP_POWI */
  ,opmode(0, 0, 0, 1, iABC)		/* OP_DIVI */
  ,opmode(0, 0, 0, 1, iABC)		/* OP_IDIVI */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_ADDK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_SUBK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_MULK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_MODK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_POWK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_DIVK */
+ ,opmode(0, 0, 0, 1, iABC)		/* OP_IDIVK */
  ,opmode(0, 0, 0, 1, iABC)		/* OP_BANDK */
  ,opmode(0, 0, 0, 1, iABC)		/* OP_BORK */
  ,opmode(0, 0, 0, 1, iABC)		/* OP_BXORK */
diff --git a/lopcodes.h b/lopcodes.h
index 7bb83a1..d7403ca 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -221,6 +221,14 @@
 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_SUBK,/*	A B C	R(A) := R(B) - K(C)				*/
+OP_MULK,/*	A B C	R(A) := R(B) * K(C)				*/
+OP_MODK,/*	A B C	R(A) := R(B) % K(C)				*/
+OP_POWK,/*	A B C	R(A) := R(B) ^ K(C)				*/
+OP_DIVK,/*	A B C	R(A) := R(B) / K(C)				*/
+OP_IDIVK,/*	A B C	R(A) := R(B) // K(C)				*/
+
 OP_BANDK,/*	A B C	R(A) := R(B) & K(C):integer			*/
 OP_BORK,/*	A B C	R(A) := R(B) | K(C):integer			*/
 OP_BXORK,/*	A B C	R(A) := R(B) ~ K(C):integer			*/
@@ -235,11 +243,13 @@
 OP_POW,/*	A B C	R(A) := R(B) ^ R(C)				*/
 OP_DIV,/*	A B C	R(A) := R(B) / R(C)				*/
 OP_IDIV,/*	A B C	R(A) := R(B) // R(C)				*/
+
 OP_BAND,/*	A B C	R(A) := R(B) & R(C)				*/
 OP_BOR,/*	A B C	R(A) := R(B) | R(C)				*/
 OP_BXOR,/*	A B C	R(A) := R(B) ~ R(C)				*/
 OP_SHL,/*	A B C	R(A) := R(B) << R(C)				*/
 OP_SHR,/*	A B C	R(A) := R(B) >> R(C)				*/
+
 OP_UNM,/*	A B	R(A) := -R(B)					*/
 OP_BNOT,/*	A B	R(A) := ~R(B)					*/
 OP_NOT,/*	A B	R(A) := not R(B)				*/
diff --git a/lopnames.h b/lopnames.h
index b2c4fe2..96d901a 100644
--- a/lopnames.h
+++ b/lopnames.h
@@ -36,6 +36,13 @@
   "POWI",
   "DIVI",
   "IDIVI",
+  "ADDK",
+  "SUBK",
+  "MULK",
+  "MODK",
+  "POWK",
+  "DIVK",
+  "IDIVK",
   "BANDK",
   "BORK",
   "BXORK",
diff --git a/ltests.h b/ltests.h
index d44974a..9d409c8 100644
--- a/ltests.h
+++ b/ltests.h
@@ -119,7 +119,6 @@
 #undef LUAL_BUFFERSIZE
 #define LUAL_BUFFERSIZE		23
 #define MINSTRTABSIZE		2
-#define MAXINDEXRK		1
 #define MAXIWTHABS		3
 
 
diff --git a/lvm.c b/lvm.c
index ece7d77..27ef68c 100644
--- a/lvm.c
+++ b/lvm.c
@@ -856,6 +856,39 @@
 
 
 /*
+** Arithmetic operations with K operands.
+*/
+#define op_arithK(L,iop,fop,tm,flip) {  \
+  TValue *v1 = vRB(i);  \
+  TValue *v2 = KC(i);  \
+  if (ttisinteger(v1) && ttisinteger(v2)) {  \
+    lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2);  \
+    setivalue(s2v(ra), iop(L, i1, i2));  \
+  }  \
+  else { \
+    lua_Number n1; lua_Number n2;  \
+    if (tonumberns(v1, n1) && tonumberns(v2, n2)) {  \
+      setfltvalue(s2v(ra), fop(L, n1, n2));  \
+    }  \
+    else  \
+      Protect(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } }
+
+
+/*
+** Arithmetic operations with K operands for floats.
+*/
+#define op_arithfK(L,fop,tm) {  \
+  TValue *v1 = vRB(i);  \
+  TValue *v2 = KC(i);  \
+  lua_Number n1; lua_Number n2;  \
+  if (tonumberns(v1, n1) && tonumberns(v2, n2)) {  \
+    setfltvalue(s2v(ra), fop(L, n1, n2));  \
+  }  \
+  else  \
+    Protect(luaT_trybinTM(L, v1, v2, ra, tm)); }
+
+
+/*
 ** Bitwise operations with constant operand.
 */
 #define op_bitwiseK(L,op,tm) {  \
@@ -1219,6 +1252,34 @@
         op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0);
         vmbreak;
       }
+      vmcase(OP_ADDK) {
+        op_arithK(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i));
+        vmbreak;
+      }
+      vmcase(OP_SUBK) {
+        op_arithK(L, l_subi, luai_numsub, TM_SUB, 0);
+        vmbreak;
+      }
+      vmcase(OP_MULK) {
+        op_arithK(L, l_muli, luai_nummul, TM_MUL, GETARG_k(i));
+        vmbreak;
+      }
+      vmcase(OP_MODK) {
+        op_arithK(L, luaV_mod, luaV_modf, TM_MOD, 0);
+        vmbreak;
+      }
+      vmcase(OP_POWK) {
+        op_arithfK(L, luai_numpow, TM_POW);
+        vmbreak;
+      }
+      vmcase(OP_DIVK) {
+        op_arithfK(L, luai_numdiv, TM_DIV);
+        vmbreak;
+      }
+      vmcase(OP_IDIVK) {
+        op_arithK(L, luaV_idiv, luai_numidiv, TM_IDIV, 0);
+        vmbreak;
+      }
       vmcase(OP_ADD) {
         op_arith(L, l_addi, luai_numadd, TM_ADD);
         vmbreak;
diff --git a/testes/code.lua b/testes/code.lua
index 4d44fa6..834ff5e 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -40,6 +40,7 @@
 
 -- testing opcodes
 
+-- check that 'f' opcodes match '...'
 function check (f, ...)
   local arg = {...}
   local c = T.listcode(f)
@@ -52,9 +53,19 @@
 end
 
 
+-- check that 'f' opcodes match '...' and that 'f(p) == r'.
+function checkR (f, p, r, ...)
+  local r1 = f(p)
+  assert(r == r1 and math.type(r) == math.type(r1))
+  check(f, ...)
+end
+
+
+-- check that 'a' and 'b' has the same opcodes
 function checkequal (a, b)
   a = T.listcode(a)
   b = T.listcode(b)
+  assert(#a == #b)
   for i = 1, #a do
     a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
     b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
@@ -165,65 +176,64 @@
 
 
 -- equalities
-check(function (a) if a == 1 then return 2 end end,
+checkR(function (a) if a == 1 then return 2 end end, 1, 2,
   'EQI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if -4.0 == a then return 2 end end,
+checkR(function (a) if -4.0 == a then return 2 end end, -4, 2,
   'EQI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if a == "hi" then return 2 end end,
+checkR(function (a) if a == "hi" then return 2 end end, 10, nil,
   'EQK', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if a == 10000 then return 2 end end,
+checkR(function (a) if a == 10000 then return 2 end end, 1, nil,
   'EQK', 'JMP', 'LOADI', 'RETURN1')   -- number too large
 
-check(function (a) if -10000 == a then return 2 end end,
+checkR(function (a) if -10000 == a then return 2 end end, -10000, 2,
   'EQK', 'JMP', 'LOADI', 'RETURN1')   -- number too large
 
 -- comparisons
 
-check(function (a) if -10 <= a then return 2 end end,
+checkR(function (a) if -10 <= a then return 2 end end, -10, 2,
   'GEI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if 128.0 > a then return 2 end end,
+checkR(function (a) if 128.0 > a then return 2 end end, 129, nil,
   'LTI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if -127.0 < a then return 2 end end,
+checkR(function (a) if -127.0 < a then return 2 end end, -127, nil,
   'GTI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if 10 < a then return 2 end end,
+checkR(function (a) if 10 < a then return 2 end end, 11, 2,
   'GTI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if 129 < a then return 2 end end,
+checkR(function (a) if 129 < a then return 2 end end, 130, 2,
   'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if a >= 23.0 then return 2 end end,
+checkR(function (a) if a >= 23.0 then return 2 end end, 25, 2,
   'GEI', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if a >= 23.1 then return 2 end end,
+checkR(function (a) if a >= 23.1 then return 2 end end, 0, nil,
   'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1')
 
-check(function (a) if a > 2300.0 then return 2 end end,
+checkR(function (a) if a > 2300.0 then return 2 end end, 0, nil,
   'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1')
 
 
 -- constant folding
 local function checkK (func, val)
   check(func, 'LOADK', 'RETURN1')
-  local k = T.listk(func)
-  assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val))
+  checkKlist(func, {val})
   assert(func() == val)
 end
 
 local function checkI (func, val)
   check(func, 'LOADI', 'RETURN1')
-  assert(#T.listk(func) == 0)
+  checkKlist(func, {})
   assert(func() == val)
 end
 
 local function checkF (func, val)
   check(func, 'LOADF', 'RETURN1')
-  assert(#T.listk(func) == 0)
+  checkKlist(func, {})
   assert(func() == val)
 end
 
@@ -258,20 +268,30 @@
 
 
 -- immediate operands
-check(function (x) return x + 1 end, 'ADDI', 'RETURN1')
-check(function (x) return 128 + x end, 'ADDI', 'RETURN1')
-check(function (x) return x * -127 end, 'MULI', 'RETURN1')
-check(function (x) return 20 * x end, 'MULI', 'RETURN1')
-check(function (x) return x ^ -2 end, 'POWI', 'RETURN1')
-check(function (x) return x / 40 end, 'DIVI', 'RETURN1')
-check(function (x) return x // 1 end, 'IDIVI', 'RETURN1')
-check(function (x) return x % (100 - 10) end, 'MODI', 'RETURN1')
-check(function (x) return 1 << x end, 'SHLI', 'RETURN1')
-check(function (x) return x << 2 end, 'SHRI', 'RETURN1')
-check(function (x) return x >> 2 end, 'SHRI', 'RETURN1')
-check(function (x) return x & 1 end, 'BANDK', 'RETURN1')
-check(function (x) return 10 | x end, 'BORK', 'RETURN1')
-check(function (x) return -10 ~ x end, 'BXORK', 'RETURN1')
+checkR(function (x) return x + 1 end, 10, 11, 'ADDI', 'RETURN1')
+checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1')
+checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1')
+checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1')
+checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1')
+checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1')
+checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1')
+checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1')
+checkR(function (x) return 1 << x end, 3, 8, 'SHLI', 'RETURN1')
+checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1')
+checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1')
+checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1')
+checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1')
+checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1')
+
+-- K operands in arithmetic operations
+checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1')
+--  check(function (x) return 128 + x end, 'ADDK', 'RETURN1')
+checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1')
+--  check(function (x) return 20 * x end, 'MULK', 'RETURN1')
+checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1')
+checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1')
+checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1')
+checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1')
 
 -- no foldings (and immediate operands)
 check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
diff --git a/testes/db.lua b/testes/db.lua
index 9da6821..5b243c3 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -794,6 +794,8 @@
 assert(a/3 == "div" and 3%a == "mod")
 assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and
        -a == "unm" and #a == "len" and a&3 == "band")
+assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and
+       -a == "unm" and #a == "len" and a & 3 == "band")
 assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and
        a>>1 == "shift")
 assert (a==b and a.op == "eq")
diff --git a/testes/events.lua b/testes/events.lua
index b071c2a..ac630d8 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -144,6 +144,8 @@
 -- when the constant table is very small.
 assert(b+5 == b)
 assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef)
+assert(5.2 + b == 5.2)
+assert(cap[0] == "add" and cap[1] == 5.2 and cap[2] == b and cap[3]==undef)
 assert(b+'5' == b)
 assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef)
 assert(5+b == 5)