aboutsummaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_opt_fold.c37
1 files changed, 8 insertions, 29 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 34f70e27..92bdc553 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -236,14 +236,10 @@ LJFOLDF(kfold_fpcall2)
236 return NEXTFOLD; 236 return NEXTFOLD;
237} 237}
238 238
239LJFOLD(POW KNUM KINT)
240LJFOLD(POW KNUM KNUM) 239LJFOLD(POW KNUM KNUM)
241LJFOLDF(kfold_numpow) 240LJFOLDF(kfold_numpow)
242{ 241{
243 lua_Number a = knumleft; 242 return lj_ir_knum(J, lj_vm_foldarith(knumleft, knumright, IR_POW - IR_ADD));
244 lua_Number b = fright->o == IR_KINT ? (lua_Number)fright->i : knumright;
245 lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD);
246 return lj_ir_knum(J, y);
247} 243}
248 244
249/* Must not use kfold_kref for numbers (could be NaN). */ 245/* Must not use kfold_kref for numbers (could be NaN). */
@@ -1113,34 +1109,17 @@ LJFOLDF(simplify_nummuldiv_negneg)
1113 return RETRYFOLD; 1109 return RETRYFOLD;
1114} 1110}
1115 1111
1116LJFOLD(POW any KINT) 1112LJFOLD(POW any KNUM)
1117LJFOLDF(simplify_numpow_xkint) 1113LJFOLDF(simplify_numpow_k)
1118{ 1114{
1119 int32_t k = fright->i; 1115 if (knumright == 0) /* x ^ 0 ==> 1 */
1120 TRef ref = fins->op1;
1121 if (k == 0) /* x ^ 0 ==> 1 */
1122 return lj_ir_knum_one(J); /* Result must be a number, not an int. */ 1116 return lj_ir_knum_one(J); /* Result must be a number, not an int. */
1123 if (k == 1) /* x ^ 1 ==> x */ 1117 else if (knumright == 1) /* x ^ 1 ==> x */
1124 return LEFTFOLD; 1118 return LEFTFOLD;
1125 if ((uint32_t)(k+65536) > 2*65536u) /* Limit code explosion. */ 1119 else if (knumright == 2) /* x ^ 2 ==> x * x */
1120 return emitir(IRTN(IR_MUL), fins->op1, fins->op1);
1121 else
1126 return NEXTFOLD; 1122 return NEXTFOLD;
1127 if (k < 0) { /* x ^ (-k) ==> (1/x) ^ k. */
1128 ref = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), ref);
1129 k = -k;
1130 }
1131 /* Unroll x^k for 1 <= k <= 65536. */
1132 for (; (k & 1) == 0; k >>= 1) /* Handle leading zeros. */
1133 ref = emitir(IRTN(IR_MUL), ref, ref);
1134 if ((k >>= 1) != 0) { /* Handle trailing bits. */
1135 TRef tmp = emitir(IRTN(IR_MUL), ref, ref);
1136 for (; k != 1; k >>= 1) {
1137 if (k & 1)
1138 ref = emitir(IRTN(IR_MUL), ref, tmp);
1139 tmp = emitir(IRTN(IR_MUL), tmp, tmp);
1140 }
1141 ref = emitir(IRTN(IR_MUL), ref, tmp);
1142 }
1143 return ref;
1144} 1123}
1145 1124
1146/* -- Simplify conversions ------------------------------------------------ */ 1125/* -- Simplify conversions ------------------------------------------------ */