aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-11 23:28:46 +0100
committerMike Pall <mike>2011-03-11 23:28:46 +0100
commit7fb1075903587084b785260fc14cc35976bbe5fd (patch)
tree0075489c1d73cfd2c42fde7520c8ce5e1f5f2d5c /src
parent889368e921a11e2abb3769e2c1f395174e83112d (diff)
downloadluajit-7fb1075903587084b785260fc14cc35976bbe5fd.tar.gz
luajit-7fb1075903587084b785260fc14cc35976bbe5fd.tar.bz2
luajit-7fb1075903587084b785260fc14cc35976bbe5fd.zip
DUALNUM: Add integer variant of MIN/MAX.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c25
-rw-r--r--src/lj_ffrecord.c14
-rw-r--r--src/lj_ir.c12
-rw-r--r--src/lj_iropt.h1
-rw-r--r--src/lj_opt_fold.c18
-rw-r--r--src/lj_target_x86.h1
6 files changed, 64 insertions, 7 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index d395010d..85962ab1 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -3005,6 +3005,17 @@ static void asm_neg_not(ASMState *as, IRIns *ir, x86Group3 xg)
3005 ra_left(as, dest, ir->op1); 3005 ra_left(as, dest, ir->op1);
3006} 3006}
3007 3007
3008static void asm_min_max(ASMState *as, IRIns *ir, int cc)
3009{
3010 Reg right, dest = ra_dest(as, ir, RSET_GPR);
3011 IRRef lref = ir->op1, rref = ir->op2;
3012 if (irref_isk(rref)) { lref = rref; rref = ir->op1; }
3013 right = ra_alloc1(as, rref, rset_exclude(RSET_GPR, dest));
3014 emit_rr(as, XO_CMOV + (cc<<24), REX_64IR(ir, dest), right);
3015 emit_rr(as, XO_CMP, REX_64IR(ir, dest), right);
3016 ra_left(as, dest, lref);
3017}
3018
3008static void asm_bitswap(ASMState *as, IRIns *ir) 3019static void asm_bitswap(ASMState *as, IRIns *ir)
3009{ 3020{
3010 Reg dest = ra_dest(as, ir, RSET_GPR); 3021 Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -4067,8 +4078,18 @@ static void asm_ir(ASMState *as, IRIns *ir)
4067 break; 4078 break;
4068 case IR_ABS: asm_fparith(as, ir, XO_ANDPS); break; 4079 case IR_ABS: asm_fparith(as, ir, XO_ANDPS); break;
4069 4080
4070 case IR_MIN: asm_fparith(as, ir, XO_MINSD); break; 4081 case IR_MIN:
4071 case IR_MAX: asm_fparith(as, ir, XO_MAXSD); break; 4082 if (irt_isnum(ir->t))
4083 asm_fparith(as, ir, XO_MINSD);
4084 else
4085 asm_min_max(as, ir, CC_G);
4086 break;
4087 case IR_MAX:
4088 if (irt_isnum(ir->t))
4089 asm_fparith(as, ir, XO_MAXSD);
4090 else
4091 asm_min_max(as, ir, CC_L);
4092 break;
4072 4093
4073 case IR_FPMATH: case IR_ATAN2: case IR_LDEXP: 4094 case IR_FPMATH: case IR_ATAN2: case IR_LDEXP:
4074 asm_fpmath(as, ir); 4095 asm_fpmath(as, ir);
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index 8077bf84..84957373 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -488,11 +488,19 @@ static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
488 488
489static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd) 489static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
490{ 490{
491 TRef tr = lj_ir_tonum(J, J->base[0]); 491 TRef tr = lj_ir_tonumber(J, J->base[0]);
492 uint32_t op = rd->data; 492 uint32_t op = rd->data;
493 BCReg i; 493 BCReg i;
494 for (i = 1; J->base[i] != 0; i++) 494 for (i = 1; J->base[i] != 0; i++) {
495 tr = emitir(IRTN(op), tr, lj_ir_tonum(J, J->base[i])); 495 TRef tr2 = lj_ir_tonumber(J, J->base[i]);
496 IRType t = IRT_INT;
497 if (!(tref_isinteger(tr) && tref_isinteger(tr2))) {
498 if (tref_isinteger(tr)) tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
499 if (tref_isinteger(tr2)) tr2 = emitir(IRTN(IR_CONV), tr2, IRCONV_NUM_INT);
500 t = IRT_NUM;
501 }
502 tr = emitir(IRT(op, t), tr, tr2);
503 }
496 J->base[0] = tr; 504 J->base[0] = tr;
497} 505}
498 506
diff --git a/src/lj_ir.c b/src/lj_ir.c
index 64467758..94fe44b1 100644
--- a/src/lj_ir.c
+++ b/src/lj_ir.c
@@ -401,6 +401,18 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
401 401
402/* -- Convert IR operand types -------------------------------------------- */ 402/* -- Convert IR operand types -------------------------------------------- */
403 403
404/* Convert from string to number. */
405TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr)
406{
407 if (!tref_isnumber(tr)) {
408 if (tref_isstr(tr))
409 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
410 else
411 lj_trace_err(J, LJ_TRERR_BADTYPE);
412 }
413 return tr;
414}
415
404/* Convert from integer or string to number. */ 416/* Convert from integer or string to number. */
405TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr) 417TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr)
406{ 418{
diff --git a/src/lj_iropt.h b/src/lj_iropt.h
index 1c94e91c..dd1128bc 100644
--- a/src/lj_iropt.h
+++ b/src/lj_iropt.h
@@ -82,6 +82,7 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n)
82LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); 82LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir);
83 83
84/* Convert IR operand types. */ 84/* Convert IR operand types. */
85LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr);
85LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr); 86LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr);
86LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr); 87LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
87 88
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index eb500db9..325b0372 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -226,6 +226,8 @@ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
226 case IR_BSAR: k1 >>= (k2 & 31); break; 226 case IR_BSAR: k1 >>= (k2 & 31); break;
227 case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break; 227 case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break;
228 case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break; 228 case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break;
229 case IR_MIN: k1 = k1 < k2 ? k1 : k2; break;
230 case IR_MAX: k1 = k1 > k2 ? k1 : k2; break;
229 default: lua_assert(0); break; 231 default: lua_assert(0); break;
230 } 232 }
231 return k1; 233 return k1;
@@ -242,6 +244,8 @@ LJFOLD(BSHR KINT KINT)
242LJFOLD(BSAR KINT KINT) 244LJFOLD(BSAR KINT KINT)
243LJFOLD(BROL KINT KINT) 245LJFOLD(BROL KINT KINT)
244LJFOLD(BROR KINT KINT) 246LJFOLD(BROR KINT KINT)
247LJFOLD(MIN KINT KINT)
248LJFOLD(MAX KINT KINT)
245LJFOLDF(kfold_intarith) 249LJFOLDF(kfold_intarith)
246{ 250{
247 return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o)); 251 return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
@@ -1434,19 +1438,29 @@ LJFOLDF(reassoc_shift)
1434 1438
1435LJFOLD(MIN MIN KNUM) 1439LJFOLD(MIN MIN KNUM)
1436LJFOLD(MAX MAX KNUM) 1440LJFOLD(MAX MAX KNUM)
1441LJFOLD(MIN MIN KINT)
1442LJFOLD(MAX MAX KINT)
1437LJFOLDF(reassoc_minmax_k) 1443LJFOLDF(reassoc_minmax_k)
1438{ 1444{
1439 IRIns *irk = IR(fleft->op2); 1445 IRIns *irk = IR(fleft->op2);
1440 if (irk->o == IR_KNUM) { 1446 if (irk->o == IR_KNUM) {
1441 lua_Number a = ir_knum(irk)->n; 1447 lua_Number a = ir_knum(irk)->n;
1442 lua_Number b = knumright; 1448 lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
1443 lua_Number y = lj_vm_foldarith(a, b, fins->o - IR_ADD);
1444 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */ 1449 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1445 return LEFTFOLD; 1450 return LEFTFOLD;
1446 PHIBARRIER(fleft); 1451 PHIBARRIER(fleft);
1447 fins->op1 = fleft->op1; 1452 fins->op1 = fleft->op1;
1448 fins->op2 = (IRRef1)lj_ir_knum(J, y); 1453 fins->op2 = (IRRef1)lj_ir_knum(J, y);
1449 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */ 1454 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1455 } else if (irk->o == IR_KINT) {
1456 int32_t a = irk->i;
1457 int32_t y = kfold_intop(a, fright->i, fins->o);
1458 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1459 return LEFTFOLD;
1460 PHIBARRIER(fleft);
1461 fins->op1 = fleft->op1;
1462 fins->op2 = (IRRef1)lj_ir_kint(J, y);
1463 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1450 } 1464 }
1451 return NEXTFOLD; 1465 return NEXTFOLD;
1452} 1466}
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index 37c68f4b..564ffc63 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -234,6 +234,7 @@ typedef enum {
234 XO_MOVSXw = XO_0f(bf), 234 XO_MOVSXw = XO_0f(bf),
235 XO_MOVSXd = XO_(63), 235 XO_MOVSXd = XO_(63),
236 XO_BSWAP = XO_0f(c8), 236 XO_BSWAP = XO_0f(c8),
237 XO_CMOV = XO_0f(40),
237 238
238 XO_MOVSD = XO_f20f(10), 239 XO_MOVSD = XO_f20f(10),
239 XO_MOVSDto = XO_f20f(11), 240 XO_MOVSDto = XO_f20f(11),