Move math helpers to lj_vmmath.c. Add missing log2/exp2 for Symbian.

This commit is contained in:
Mike Pall 2011-06-03 17:12:46 +02:00
parent 77bb8de93d
commit eec28aa9fd
14 changed files with 160 additions and 119 deletions

View File

@ -359,7 +359,7 @@ LJLIB_C= $(LJLIB_O:.o=.c)
LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o \
lj_state.o lj_dispatch.o lj_vmevent.o lj_api.o \
lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_api.o \
lj_lex.o lj_parse.o \
lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
lj_opt_dce.o lj_opt_loop.o lj_opt_split.o \

View File

@ -166,22 +166,24 @@ lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
lj_vm.h lj_vmevent.h
lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_vm.h
ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c \
lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_state.c lj_lex.h \
lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c lj_vmevent.h lj_api.c \
lj_parse.h lj_lex.c lualib.h lj_parse.c lj_ctype.c lj_cdata.c lj_cconv.h \
lj_cconv.c lj_ccall.c lj_ccall.h lj_carith.c lj_carith.h lj_clib.c \
lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h \
lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \
lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_mcode.c \
lj_mcode.h lj_snap.c lj_target.h lj_target_*.h lj_record.c lj_record.h \
lj_ffrecord.h lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h \
lj_asm.c lj_asm.h lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h \
lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c lj_libdef.h lib_math.c \
lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c \
lib_bit.c lib_jit.c lib_ffi.c lib_init.c
lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c lj_vmevent.h lj_vmmath.c \
lj_api.c lj_parse.h lj_lex.c lualib.h lj_parse.c lj_ctype.c lj_cdata.c \
lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_carith.c lj_carith.h \
lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c \
lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \
lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \
lj_mcode.c lj_mcode.h lj_snap.c lj_target.h lj_target_*.h lj_record.c \
lj_record.h lj_ffrecord.h lj_crecord.c lj_crecord.h lj_ffrecord.c \
lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h lj_asm_*.h lj_trace.c \
lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c lj_libdef.h \
lib_math.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c \
lib_debug.c lib_bit.c lib_jit.c lib_ffi.c lib_init.c
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h

View File

@ -879,7 +879,7 @@ enum {
GLOB_ff_math_log,
GLOB_ff_math_log10,
GLOB_ff_math_exp,
GLOB_vm_exp,
GLOB_vm_exp_x87,
GLOB_ff_math_sin,
GLOB_ff_math_cos,
GLOB_ff_math_tan,
@ -939,7 +939,7 @@ enum {
GLOB_vm_ceil_sse,
GLOB_vm_trunc_sse,
GLOB_vm_mod,
GLOB_vm_exp2,
GLOB_vm_exp2_x87,
GLOB_vm_exp2raw,
GLOB_vm_pow_sse,
GLOB_vm_powi_sse,
@ -1040,7 +1040,7 @@ static const char *const globnames[] = {
"ff_math_log",
"ff_math_log10",
"ff_math_exp",
"vm_exp",
"vm_exp_x87",
"ff_math_sin",
"ff_math_cos",
"ff_math_tan",
@ -1100,7 +1100,7 @@ static const char *const globnames[] = {
"vm_ceil_sse",
"vm_trunc_sse",
"vm_mod",
"vm_exp2",
"vm_exp2_x87",
"vm_exp2raw",
"vm_pow_sse",
"vm_powi_sse",
@ -1132,9 +1132,9 @@ static const char *const extnames[] = {
"lj_tab_next",
"lj_tab_getinth@8",
"lj_ffh_coroutine_wrap_err@8",
"lj_wrapper_sinh",
"lj_wrapper_cosh",
"lj_wrapper_tanh",
"lj_vm_sinh",
"lj_vm_cosh",
"lj_vm_tanh",
"lj_str_new",
"lj_tab_len@4",
"lj_gc_step@4",

View File

@ -876,7 +876,7 @@ enum {
GLOB_ff_math_log,
GLOB_ff_math_log10,
GLOB_ff_math_exp,
GLOB_vm_exp,
GLOB_vm_exp_x87,
GLOB_ff_math_sin,
GLOB_ff_math_cos,
GLOB_ff_math_tan,
@ -936,7 +936,7 @@ enum {
GLOB_vm_ceil_sse,
GLOB_vm_trunc_sse,
GLOB_vm_mod,
GLOB_vm_exp2,
GLOB_vm_exp2_x87,
GLOB_vm_exp2raw,
GLOB_vm_pow_sse,
GLOB_vm_powi_sse,
@ -1037,7 +1037,7 @@ static const char *const globnames[] = {
"ff_math_log",
"ff_math_log10",
"ff_math_exp",
"vm_exp",
"vm_exp_x87",
"ff_math_sin",
"ff_math_cos",
"ff_math_tan",
@ -1097,7 +1097,7 @@ static const char *const globnames[] = {
"vm_ceil_sse",
"vm_trunc_sse",
"vm_mod",
"vm_exp2",
"vm_exp2_x87",
"vm_exp2raw",
"vm_pow_sse",
"vm_powi_sse",
@ -1128,9 +1128,9 @@ static const char *const extnames[] = {
"lj_tab_next",
"lj_tab_getinth@8",
"lj_ffh_coroutine_wrap_err@8",
"lj_wrapper_sinh",
"lj_wrapper_cosh",
"lj_wrapper_tanh",
"lj_vm_sinh",
"lj_vm_cosh",
"lj_vm_tanh",
"lj_str_new",
"lj_tab_len@4",
"lj_gc_step@4",

View File

@ -2028,7 +2028,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
}
|.ffunc_n math_log, fldln2; fyl2x; jmp ->fff_resn
|.ffunc_n math_log10, fldlg2; fyl2x; jmp ->fff_resn
|.ffunc_n math_exp; call ->vm_exp; jmp ->fff_resn
|.ffunc_n math_exp; call ->vm_exp_x87; jmp ->fff_resn
|
|.ffunc_n math_sin; fsin; jmp ->fff_resn
|.ffunc_n math_cos; fcos; jmp ->fff_resn
@ -2055,7 +2055,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| .endif
||}
| mov RB, BASE
| call extern lj_wrapper_ .. func
| call extern lj_vm_ .. func
| mov BASE, RB
| .if X64
| jmp ->fff_resxmm0
@ -3169,9 +3169,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
|// FP exponentiation e^x and 2^x. Called by math.exp fast function and
|// from JIT code. Arg/ret on x87 stack. No int/xmm regs modified.
|// Caveat: needs 3 slots on x87 stack!
|->vm_exp:
|->vm_exp_x87:
| fldl2e; fmulp st1 // e^x ==> 2^(x*log2(e))
|->vm_exp2:
|->vm_exp2_x87:
| .if X64WIN
| .define expscratch, dword [rsp+8] // Use scratch area.
| .elif X64
@ -3444,11 +3444,11 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| cmp fpmop, 5; ja >2
| .if X64WIN; pop rax; .endif
| je >1
| call ->vm_exp
| call ->vm_exp_x87
| .if X64WIN; push rax; .endif
| jmp >7
|1:
| call ->vm_exp2
| call ->vm_exp2_x87
| .if X64WIN; push rax; .endif
| jmp >7
|2: ; cmp fpmop, 7; je >1; ja >2
@ -3487,7 +3487,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| fld qword [esp+4]
| ret
|2: ; fld qword [esp+4]
| cmp fpmop, 5; jb ->vm_exp; je ->vm_exp2
| cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
|2: ; cmp fpmop, 7; je >1; ja >2
| fldln2; fxch; fyl2x; ret
|1: ; fld1; fxch; fyl2x; ret
@ -3505,7 +3505,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| cmp fpmop, 1; jb ->vm_floor; je ->vm_ceil
| cmp fpmop, 3; jb ->vm_trunc; ja >2
| fsqrt; ret
|2: ; cmp fpmop, 5; jb ->vm_exp; je ->vm_exp2
|2: ; cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
| cmp fpmop, 7; je >1; ja >2
| fldln2; fxch; fyl2x; ret
|1: ; fld1; fxch; fyl2x; ret

View File

@ -925,7 +925,7 @@ enum {
GLOB_ff_math_log,
GLOB_ff_math_log10,
GLOB_ff_math_exp,
GLOB_vm_exp,
GLOB_vm_exp_x87,
GLOB_ff_math_sin,
GLOB_ff_math_cos,
GLOB_ff_math_tan,
@ -985,7 +985,7 @@ enum {
GLOB_vm_ceil_sse,
GLOB_vm_trunc_sse,
GLOB_vm_mod,
GLOB_vm_exp2,
GLOB_vm_exp2_x87,
GLOB_vm_exp2raw,
GLOB_vm_pow_sse,
GLOB_vm_powi_sse,
@ -1086,7 +1086,7 @@ static const char *const globnames[] = {
"ff_math_log",
"ff_math_log10",
"ff_math_exp",
"vm_exp",
"vm_exp_x87",
"ff_math_sin",
"ff_math_cos",
"ff_math_tan",
@ -1146,7 +1146,7 @@ static const char *const globnames[] = {
"vm_ceil_sse",
"vm_trunc_sse",
"vm_mod",
"vm_exp2",
"vm_exp2_x87",
"vm_exp2raw",
"vm_pow_sse",
"vm_powi_sse",
@ -1177,9 +1177,9 @@ static const char *const extnames[] = {
"lj_tab_next",
"lj_tab_getinth@8",
"lj_ffh_coroutine_wrap_err@8",
"lj_wrapper_sinh",
"lj_wrapper_cosh",
"lj_wrapper_tanh",
"lj_vm_sinh",
"lj_vm_cosh",
"lj_vm_tanh",
"lj_str_new",
"lj_tab_len@4",
"lj_gc_step@4",

View File

@ -84,10 +84,6 @@ LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
LJLIB_PUSH(1e310) LJLIB_SET(huge)
LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); }
LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); }
LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); }
/* ------------------------------------------------------------------------ */
/* This implements a Tausworthe PRNG with period 2^223. Based on:

View File

@ -1591,8 +1591,8 @@ static void asm_fpmath(ASMState *as, IRIns *ir)
}
emit_rmro(as, XO_FSTPq, XOg_FSTPq, RID_ESP, ofs);
switch (fpm) { /* st0 = lj_vm_*(st0) */
case IRFPM_EXP: emit_call(as, lj_vm_exp); break;
case IRFPM_EXP2: emit_call(as, lj_vm_exp2); break;
case IRFPM_EXP: emit_call(as, lj_vm_exp_x87); break;
case IRFPM_EXP2: emit_call(as, lj_vm_exp2_x87); break;
case IRFPM_SIN: emit_x87op(as, XI_FSIN); break;
case IRFPM_COS: emit_x87op(as, XI_FCOS); break;
case IRFPM_TAN: emit_x87op(as, XI_FPOP); emit_x87op(as, XI_FPTAN); break;

View File

@ -37,72 +37,6 @@
/* Pass IR on to next optimization in chain (FOLD). */
#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
/* -- Helper functions for generated machine code ------------------------- */
#ifdef __ANDROID__
/* Android doesn't have log2(). Oh well. */
#define log2 lj_vm_log2
static double lj_vm_log2(double a)
{
return log(a) * 1.4426950408889634074;
}
#endif
#if !LJ_TARGET_X86ORX64
/* Unsigned x^k. */
static double lj_vm_powui(double x, uint32_t k)
{
double y;
lua_assert(k != 0);
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. */
static 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;
else
return 1.0 / lj_vm_powui(x, (uint32_t)-k);
}
/* Computes fpm(x) for extended math functions. */
double lj_vm_foldfpm(double x, int fpm)
{
switch (fpm) {
case IRFPM_FLOOR: return lj_vm_floor(x);
case IRFPM_CEIL: return lj_vm_ceil(x);
case IRFPM_TRUNC: return lj_vm_trunc(x);
case IRFPM_SQRT: return sqrt(x);
case IRFPM_EXP: return exp(x);
case IRFPM_EXP2: return exp2(x);
case IRFPM_LOG: return log(x);
case IRFPM_LOG2: return log2(x);
case IRFPM_LOG10: return log10(x);
case IRFPM_SIN: return sin(x);
case IRFPM_COS: return cos(x);
case IRFPM_TAN: return tan(x);
default: lua_assert(0);
}
return 0;
}
#endif
/* -- IR tables ----------------------------------------------------------- */
/* IR instruction modes. */

View File

@ -91,9 +91,9 @@ typedef struct CCallInfo {
_(lj_vm_trunc, ARG1_FP, N, NUM, 0) \
_(sqrt, ARG1_FP, N, NUM, 0) \
_(exp, ARG1_FP, N, NUM, 0) \
_(exp2, ARG1_FP, N, NUM, 0) \
_(lj_vm_exp2, ARG1_FP, N, NUM, 0) \
_(log, ARG1_FP, N, NUM, 0) \
_(log2, ARG1_FP, N, NUM, 0) \
_(lj_vm_log2, ARG1_FP, N, NUM, 0) \
_(log10, ARG1_FP, N, NUM, 0) \
_(sin, ARG1_FP, N, NUM, 0) \
_(cos, ARG1_FP, N, NUM, 0) \

View File

@ -274,7 +274,7 @@ static void split_ir(jit_State *J)
IRIns *irm12 = IR(irm3->op1);
IRIns *irl1 = IR(irm12->op1);
if (irm12->op1 > J->loopref && irl1->o == IR_CALLN &&
irl1->op2 == IRCALL_log2) {
irl1->op2 == IRCALL_lj_vm_log2) {
IRRef tmp = irl1->op1; /* Recycle first two args from LOG2. */
IRRef arg3 = irm3->op2, arg4 = irm4->op2;
J->cur.nins--;

View File

@ -51,14 +51,25 @@ LJ_ASMF void lj_vm_exit_interp(void);
LJ_ASMF void lj_vm_floor_sse(void);
LJ_ASMF void lj_vm_ceil_sse(void);
LJ_ASMF void lj_vm_trunc_sse(void);
LJ_ASMF void lj_vm_exp(void);
LJ_ASMF void lj_vm_exp2(void);
LJ_ASMF void lj_vm_exp_x87(void);
LJ_ASMF void lj_vm_exp2_x87(void);
LJ_ASMF void lj_vm_pow_sse(void);
LJ_ASMF void lj_vm_powi_sse(void);
#else
LJ_ASMF double lj_vm_floor(double);
LJ_ASMF double lj_vm_ceil(double);
LJ_ASMF double lj_vm_trunc(double);
LJ_ASMF double lj_vm_powi(double, int32_t);
#if defined(__ANDROID__) || defined(__symbian__)
LJ_ASMF double lj_vm_log2(double);
#else
#define lj_vm_log2 log2
#endif
#if defined(__symbian__)
LJ_ASMF double lj_vm_exp2(double);
#else
#define lj_vm_exp2 exp2
#endif
#endif
#endif

97
src/lj_vmmath.c Normal file
View File

@ -0,0 +1,97 @@
/*
** Math helper functions for assembler VM.
** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
*/
#define lj_vmmath_c
#define LUA_CORE
#include <math.h>
#include "lj_obj.h"
#if LJ_HASJIT
#include "lj_ir.h"
#endif
#include "lj_vm.h"
/* -- Helper functions for generated machine code ------------------------- */
#if LJ_TARGET_X86ORX64
/* Wrapper functions to avoid linker issues on OSX. */
LJ_FUNCA double lj_vm_sinh(double x) { return sinh(x); }
LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); }
LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); }
#endif
#if LJ_HASJIT
#if defined(__ANDROID__) || defined(__symbian__)
double lj_vm_log2(double a)
{
return log(a) * 1.4426950408889634074;
}
#endif
#if defined(__symbian__)
double lj_vm_exp2(double a)
{
return exp(a * 0.6931471805599453);
}
#endif
#if !LJ_TARGET_X86ORX64
/* Unsigned x^k. */
static double lj_vm_powui(double x, uint32_t k)
{
double y;
lua_assert(k != 0);
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;
else
return 1.0 / lj_vm_powui(x, (uint32_t)-k);
}
/* Computes fpm(x) for extended math functions. */
double lj_vm_foldfpm(double x, int fpm)
{
switch (fpm) {
case IRFPM_FLOOR: return lj_vm_floor(x);
case IRFPM_CEIL: return lj_vm_ceil(x);
case IRFPM_TRUNC: return lj_vm_trunc(x);
case IRFPM_SQRT: return sqrt(x);
case IRFPM_EXP: return exp(x);
case IRFPM_EXP2: return lj_vm_exp2(x);
case IRFPM_LOG: return log(x);
case IRFPM_LOG2: return lj_vm_log2(x);
case IRFPM_LOG10: return log10(x);
case IRFPM_SIN: return sin(x);
case IRFPM_COS: return cos(x);
case IRFPM_TAN: return tan(x);
default: lua_assert(0);
}
return 0;
}
#endif
#endif

View File

@ -41,6 +41,7 @@
#include "lj_state.c"
#include "lj_dispatch.c"
#include "lj_vmevent.c"
#include "lj_vmmath.c"
#include "lj_api.c"
#include "lj_lex.c"
#include "lj_parse.c"