mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
From Lua 5.2: Add math.log(x, base).
This commit is contained in:
parent
0d62e2e1ab
commit
0561a56938
@ -33,7 +33,6 @@ LJLIB_ASM(math_sqrt) LJLIB_REC(math_unary IRFPM_SQRT)
|
||||
lj_lib_checknum(L, 1);
|
||||
return FFH_RETRY;
|
||||
}
|
||||
LJLIB_ASM_(math_log) LJLIB_REC(math_unary IRFPM_LOG)
|
||||
LJLIB_ASM_(math_log10) LJLIB_REC(math_unary IRFPM_LOG10)
|
||||
LJLIB_ASM_(math_exp) LJLIB_REC(math_unary IRFPM_EXP)
|
||||
LJLIB_ASM_(math_sin) LJLIB_REC(math_unary IRFPM_SIN)
|
||||
@ -48,6 +47,22 @@ LJLIB_ASM_(math_tanh) LJLIB_REC(math_htrig IRCALL_tanh)
|
||||
LJLIB_ASM_(math_frexp)
|
||||
LJLIB_ASM_(math_modf) LJLIB_REC(.)
|
||||
|
||||
LJLIB_ASM(math_log) LJLIB_REC(math_log)
|
||||
{
|
||||
double x = lj_lib_checknum(L, 1);
|
||||
if (L->base+1 < L->top) {
|
||||
double y = lj_lib_checknum(L, 2);
|
||||
#ifdef LUAJIT_NO_LOG2
|
||||
x = log(x); y = 1.0 / log(y);
|
||||
#else
|
||||
x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y);
|
||||
#endif
|
||||
setnumV(L->base-1, x*y); /* Do NOT join the expression to x / y. */
|
||||
return FFH_RES(1);
|
||||
}
|
||||
return FFH_RETRY;
|
||||
}
|
||||
|
||||
LJLIB_PUSH(57.29577951308232)
|
||||
LJLIB_ASM_(math_deg) LJLIB_REC(math_degrad)
|
||||
|
||||
|
@ -447,6 +447,28 @@ static void LJ_FASTCALL recff_math_unary(jit_State *J, RecordFFData *rd)
|
||||
J->base[0] = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, J->base[0]), rd->data);
|
||||
}
|
||||
|
||||
/* Record math.log. */
|
||||
static void LJ_FASTCALL recff_math_log(jit_State *J, RecordFFData *rd)
|
||||
{
|
||||
TRef tr = lj_ir_tonum(J, J->base[0]);
|
||||
if (J->base[1]) {
|
||||
#ifdef LUAJIT_NO_LOG2
|
||||
uint32_t fpm = IRFPM_LOG;
|
||||
#else
|
||||
uint32_t fpm = IRFPM_LOG2;
|
||||
#endif
|
||||
TRef trb = lj_ir_tonum(J, J->base[1]);
|
||||
tr = emitir(IRTN(IR_FPMATH), tr, fpm);
|
||||
trb = emitir(IRTN(IR_FPMATH), trb, fpm);
|
||||
trb = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), trb);
|
||||
tr = emitir(IRTN(IR_MUL), tr, trb);
|
||||
} else {
|
||||
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_LOG);
|
||||
}
|
||||
J->base[0] = tr;
|
||||
UNUSED(rd);
|
||||
}
|
||||
|
||||
/* Record math.atan2. */
|
||||
static void LJ_FASTCALL recff_math_atan2(jit_State *J, RecordFFData *rd)
|
||||
{
|
||||
|
10
src/lj_vm.h
10
src/lj_vm.h
@ -60,6 +60,11 @@ LJ_ASMF double lj_vm_floor_hf(double);
|
||||
LJ_ASMF double lj_vm_ceil_hf(double);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(LUAJIT_NO_LOG2) || LJ_TARGET_X86ORX64
|
||||
LJ_ASMF double lj_vm_log2(double);
|
||||
#else
|
||||
#define lj_vm_log2 log2
|
||||
#endif
|
||||
|
||||
#if LJ_HASJIT
|
||||
#if LJ_TARGET_X86ORX64
|
||||
@ -80,11 +85,6 @@ LJ_ASMF double lj_vm_trunc_hf(double);
|
||||
#endif
|
||||
#endif
|
||||
LJ_ASMF double lj_vm_powi(double, int32_t);
|
||||
#ifdef LUAJIT_NO_LOG2
|
||||
LJ_ASMF double lj_vm_log2(double);
|
||||
#else
|
||||
#define lj_vm_log2 log2
|
||||
#endif
|
||||
#ifdef LUAJIT_NO_EXP2
|
||||
LJ_ASMF double lj_vm_exp2(double);
|
||||
#else
|
||||
|
@ -1468,7 +1468,28 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| math_extern sqrt
|
||||
|.endif
|
||||
|
|
||||
| math_extern log
|
||||
|.ffunc math_log
|
||||
|.if HFABI
|
||||
| ldr CARG2, [BASE, #4]
|
||||
| cmp NARGS8:RC, #8 // Need exactly 1 argument.
|
||||
| vldr d0, [BASE]
|
||||
| bne ->fff_fallback
|
||||
|.else
|
||||
| ldrd CARG12, [BASE]
|
||||
| cmp NARGS8:RC, #8 // Need exactly 1 argument.
|
||||
| bne ->fff_fallback
|
||||
|.endif
|
||||
| checktp CARG2, LJ_TISNUM
|
||||
| bhs ->fff_fallback
|
||||
| .IOS mov RA, BASE
|
||||
| bl extern log
|
||||
| .IOS mov BASE, RA
|
||||
|.if HFABI
|
||||
| b ->fff_resd
|
||||
|.else
|
||||
| b ->fff_restv
|
||||
|.endif
|
||||
|
|
||||
| math_extern log10
|
||||
| math_extern exp
|
||||
| math_extern sin
|
||||
|
@ -1486,7 +1486,19 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| math_round floor
|
||||
| math_round ceil
|
||||
|
|
||||
| math_extern log
|
||||
|.ffunc math_log
|
||||
| lw CARG3, HI(BASE)
|
||||
| li AT, 8
|
||||
| bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument.
|
||||
|. load_got log
|
||||
| sltiu AT, CARG3, LJ_TISNUM
|
||||
| beqz AT, ->fff_fallback
|
||||
|. nop
|
||||
| call_extern
|
||||
|. ldc1 FARG1, 0(BASE)
|
||||
| b ->fff_resn
|
||||
|. nop
|
||||
|
|
||||
| math_extern log10
|
||||
| math_extern exp
|
||||
| math_extern sin
|
||||
|
@ -1804,7 +1804,16 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|.else
|
||||
| math_extern sqrt
|
||||
|.endif
|
||||
| math_extern log
|
||||
|
|
||||
|.ffunc math_log
|
||||
| cmplwi NARGS8:RC, 8
|
||||
| lwz CARG3, 0(BASE)
|
||||
| lfd FARG1, 0(BASE)
|
||||
| bne ->fff_fallback // Need exactly 1 argument.
|
||||
| checknum CARG3; bge ->fff_fallback
|
||||
| blex log
|
||||
| b ->fff_resn
|
||||
|
|
||||
| math_extern log10
|
||||
| math_extern exp
|
||||
| math_extern sin
|
||||
|
@ -1426,7 +1426,18 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| math_round ceil
|
||||
|
|
||||
| math_extern sqrt
|
||||
| math_extern log
|
||||
|
|
||||
|.ffunc math_log
|
||||
| cmplwi NARGS8:RC, 8
|
||||
| evldd CARG2, 0(BASE)
|
||||
| bne ->fff_fallback // Need exactly 1 argument.
|
||||
| checknum CARG2
|
||||
| evmergehi CARG1, CARG2, CARG2
|
||||
| checkfail ->fff_fallback
|
||||
| bl extern log
|
||||
| evmergelo CRET1, CRET1, CRET2
|
||||
| b ->fff_restv
|
||||
|
|
||||
| math_extern log10
|
||||
| math_extern exp
|
||||
| math_extern sin
|
||||
|
@ -2045,7 +2045,12 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|.else
|
||||
|.ffunc_n math_sqrt; fsqrt; jmp ->fff_resn
|
||||
|.endif
|
||||
|.ffunc_n math_log, fldln2; fyl2x; jmp ->fff_resn
|
||||
|
|
||||
|.ffunc math_log
|
||||
| cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
|
||||
| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
|
||||
| fldln2; fld qword [BASE]; fyl2x; jmp ->fff_resn
|
||||
|
|
||||
|.ffunc_n math_log10, fldlg2; fyl2x; jmp ->fff_resn
|
||||
|.ffunc_n math_exp; call ->vm_exp_x87; jmp ->fff_resn
|
||||
|
|
||||
@ -3157,6 +3162,29 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| ret
|
||||
|.endif
|
||||
|
|
||||
|// FP log2(x). Called by math.log(x, base).
|
||||
|->vm_log2:
|
||||
|.if X64WIN
|
||||
| movsd qword [rsp+8], xmm0 // Use scratch area.
|
||||
| fld1
|
||||
| fld qword [rsp+8]
|
||||
| fyl2x
|
||||
| fstp qword [rsp+8]
|
||||
| movsd xmm0, qword [rsp+8]
|
||||
|.elif X64
|
||||
| movsd qword [rsp-8], xmm0 // Use red zone.
|
||||
| fld1
|
||||
| fld qword [rsp-8]
|
||||
| fyl2x
|
||||
| fstp qword [rsp-8]
|
||||
| movsd xmm0, qword [rsp-8]
|
||||
|.else
|
||||
| fld1
|
||||
| fld qword [esp+4]
|
||||
| fyl2x
|
||||
|.endif
|
||||
| ret
|
||||
|
|
||||
|// 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!
|
||||
|
Loading…
Reference in New Issue
Block a user