mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-12 17:24:09 +00:00
Simplify helper routines for soft-float targets. Add POW rejoin.
This commit is contained in:
parent
ae3179926a
commit
625ef8626f
@ -2003,16 +2003,6 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| eors CARG2, CARG1, RB, lsl #1
|
| eors CARG2, CARG1, RB, lsl #1
|
||||||
| rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
|
| rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
|
||||||
| bx lr
|
| bx lr
|
||||||
|
|
|
||||||
|->vm_powi:
|
|
||||||
#if LJ_HASJIT
|
|
||||||
| NYI
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|->vm_foldfpm:
|
|
||||||
#if LJ_HASJIT
|
|
||||||
| NYI
|
|
||||||
#endif
|
|
||||||
|
|
|
|
||||||
|// Callable from C: double lj_vm_foldarith(double x, double y, int op)
|
|// Callable from C: double lj_vm_foldarith(double x, double y, int op)
|
||||||
|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
|
|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
|
||||||
|
67
src/lj_ir.c
67
src/lj_ir.c
@ -37,6 +37,72 @@
|
|||||||
/* Pass IR on to next optimization in chain (FOLD). */
|
/* Pass IR on to next optimization in chain (FOLD). */
|
||||||
#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
|
#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
|
||||||
|
|
||||||
|
/* -- Helper functions for generated machine code ------------------------- */
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
/* Android doesn't have log2(). Oh well. */
|
||||||
|
#define log2 lj_vm_log2
|
||||||
|
static double lj_vm_log2(double a)
|
||||||
|
{
|
||||||
|
return log(a) * 1.4426950408889634074;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !LJ_TARGET_X86ORX64
|
||||||
|
/* Unsigned x^k. */
|
||||||
|
static double lj_vm_powui(double x, uint32_t k)
|
||||||
|
{
|
||||||
|
double y;
|
||||||
|
lua_assert(k != 0);
|
||||||
|
for (; (k & 1) == 0; k >>= 1) x *= x;
|
||||||
|
y = x;
|
||||||
|
if ((k >>= 1) != 0) {
|
||||||
|
for (;;) {
|
||||||
|
x *= x;
|
||||||
|
if (k == 1) break;
|
||||||
|
if (k & 1) y *= x;
|
||||||
|
k >>= 1;
|
||||||
|
}
|
||||||
|
y *= x;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signed x^k. */
|
||||||
|
static double lj_vm_powi(double x, int32_t k)
|
||||||
|
{
|
||||||
|
if (k > 1)
|
||||||
|
return lj_vm_powui(x, (uint32_t)k);
|
||||||
|
else if (k == 1)
|
||||||
|
return x;
|
||||||
|
else if (k == 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 1.0 / lj_vm_powui(x, (uint32_t)-k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes fpm(x) for extended math functions. */
|
||||||
|
double lj_vm_foldfpm(double x, int fpm)
|
||||||
|
{
|
||||||
|
switch (fpm) {
|
||||||
|
case IRFPM_FLOOR: return lj_vm_floor(x);
|
||||||
|
case IRFPM_CEIL: return lj_vm_ceil(x);
|
||||||
|
case IRFPM_TRUNC: return lj_vm_trunc(x);
|
||||||
|
case IRFPM_SQRT: return sqrt(x);
|
||||||
|
case IRFPM_EXP: return exp(x);
|
||||||
|
case IRFPM_EXP2: return exp2(x);
|
||||||
|
case IRFPM_LOG: return log(x);
|
||||||
|
case IRFPM_LOG2: return log2(x);
|
||||||
|
case IRFPM_LOG10: return log10(x);
|
||||||
|
case IRFPM_SIN: return sin(x);
|
||||||
|
case IRFPM_COS: return cos(x);
|
||||||
|
case IRFPM_TAN: return tan(x);
|
||||||
|
default: lua_assert(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* -- IR tables ----------------------------------------------------------- */
|
/* -- IR tables ----------------------------------------------------------- */
|
||||||
|
|
||||||
/* IR instruction modes. */
|
/* IR instruction modes. */
|
||||||
@ -55,7 +121,6 @@ IRCALLDEF(IRCALLCI)
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* -- IR emitter ---------------------------------------------------------- */
|
/* -- IR emitter ---------------------------------------------------------- */
|
||||||
|
|
||||||
/* Grow IR buffer at the top. */
|
/* Grow IR buffer at the top. */
|
||||||
|
@ -191,6 +191,7 @@ static void split_ir(jit_State *J)
|
|||||||
|
|
||||||
/* Remove all IR instructions, but retain IR constants. */
|
/* Remove all IR instructions, but retain IR constants. */
|
||||||
J->cur.nins = REF_FIRST;
|
J->cur.nins = REF_FIRST;
|
||||||
|
J->loopref = 0;
|
||||||
|
|
||||||
/* Process constants and fixed references. */
|
/* Process constants and fixed references. */
|
||||||
for (ref = nk; ref <= REF_BASE; ref++) {
|
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);
|
hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi);
|
||||||
break;
|
break;
|
||||||
case IR_FPMATH:
|
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);
|
hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||||
break;
|
break;
|
||||||
case IR_ATAN2:
|
case IR_ATAN2:
|
||||||
|
@ -56,10 +56,9 @@ LJ_ASMF void lj_vm_exp2(void);
|
|||||||
LJ_ASMF void lj_vm_pow_sse(void);
|
LJ_ASMF void lj_vm_pow_sse(void);
|
||||||
LJ_ASMF void lj_vm_powi_sse(void);
|
LJ_ASMF void lj_vm_powi_sse(void);
|
||||||
#else
|
#else
|
||||||
LJ_ASMF void lj_vm_floor(void);
|
LJ_ASMF double lj_vm_floor(double);
|
||||||
LJ_ASMF void lj_vm_ceil(void);
|
LJ_ASMF double lj_vm_ceil(double);
|
||||||
LJ_ASMF void lj_vm_trunc(void);
|
LJ_ASMF double lj_vm_trunc(double);
|
||||||
LJ_ASMF void lj_vm_powi(void);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user