src/lj_vmmath.c - luajit-2.0-src

Functions defined

Macros defined

Source code

  1. /*
  2. ** Math helper functions for assembler VM.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. */

  5. #define lj_vmmath_c
  6. #define LUA_CORE

  7. #include <errno.h>
  8. #include <math.h>

  9. #include "lj_obj.h"
  10. #include "lj_ir.h"
  11. #include "lj_vm.h"

  12. /* -- Wrapper functions --------------------------------------------------- */

  13. #if LJ_TARGET_X86 && __ELF__ && __PIC__
  14. /* Wrapper functions to deal with the ELF/x86 PIC disaster. */
  15. LJ_FUNCA double lj_wrap_log(double x) { return log(x); }
  16. LJ_FUNCA double lj_wrap_log10(double x) { return log10(x); }
  17. LJ_FUNCA double lj_wrap_exp(double x) { return exp(x); }
  18. LJ_FUNCA double lj_wrap_sin(double x) { return sin(x); }
  19. LJ_FUNCA double lj_wrap_cos(double x) { return cos(x); }
  20. LJ_FUNCA double lj_wrap_tan(double x) { return tan(x); }
  21. LJ_FUNCA double lj_wrap_asin(double x) { return asin(x); }
  22. LJ_FUNCA double lj_wrap_acos(double x) { return acos(x); }
  23. LJ_FUNCA double lj_wrap_atan(double x) { return atan(x); }
  24. LJ_FUNCA double lj_wrap_sinh(double x) { return sinh(x); }
  25. LJ_FUNCA double lj_wrap_cosh(double x) { return cosh(x); }
  26. LJ_FUNCA double lj_wrap_tanh(double x) { return tanh(x); }
  27. LJ_FUNCA double lj_wrap_atan2(double x, double y) { return atan2(x, y); }
  28. LJ_FUNCA double lj_wrap_pow(double x, double y) { return pow(x, y); }
  29. LJ_FUNCA double lj_wrap_fmod(double x, double y) { return fmod(x, y); }
  30. #endif

  31. /* -- Helper functions for generated machine code ------------------------- */

  32. double lj_vm_foldarith(double x, double y, int op)
  33. {
  34.   switch (op) {
  35.   case IR_ADD - IR_ADD: return x+y; break;
  36.   case IR_SUB - IR_ADD: return x-y; break;
  37.   case IR_MUL - IR_ADD: return x*y; break;
  38.   case IR_DIV - IR_ADD: return x/y; break;
  39.   case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
  40.   case IR_POW - IR_ADD: return pow(x, y); break;
  41.   case IR_NEG - IR_ADD: return -x; break;
  42.   case IR_ABS - IR_ADD: return fabs(x); break;
  43. #if LJ_HASJIT
  44.   case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
  45.   case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
  46.   case IR_MIN - IR_ADD: return x > y ? y : x; break;
  47.   case IR_MAX - IR_ADD: return x < y ? y : x; break;
  48. #endif
  49.   default: return x;
  50.   }
  51. }

  52. #if LJ_HASJIT

  53. #ifdef LUAJIT_NO_LOG2
  54. double lj_vm_log2(double a)
  55. {
  56.   return log(a) * 1.4426950408889634074;
  57. }
  58. #endif

  59. #ifdef LUAJIT_NO_EXP2
  60. double lj_vm_exp2(double a)
  61. {
  62.   return exp(a * 0.6931471805599453);
  63. }
  64. #endif

  65. #if !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC)
  66. int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
  67. {
  68.   uint32_t y, ua, ub;
  69.   lua_assert(b != 0);  /* This must be checked before using this function. */
  70.   ua = a < 0 ? (uint32_t)-a : (uint32_t)a;
  71.   ub = b < 0 ? (uint32_t)-b : (uint32_t)b;
  72.   y = ua % ub;
  73.   if (y != 0 && (a^b) < 0) y = y - ub;
  74.   if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y;
  75.   return (int32_t)y;
  76. }
  77. #endif

  78. #if !LJ_TARGET_X86ORX64
  79. /* Unsigned x^k. */
  80. static double lj_vm_powui(double x, uint32_t k)
  81. {
  82.   double y;
  83.   lua_assert(k != 0);
  84.   for (; (k & 1) == 0; k >>= 1) x *= x;
  85.   y = x;
  86.   if ((k >>= 1) != 0) {
  87.     for (;;) {
  88.       x *= x;
  89.       if (k == 1) break;
  90.       if (k & 1) y *= x;
  91.       k >>= 1;
  92.     }
  93.     y *= x;
  94.   }
  95.   return y;
  96. }

  97. /* Signed x^k. */
  98. double lj_vm_powi(double x, int32_t k)
  99. {
  100.   if (k > 1)
  101.     return lj_vm_powui(x, (uint32_t)k);
  102.   else if (k == 1)
  103.     return x;
  104.   else if (k == 0)
  105.     return 1.0;
  106.   else
  107.     return 1.0 / lj_vm_powui(x, (uint32_t)-k);
  108. }
  109. #endif

  110. /* Computes fpm(x) for extended math functions. */
  111. double lj_vm_foldfpm(double x, int fpm)
  112. {
  113.   switch (fpm) {
  114.   case IRFPM_FLOOR: return lj_vm_floor(x);
  115.   case IRFPM_CEIL: return lj_vm_ceil(x);
  116.   case IRFPM_TRUNC: return lj_vm_trunc(x);
  117.   case IRFPM_SQRT: return sqrt(x);
  118.   case IRFPM_EXP: return exp(x);
  119.   case IRFPM_EXP2: return lj_vm_exp2(x);
  120.   case IRFPM_LOG: return log(x);
  121.   case IRFPM_LOG2: return lj_vm_log2(x);
  122.   case IRFPM_LOG10: return log10(x);
  123.   case IRFPM_SIN: return sin(x);
  124.   case IRFPM_COS: return cos(x);
  125.   case IRFPM_TAN: return tan(x);
  126.   default: lua_assert(0);
  127.   }
  128.   return 0;
  129. }

  130. #if LJ_HASFFI
  131. int lj_vm_errno(void)
  132. {
  133.   return errno;
  134. }
  135. #endif

  136. #endif