ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_vmmath.c (4083B)


      1 /*
      2 ** Math helper functions for assembler VM.
      3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
      4 */
      5 
      6 #define lj_vmmath_c
      7 #define LUA_CORE
      8 
      9 #include <errno.h>
     10 #include <math.h>
     11 
     12 #include "lj_obj.h"
     13 #include "lj_ir.h"
     14 #include "lj_vm.h"
     15 
     16 /* -- Wrapper functions --------------------------------------------------- */
     17 
     18 #if LJ_TARGET_X86 && __ELF__ && __PIC__
     19 /* Wrapper functions to deal with the ELF/x86 PIC disaster. */
     20 LJ_FUNCA double lj_wrap_log(double x) { return log(x); }
     21 LJ_FUNCA double lj_wrap_log10(double x) { return log10(x); }
     22 LJ_FUNCA double lj_wrap_exp(double x) { return exp(x); }
     23 LJ_FUNCA double lj_wrap_sin(double x) { return sin(x); }
     24 LJ_FUNCA double lj_wrap_cos(double x) { return cos(x); }
     25 LJ_FUNCA double lj_wrap_tan(double x) { return tan(x); }
     26 LJ_FUNCA double lj_wrap_asin(double x) { return asin(x); }
     27 LJ_FUNCA double lj_wrap_acos(double x) { return acos(x); }
     28 LJ_FUNCA double lj_wrap_atan(double x) { return atan(x); }
     29 LJ_FUNCA double lj_wrap_sinh(double x) { return sinh(x); }
     30 LJ_FUNCA double lj_wrap_cosh(double x) { return cosh(x); }
     31 LJ_FUNCA double lj_wrap_tanh(double x) { return tanh(x); }
     32 LJ_FUNCA double lj_wrap_atan2(double x, double y) { return atan2(x, y); }
     33 LJ_FUNCA double lj_wrap_pow(double x, double y) { return pow(x, y); }
     34 LJ_FUNCA double lj_wrap_fmod(double x, double y) { return fmod(x, y); }
     35 #endif
     36 
     37 /* -- Helper functions for generated machine code ------------------------- */
     38 
     39 double lj_vm_foldarith(double x, double y, int op)
     40 {
     41   switch (op) {
     42   case IR_ADD - IR_ADD: return x+y; break;
     43   case IR_SUB - IR_ADD: return x-y; break;
     44   case IR_MUL - IR_ADD: return x*y; break;
     45   case IR_DIV - IR_ADD: return x/y; break;
     46   case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
     47   case IR_POW - IR_ADD: return pow(x, y); break;
     48   case IR_NEG - IR_ADD: return -x; break;
     49   case IR_ABS - IR_ADD: return fabs(x); break;
     50 #if LJ_HASJIT
     51   case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
     52   case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
     53   case IR_MIN - IR_ADD: return x > y ? y : x; break;
     54   case IR_MAX - IR_ADD: return x < y ? y : x; break;
     55 #endif
     56   default: return x;
     57   }
     58 }
     59 
     60 #if (LJ_HASJIT && !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC)) || LJ_TARGET_MIPS
     61 int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
     62 {
     63   uint32_t y, ua, ub;
     64   lua_assert(b != 0);  /* This must be checked before using this function. */
     65   ua = a < 0 ? (uint32_t)-a : (uint32_t)a;
     66   ub = b < 0 ? (uint32_t)-b : (uint32_t)b;
     67   y = ua % ub;
     68   if (y != 0 && (a^b) < 0) y = y - ub;
     69   if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y;
     70   return (int32_t)y;
     71 }
     72 #endif
     73 
     74 #if LJ_HASJIT
     75 
     76 #ifdef LUAJIT_NO_LOG2
     77 double lj_vm_log2(double a)
     78 {
     79   return log(a) * 1.4426950408889634074;
     80 }
     81 #endif
     82 
     83 #ifdef LUAJIT_NO_EXP2
     84 double lj_vm_exp2(double a)
     85 {
     86   return exp(a * 0.6931471805599453);
     87 }
     88 #endif
     89 
     90 #if !LJ_TARGET_X86ORX64
     91 /* Unsigned x^k. */
     92 static double lj_vm_powui(double x, uint32_t k)
     93 {
     94   double y;
     95   lua_assert(k != 0);
     96   for (; (k & 1) == 0; k >>= 1) x *= x;
     97   y = x;
     98   if ((k >>= 1) != 0) {
     99     for (;;) {
    100       x *= x;
    101       if (k == 1) break;
    102       if (k & 1) y *= x;
    103       k >>= 1;
    104     }
    105     y *= x;
    106   }
    107   return y;
    108 }
    109 
    110 /* Signed x^k. */
    111 double lj_vm_powi(double x, int32_t k)
    112 {
    113   if (k > 1)
    114     return lj_vm_powui(x, (uint32_t)k);
    115   else if (k == 1)
    116     return x;
    117   else if (k == 0)
    118     return 1.0;
    119   else
    120     return 1.0 / lj_vm_powui(x, (uint32_t)-k);
    121 }
    122 #endif
    123 
    124 /* Computes fpm(x) for extended math functions. */
    125 double lj_vm_foldfpm(double x, int fpm)
    126 {
    127   switch (fpm) {
    128   case IRFPM_FLOOR: return lj_vm_floor(x);
    129   case IRFPM_CEIL: return lj_vm_ceil(x);
    130   case IRFPM_TRUNC: return lj_vm_trunc(x);
    131   case IRFPM_SQRT: return sqrt(x);
    132   case IRFPM_EXP: return exp(x);
    133   case IRFPM_EXP2: return lj_vm_exp2(x);
    134   case IRFPM_LOG: return log(x);
    135   case IRFPM_LOG2: return lj_vm_log2(x);
    136   case IRFPM_LOG10: return log10(x);
    137   case IRFPM_SIN: return sin(x);
    138   case IRFPM_COS: return cos(x);
    139   case IRFPM_TAN: return tan(x);
    140   default: lua_assert(0);
    141   }
    142   return 0;
    143 }
    144 
    145 #if LJ_HASFFI
    146 int lj_vm_errno(void)
    147 {
    148   return errno;
    149 }
    150 #endif
    151 
    152 #endif