diff options
author | Mike Pall <mike> | 2011-05-26 18:01:55 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-05-26 18:01:55 +0200 |
commit | 625ef8626fcd400a65a270654ba056c48aae0e56 (patch) | |
tree | 8771a89c581511afbf27a0431c9f4bd4adbc9697 /src/lj_opt_split.c | |
parent | ae3179926af3deca671437c978375b39df6350e1 (diff) | |
download | luajit2-625ef8626fcd400a65a270654ba056c48aae0e56.tar.gz |
Simplify helper routines for soft-float targets. Add POW rejoin.
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) /* Remove all IR instructions, but retain IR constants. */ J->cur.nins = REF_FIRST; + J->loopref = 0; /* Process constants and fixed references. */ for (ref = nk; ref <= REF_BASE; ref++) { @@ -243,6 +244,25 @@ static void split_ir(jit_State *J) hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi); break; case IR_FPMATH: + /* Try to rejoin pow from EXP2, MUL and LOG2. */ + if (nir->op2 == IRFPM_EXP2 && nir->op1 > J->loopref) { + IRIns *irp = IR(nir->op1); + if (irp->o == IR_CALLN && irp->op2 == IRCALL_softfp_mul) { + IRIns *irm4 = IR(irp->op1); + IRIns *irm3 = IR(irm4->op1); + IRIns *irm12 = IR(irm3->op1); + IRIns *irl1 = IR(irm12->op1); + if (irm12->op1 > J->loopref && irl1->o == IR_CALLN && + irl1->op2 == IRCALL_log2) { + IRRef tmp = irl1->op1; /* Recycle first two args from LOG2. */ + tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, irm3->op2); + tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, irm4->op2); + ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_pow); + hi = split_emit(J, IRT(IR_HIOP, LJ_SOFTFP), tmp, tmp); + break; + } + } + } hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2); break; case IR_ATAN2: |