]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
DUALNUM: Narrow unary minus.
authorMike Pall <mike>
Tue, 15 Mar 2011 16:56:55 +0000 (17:56 +0100)
committerMike Pall <mike>
Tue, 15 Mar 2011 17:14:18 +0000 (18:14 +0100)
src/lj_iropt.h
src/lj_opt_fold.c
src/lj_opt_narrow.c
src/lj_record.c

index dd1128bc5a4786818d92114c67e9a79a40d42cb6..82dc2e27c3ab4d7da7a398a7345895237112d9d0 100644 (file)
@@ -141,6 +141,7 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key);
 #endif
 LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
                                 TValue *vb, TValue *vc, IROp op);
+LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc);
 LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc);
 LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc);
 LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);
index 325b037232bd0dfd483746737c60ed1dff42e069..edd376c98cf8a4905dbcd3b6b9d232f446e7a039 100644 (file)
@@ -701,7 +701,7 @@ LJFOLDF(shortcut_dropleft)
 }
 
 /* Note: no safe shortcuts with STRTO and TOSTR ("1e2" ==> +100 ==> "100"). */
-LJFOLD(NEG NEG KNUM)
+LJFOLD(NEG NEG any)
 LJFOLD(BNOT BNOT)
 LJFOLD(BSWAP BSWAP)
 LJFOLDF(shortcut_leftleft)
@@ -1067,6 +1067,18 @@ LJFOLDF(simplify_intsub_k)
   return RETRYFOLD;
 }
 
+LJFOLD(SUB KINT any)
+LJFOLD(SUB KINT64 any)
+LJFOLDF(simplify_intsub_kleft)
+{
+  if (fleft->o == IR_KINT ? (fleft->i == 0) : (ir_kint64(fleft)->u64 == 0)) {
+    fins->o = IR_NEG;  /* 0 - i ==> -i */
+    fins->op1 = fins->op2;
+    return RETRYFOLD;
+  }
+  return NEXTFOLD;
+}
+
 LJFOLD(ADD any KINT64)
 LJFOLDF(simplify_intadd_k64)
 {
index 1727e9b5c9d0e3a79446b41cba9a0a7cc809fbe0..e7f280ec9f6c3a21e888e925228a7b1fa7a81ba0 100644 (file)
@@ -535,6 +535,21 @@ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
   return emitir(IRTN(op), rb, rc);
 }
 
+/* Narrowing of unary minus operator. */
+TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc)
+{
+  if (tref_isstr(rc)) {
+    rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
+    lj_str_tonum(strV(vc), vc);
+  }
+  if (tref_isinteger(rc)) {
+    if ((uint32_t)numberVint(vc) != 0x80000000u)
+      return emitir(IRTGI(IR_SUBOV), lj_ir_kint(J, 0), rc);
+    rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
+  }
+  return emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J));
+}
+
 /* Narrowing of modulo operator. */
 TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc)
 {
index 613e458eab9f73d07468170c099423ac9b4ee8fb..ea23c758f4b8cbc02092b2917bba158b1d7e4019 100644 (file)
@@ -1666,8 +1666,7 @@ void lj_record_ins(jit_State *J)
 
   case BC_UNM:
     if (tref_isnumber_str(rc)) {
-      rc = lj_ir_tonum(J, rc);
-      rc = emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J));
+      rc = lj_opt_narrow_unm(J, rc, &ix.tabv);
     } else {
       ix.tab = rc;
       copyTV(J->L, &ix.tabv, &ix.keyv);