mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
DUALNUM: Add integer variant of MIN/MAX.
This commit is contained in:
parent
889368e921
commit
7fb1075903
25
src/lj_asm.c
25
src/lj_asm.c
@ -3005,6 +3005,17 @@ static void asm_neg_not(ASMState *as, IRIns *ir, x86Group3 xg)
|
|||||||
ra_left(as, dest, ir->op1);
|
ra_left(as, dest, ir->op1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asm_min_max(ASMState *as, IRIns *ir, int cc)
|
||||||
|
{
|
||||||
|
Reg right, dest = ra_dest(as, ir, RSET_GPR);
|
||||||
|
IRRef lref = ir->op1, rref = ir->op2;
|
||||||
|
if (irref_isk(rref)) { lref = rref; rref = ir->op1; }
|
||||||
|
right = ra_alloc1(as, rref, rset_exclude(RSET_GPR, dest));
|
||||||
|
emit_rr(as, XO_CMOV + (cc<<24), REX_64IR(ir, dest), right);
|
||||||
|
emit_rr(as, XO_CMP, REX_64IR(ir, dest), right);
|
||||||
|
ra_left(as, dest, lref);
|
||||||
|
}
|
||||||
|
|
||||||
static void asm_bitswap(ASMState *as, IRIns *ir)
|
static void asm_bitswap(ASMState *as, IRIns *ir)
|
||||||
{
|
{
|
||||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
@ -4067,8 +4078,18 @@ static void asm_ir(ASMState *as, IRIns *ir)
|
|||||||
break;
|
break;
|
||||||
case IR_ABS: asm_fparith(as, ir, XO_ANDPS); break;
|
case IR_ABS: asm_fparith(as, ir, XO_ANDPS); break;
|
||||||
|
|
||||||
case IR_MIN: asm_fparith(as, ir, XO_MINSD); break;
|
case IR_MIN:
|
||||||
case IR_MAX: asm_fparith(as, ir, XO_MAXSD); break;
|
if (irt_isnum(ir->t))
|
||||||
|
asm_fparith(as, ir, XO_MINSD);
|
||||||
|
else
|
||||||
|
asm_min_max(as, ir, CC_G);
|
||||||
|
break;
|
||||||
|
case IR_MAX:
|
||||||
|
if (irt_isnum(ir->t))
|
||||||
|
asm_fparith(as, ir, XO_MAXSD);
|
||||||
|
else
|
||||||
|
asm_min_max(as, ir, CC_L);
|
||||||
|
break;
|
||||||
|
|
||||||
case IR_FPMATH: case IR_ATAN2: case IR_LDEXP:
|
case IR_FPMATH: case IR_ATAN2: case IR_LDEXP:
|
||||||
asm_fpmath(as, ir);
|
asm_fpmath(as, ir);
|
||||||
|
@ -488,11 +488,19 @@ static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
|
|||||||
|
|
||||||
static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
|
static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
|
||||||
{
|
{
|
||||||
TRef tr = lj_ir_tonum(J, J->base[0]);
|
TRef tr = lj_ir_tonumber(J, J->base[0]);
|
||||||
uint32_t op = rd->data;
|
uint32_t op = rd->data;
|
||||||
BCReg i;
|
BCReg i;
|
||||||
for (i = 1; J->base[i] != 0; i++)
|
for (i = 1; J->base[i] != 0; i++) {
|
||||||
tr = emitir(IRTN(op), tr, lj_ir_tonum(J, J->base[i]));
|
TRef tr2 = lj_ir_tonumber(J, J->base[i]);
|
||||||
|
IRType t = IRT_INT;
|
||||||
|
if (!(tref_isinteger(tr) && tref_isinteger(tr2))) {
|
||||||
|
if (tref_isinteger(tr)) tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
|
||||||
|
if (tref_isinteger(tr2)) tr2 = emitir(IRTN(IR_CONV), tr2, IRCONV_NUM_INT);
|
||||||
|
t = IRT_NUM;
|
||||||
|
}
|
||||||
|
tr = emitir(IRT(op, t), tr, tr2);
|
||||||
|
}
|
||||||
J->base[0] = tr;
|
J->base[0] = tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/lj_ir.c
12
src/lj_ir.c
@ -401,6 +401,18 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
|
|||||||
|
|
||||||
/* -- Convert IR operand types -------------------------------------------- */
|
/* -- Convert IR operand types -------------------------------------------- */
|
||||||
|
|
||||||
|
/* Convert from string to number. */
|
||||||
|
TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr)
|
||||||
|
{
|
||||||
|
if (!tref_isnumber(tr)) {
|
||||||
|
if (tref_isstr(tr))
|
||||||
|
tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
|
||||||
|
else
|
||||||
|
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||||
|
}
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert from integer or string to number. */
|
/* Convert from integer or string to number. */
|
||||||
TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr)
|
TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +82,7 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n)
|
|||||||
LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir);
|
LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir);
|
||||||
|
|
||||||
/* Convert IR operand types. */
|
/* Convert IR operand types. */
|
||||||
|
LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr);
|
||||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr);
|
LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr);
|
||||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
|
LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
|
||||||
|
|
||||||
|
@ -226,6 +226,8 @@ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
|
|||||||
case IR_BSAR: k1 >>= (k2 & 31); break;
|
case IR_BSAR: k1 >>= (k2 & 31); break;
|
||||||
case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break;
|
case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break;
|
||||||
case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break;
|
case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break;
|
||||||
|
case IR_MIN: k1 = k1 < k2 ? k1 : k2; break;
|
||||||
|
case IR_MAX: k1 = k1 > k2 ? k1 : k2; break;
|
||||||
default: lua_assert(0); break;
|
default: lua_assert(0); break;
|
||||||
}
|
}
|
||||||
return k1;
|
return k1;
|
||||||
@ -242,6 +244,8 @@ LJFOLD(BSHR KINT KINT)
|
|||||||
LJFOLD(BSAR KINT KINT)
|
LJFOLD(BSAR KINT KINT)
|
||||||
LJFOLD(BROL KINT KINT)
|
LJFOLD(BROL KINT KINT)
|
||||||
LJFOLD(BROR KINT KINT)
|
LJFOLD(BROR KINT KINT)
|
||||||
|
LJFOLD(MIN KINT KINT)
|
||||||
|
LJFOLD(MAX KINT KINT)
|
||||||
LJFOLDF(kfold_intarith)
|
LJFOLDF(kfold_intarith)
|
||||||
{
|
{
|
||||||
return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
|
return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
|
||||||
@ -1434,19 +1438,29 @@ LJFOLDF(reassoc_shift)
|
|||||||
|
|
||||||
LJFOLD(MIN MIN KNUM)
|
LJFOLD(MIN MIN KNUM)
|
||||||
LJFOLD(MAX MAX KNUM)
|
LJFOLD(MAX MAX KNUM)
|
||||||
|
LJFOLD(MIN MIN KINT)
|
||||||
|
LJFOLD(MAX MAX KINT)
|
||||||
LJFOLDF(reassoc_minmax_k)
|
LJFOLDF(reassoc_minmax_k)
|
||||||
{
|
{
|
||||||
IRIns *irk = IR(fleft->op2);
|
IRIns *irk = IR(fleft->op2);
|
||||||
if (irk->o == IR_KNUM) {
|
if (irk->o == IR_KNUM) {
|
||||||
lua_Number a = ir_knum(irk)->n;
|
lua_Number a = ir_knum(irk)->n;
|
||||||
lua_Number b = knumright;
|
lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
|
||||||
lua_Number y = lj_vm_foldarith(a, b, fins->o - IR_ADD);
|
|
||||||
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
||||||
return LEFTFOLD;
|
return LEFTFOLD;
|
||||||
PHIBARRIER(fleft);
|
PHIBARRIER(fleft);
|
||||||
fins->op1 = fleft->op1;
|
fins->op1 = fleft->op1;
|
||||||
fins->op2 = (IRRef1)lj_ir_knum(J, y);
|
fins->op2 = (IRRef1)lj_ir_knum(J, y);
|
||||||
return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
|
return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
|
||||||
|
} else if (irk->o == IR_KINT) {
|
||||||
|
int32_t a = irk->i;
|
||||||
|
int32_t y = kfold_intop(a, fright->i, fins->o);
|
||||||
|
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
||||||
|
return LEFTFOLD;
|
||||||
|
PHIBARRIER(fleft);
|
||||||
|
fins->op1 = fleft->op1;
|
||||||
|
fins->op2 = (IRRef1)lj_ir_kint(J, y);
|
||||||
|
return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
|
||||||
}
|
}
|
||||||
return NEXTFOLD;
|
return NEXTFOLD;
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,7 @@ typedef enum {
|
|||||||
XO_MOVSXw = XO_0f(bf),
|
XO_MOVSXw = XO_0f(bf),
|
||||||
XO_MOVSXd = XO_(63),
|
XO_MOVSXd = XO_(63),
|
||||||
XO_BSWAP = XO_0f(c8),
|
XO_BSWAP = XO_0f(c8),
|
||||||
|
XO_CMOV = XO_0f(40),
|
||||||
|
|
||||||
XO_MOVSD = XO_f20f(10),
|
XO_MOVSD = XO_f20f(10),
|
||||||
XO_MOVSDto = XO_f20f(11),
|
XO_MOVSDto = XO_f20f(11),
|
||||||
|
Loading…
Reference in New Issue
Block a user