aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-05-26 18:01:55 +0200
committerMike Pall <mike>2011-05-26 18:01:55 +0200
commit625ef8626fcd400a65a270654ba056c48aae0e56 (patch)
tree8771a89c581511afbf27a0431c9f4bd4adbc9697
parentae3179926af3deca671437c978375b39df6350e1 (diff)
downloadluajit-625ef8626fcd400a65a270654ba056c48aae0e56.tar.gz
luajit-625ef8626fcd400a65a270654ba056c48aae0e56.tar.bz2
luajit-625ef8626fcd400a65a270654ba056c48aae0e56.zip
Simplify helper routines for soft-float targets. Add POW rejoin.
-rw-r--r--src/buildvm_arm.dasc10
-rw-r--r--src/lj_ir.c67
-rw-r--r--src/lj_opt_split.c20
-rw-r--r--src/lj_vm.h7
4 files changed, 89 insertions, 15 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc
index 4d30a95b..f2b08ed9 100644
--- a/src/buildvm_arm.dasc
+++ b/src/buildvm_arm.dasc
@@ -2004,16 +2004,6 @@ static void build_subroutines(BuildCtx *ctx)
2004 | rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y 2004 | rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
2005 | bx lr 2005 | bx lr
2006 | 2006 |
2007 |->vm_powi:
2008#if LJ_HASJIT
2009 | NYI
2010#endif
2011 |
2012 |->vm_foldfpm:
2013#if LJ_HASJIT
2014 | NYI
2015#endif
2016 |
2017 |// Callable from C: double lj_vm_foldarith(double x, double y, int op) 2007 |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
2018 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -) 2008 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
2019 |// and basic math functions. ORDER ARITH 2009 |// and basic math functions. ORDER ARITH
diff --git a/src/lj_ir.c b/src/lj_ir.c
index 59ffcfde..749b7f12 100644
--- a/src/lj_ir.c
+++ b/src/lj_ir.c
@@ -37,6 +37,72 @@
37/* Pass IR on to next optimization in chain (FOLD). */ 37/* Pass IR on to next optimization in chain (FOLD). */
38#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) 38#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
39 39
40/* -- Helper functions for generated machine code ------------------------- */
41
42#ifdef __ANDROID__
43/* Android doesn't have log2(). Oh well. */
44#define log2 lj_vm_log2
45static double lj_vm_log2(double a)
46{
47 return log(a) * 1.4426950408889634074;
48}
49#endif
50
51#if !LJ_TARGET_X86ORX64
52/* Unsigned x^k. */
53static double lj_vm_powui(double x, uint32_t k)
54{
55 double y;
56 lua_assert(k != 0);
57 for (; (k & 1) == 0; k >>= 1) x *= x;
58 y = x;
59 if ((k >>= 1) != 0) {
60 for (;;) {
61 x *= x;
62 if (k == 1) break;
63 if (k & 1) y *= x;
64 k >>= 1;
65 }
66 y *= x;
67 }
68 return y;
69}
70
71/* Signed x^k. */
72static double lj_vm_powi(double x, int32_t k)
73{
74 if (k > 1)
75 return lj_vm_powui(x, (uint32_t)k);
76 else if (k == 1)
77 return x;
78 else if (k == 0)
79 return 1;
80 else
81 return 1.0 / lj_vm_powui(x, (uint32_t)-k);
82}
83
84/* Computes fpm(x) for extended math functions. */
85double lj_vm_foldfpm(double x, int fpm)
86{
87 switch (fpm) {
88 case IRFPM_FLOOR: return lj_vm_floor(x);
89 case IRFPM_CEIL: return lj_vm_ceil(x);
90 case IRFPM_TRUNC: return lj_vm_trunc(x);
91 case IRFPM_SQRT: return sqrt(x);
92 case IRFPM_EXP: return exp(x);
93 case IRFPM_EXP2: return exp2(x);
94 case IRFPM_LOG: return log(x);
95 case IRFPM_LOG2: return log2(x);
96 case IRFPM_LOG10: return log10(x);
97 case IRFPM_SIN: return sin(x);
98 case IRFPM_COS: return cos(x);
99 case IRFPM_TAN: return tan(x);
100 default: lua_assert(0);
101 }
102 return 0;
103}
104#endif
105
40/* -- IR tables ----------------------------------------------------------- */ 106/* -- IR tables ----------------------------------------------------------- */
41 107
42/* IR instruction modes. */ 108/* IR instruction modes. */
@@ -55,7 +121,6 @@ IRCALLDEF(IRCALLCI)
55 { NULL, 0 } 121 { NULL, 0 }
56}; 122};
57 123
58
59/* -- IR emitter ---------------------------------------------------------- */ 124/* -- IR emitter ---------------------------------------------------------- */
60 125
61/* Grow IR buffer at the top. */ 126/* Grow IR buffer at the top. */
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:
diff --git a/src/lj_vm.h b/src/lj_vm.h
index 55b92c83..649280d0 100644
--- a/src/lj_vm.h
+++ b/src/lj_vm.h
@@ -56,10 +56,9 @@ LJ_ASMF void lj_vm_exp2(void);
56LJ_ASMF void lj_vm_pow_sse(void); 56LJ_ASMF void lj_vm_pow_sse(void);
57LJ_ASMF void lj_vm_powi_sse(void); 57LJ_ASMF void lj_vm_powi_sse(void);
58#else 58#else
59LJ_ASMF void lj_vm_floor(void); 59LJ_ASMF double lj_vm_floor(double);
60LJ_ASMF void lj_vm_ceil(void); 60LJ_ASMF double lj_vm_ceil(double);
61LJ_ASMF void lj_vm_trunc(void); 61LJ_ASMF double lj_vm_trunc(double);
62LJ_ASMF void lj_vm_powi(void);
63#endif 62#endif
64#endif 63#endif
65 64