|
@@ -30,11 +30,51 @@ LJ_FUNCA double lj_wrap_sinh(double x) { return sinh(x); }
|
|
|
LJ_FUNCA double lj_wrap_cosh(double x) { return cosh(x); }
|
|
|
LJ_FUNCA double lj_wrap_tanh(double x) { return tanh(x); }
|
|
|
LJ_FUNCA double lj_wrap_atan2(double x, double y) { return atan2(x, y); }
|
|
|
-LJ_FUNCA double lj_wrap_pow(double x, double y) { return pow(x, y); }
|
|
|
LJ_FUNCA double lj_wrap_fmod(double x, double y) { return fmod(x, y); }
|
|
|
#endif
|
|
|
|
|
|
-/* -- Helper functions for generated machine code ------------------------- */
|
|
|
+/* -- Helper functions ---------------------------------------------------- */
|
|
|
+
|
|
|
+/* Unsigned x^k. */
|
|
|
+static double lj_vm_powui(double x, uint32_t k)
|
|
|
+{
|
|
|
+ double y;
|
|
|
+ lj_assertX(k != 0, "pow with zero exponent");
|
|
|
+ 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. */
|
|
|
+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.0;
|
|
|
+ else
|
|
|
+ return 1.0 / lj_vm_powui(x, (uint32_t)-k);
|
|
|
+}
|
|
|
+
|
|
|
+double lj_vm_pow(double x, double y)
|
|
|
+{
|
|
|
+ int32_t k = lj_num2int(y);
|
|
|
+ if ((k >= -65536 && k <= 65536) && y == (double)k)
|
|
|
+ return lj_vm_powi(x, k);
|
|
|
+ else
|
|
|
+ return pow(x, y);
|
|
|
+}
|
|
|
|
|
|
double lj_vm_foldarith(double x, double y, int op)
|
|
|
{
|
|
@@ -44,7 +84,7 @@ double lj_vm_foldarith(double x, double y, int op)
|
|
|
case IR_MUL - IR_ADD: return x*y; break;
|
|
|
case IR_DIV - IR_ADD: return x/y; break;
|
|
|
case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
|
|
|
- case IR_POW - IR_ADD: return pow(x, y); break;
|
|
|
+ case IR_POW - IR_ADD: return lj_vm_pow(x, y); break;
|
|
|
case IR_NEG - IR_ADD: return -x; break;
|
|
|
case IR_ABS - IR_ADD: return fabs(x); break;
|
|
|
#if LJ_HASJIT
|
|
@@ -56,6 +96,8 @@ double lj_vm_foldarith(double x, double y, int op)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* -- Helper functions for generated machine code ------------------------- */
|
|
|
+
|
|
|
#if (LJ_HASJIT && !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC)) || LJ_TARGET_MIPS
|
|
|
int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
|
|
|
{
|
|
@@ -80,40 +122,6 @@ double lj_vm_log2(double a)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#if !LJ_TARGET_X86ORX64
|
|
|
-/* Unsigned x^k. */
|
|
|
-static double lj_vm_powui(double x, uint32_t k)
|
|
|
-{
|
|
|
- double y;
|
|
|
- lj_assertX(k != 0, "pow with zero exponent");
|
|
|
- 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. */
|
|
|
-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.0;
|
|
|
- else
|
|
|
- return 1.0 / lj_vm_powui(x, (uint32_t)-k);
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/* Computes fpm(x) for extended math functions. */
|
|
|
double lj_vm_foldfpm(double x, int fpm)
|
|
|
{
|