#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);
}
/* 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)
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)
{
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)
{
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);