diff options
author | Mike Pall <mike> | 2011-03-11 23:28:46 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-03-11 23:28:46 +0100 |
commit | 7fb1075903587084b785260fc14cc35976bbe5fd (patch) | |
tree | 0075489c1d73cfd2c42fde7520c8ce5e1f5f2d5c /src | |
parent | 889368e921a11e2abb3769e2c1f395174e83112d (diff) | |
download | luajit-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.c | 25 | ||||
-rw-r--r-- | src/lj_ffrecord.c | 14 | ||||
-rw-r--r-- | src/lj_ir.c | 12 | ||||
-rw-r--r-- | src/lj_iropt.h | 1 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 18 | ||||
-rw-r--r-- | src/lj_target_x86.h | 1 |
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 | ||
3008 | static 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 | |||
3008 | static void asm_bitswap(ASMState *as, IRIns *ir) | 3019 | static 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 | ||
489 | static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd) | 489 | static 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. */ | ||
405 | TRef 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. */ |
405 | TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr) | 417 | TRef 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) | |||
82 | LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); | 82 | LJ_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. */ |
85 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr); | ||
85 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr); | 86 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr); |
86 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr); | 87 | LJ_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) | |||
242 | LJFOLD(BSAR KINT KINT) | 244 | LJFOLD(BSAR KINT KINT) |
243 | LJFOLD(BROL KINT KINT) | 245 | LJFOLD(BROL KINT KINT) |
244 | LJFOLD(BROR KINT KINT) | 246 | LJFOLD(BROR KINT KINT) |
247 | LJFOLD(MIN KINT KINT) | ||
248 | LJFOLD(MAX KINT KINT) | ||
245 | LJFOLDF(kfold_intarith) | 249 | LJFOLDF(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 | ||
1435 | LJFOLD(MIN MIN KNUM) | 1439 | LJFOLD(MIN MIN KNUM) |
1436 | LJFOLD(MAX MAX KNUM) | 1440 | LJFOLD(MAX MAX KNUM) |
1441 | LJFOLD(MIN MIN KINT) | ||
1442 | LJFOLD(MAX MAX KINT) | ||
1437 | LJFOLDF(reassoc_minmax_k) | 1443 | LJFOLDF(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), |