summaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
authorMike Pall <mike>2012-08-15 16:17:34 +0200
committerMike Pall <mike>2012-08-15 16:17:34 +0200
commitff0a1f3f4eedf8e43eeb5cc3d2f8d051b648e0c0 (patch)
tree344b8050d1cb8f112a8699c4d1a3a2200a196ca9 /src/lj_opt_fold.c
parent5e18c91b899f718dd371f24d5486ade1f9a9ab6d (diff)
downloadluajit2-ff0a1f3f4eedf8e43eeb5cc3d2f8d051b648e0c0.tar.gz
FOLD x / 2^k ==> x * 2^-k.
Diffstat (limited to 'src/lj_opt_fold.c')
-rw-r--r--src/lj_opt_fold.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 74cea785..461fa621 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -816,6 +816,15 @@ LJFOLDF(simplify_nummuldiv_k)
fins->o = IR_ADD;
fins->op2 = fins->op1;
return RETRYFOLD;
+ } else if (fins->o == IR_DIV) { /* x / 2^k ==> x * 2^-k */
+ uint64_t u = ir_knum(fright)->u64;
+ if ((u & U64x(000fffff,ffffffff)) == 0 &&
+ (uint32_t)(u = ((u >> 52) & 0x7ff)) - 1 < 0x7fd) {
+ u = (u & (uint64_t)1 << 63) | ((uint64_t)(0x7fe - (uint32_t)u) << 52);
+ fins->o = IR_MUL; /* Multiply by exact reciprocal. */
+ fins->op2 = lj_ir_knum_u64(J, u);
+ return RETRYFOLD;
+ }
}
return NEXTFOLD;
}