diff options
Diffstat (limited to 'src/lj_ir.c')
-rw-r--r-- | src/lj_ir.c | 67 |
1 files changed, 66 insertions, 1 deletions
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. */ |