diff options
Diffstat (limited to 'src/lj_opt_split.c')
-rw-r--r-- | src/lj_opt_split.c | 20 |
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: |