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 | ||
