summaryrefslogtreecommitdiff
path: root/src/lj_opt_split.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_opt_split.c')
-rw-r--r--src/lj_opt_split.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c
index 67436a65..b9fae10f 100644
--- a/src/lj_opt_split.c
+++ b/src/lj_opt_split.c
@@ -191,6 +191,7 @@ static void split_ir(jit_State *J)
191 191
192 /* Remove all IR instructions, but retain IR constants. */ 192 /* Remove all IR instructions, but retain IR constants. */
193 J->cur.nins = REF_FIRST; 193 J->cur.nins = REF_FIRST;
194 J->loopref = 0;
194 195
195 /* Process constants and fixed references. */ 196 /* Process constants and fixed references. */
196 for (ref = nk; ref <= REF_BASE; ref++) { 197 for (ref = nk; ref <= REF_BASE; ref++) {
@@ -243,6 +244,25 @@ static void split_ir(jit_State *J)
243 hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi); 244 hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi);
244 break; 245 break;
245 case IR_FPMATH: 246 case IR_FPMATH:
247 /* Try to rejoin pow from EXP2, MUL and LOG2. */
248 if (nir->op2 == IRFPM_EXP2 && nir->op1 > J->loopref) {
249 IRIns *irp = IR(nir->op1);
250 if (irp->o == IR_CALLN && irp->op2 == IRCALL_softfp_mul) {
251 IRIns *irm4 = IR(irp->op1);
252 IRIns *irm3 = IR(irm4->op1);
253 IRIns *irm12 = IR(irm3->op1);
254 IRIns *irl1 = IR(irm12->op1);
255 if (irm12->op1 > J->loopref && irl1->o == IR_CALLN &&
256 irl1->op2 == IRCALL_log2) {
257 IRRef tmp = irl1->op1; /* Recycle first two args from LOG2. */
258 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, irm3->op2);
259 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, irm4->op2);
260 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_pow);
261 hi = split_emit(J, IRT(IR_HIOP, LJ_SOFTFP), tmp, tmp);
262 break;
263 }
264 }
265 }
246 hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2); 266 hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2);
247 break; 267 break;
248 case IR_ATAN2: 268 case IR_ATAN2: