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 | |
parent | ae3179926af3deca671437c978375b39df6350e1 (diff) | |
download | luajit-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.dasc | 10 | ||||
-rw-r--r-- | src/lj_ir.c | 67 | ||||
-rw-r--r-- | src/lj_opt_split.c | 20 | ||||
-rw-r--r-- | src/lj_vm.h | 7 |
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 | ||
45 | static 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. */ | ||
53 | static 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. */ | ||
72 | static 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. */ | ||
85 | double 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); | |||
56 | LJ_ASMF void lj_vm_pow_sse(void); | 56 | LJ_ASMF void lj_vm_pow_sse(void); |
57 | LJ_ASMF void lj_vm_powi_sse(void); | 57 | LJ_ASMF void lj_vm_powi_sse(void); |
58 | #else | 58 | #else |
59 | LJ_ASMF void lj_vm_floor(void); | 59 | LJ_ASMF double lj_vm_floor(double); |
60 | LJ_ASMF void lj_vm_ceil(void); | 60 | LJ_ASMF double lj_vm_ceil(double); |
61 | LJ_ASMF void lj_vm_trunc(void); | 61 | LJ_ASMF double lj_vm_trunc(double); |
62 | LJ_ASMF void lj_vm_powi(void); | ||
63 | #endif | 62 | #endif |
64 | #endif | 63 | #endif |
65 | 64 | ||