mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-03-13 05:55:18 +00:00
FFI: Split up 64 bit x^k helper into signed/unsigned.
This commit is contained in:
parent
cd9b8f90e2
commit
07d8a53b39
@ -184,7 +184,12 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
|
|||||||
else
|
else
|
||||||
*up = u0 % u1;
|
*up = u0 % u1;
|
||||||
break;
|
break;
|
||||||
case MM_pow: *up = lj_carith_powi64(u0, u1, (id == CTID_UINT64)); break;
|
case MM_pow:
|
||||||
|
if (id == CTID_INT64)
|
||||||
|
*up = (uint64_t)lj_carith_powi64((int64_t)u0, (int64_t)u1);
|
||||||
|
else
|
||||||
|
*up = lj_carith_powu64(u0, u1);
|
||||||
|
break;
|
||||||
case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
|
case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
|
||||||
default: lua_assert(0); break;
|
default: lua_assert(0); break;
|
||||||
}
|
}
|
||||||
@ -225,24 +230,12 @@ int lj_carith_op(lua_State *L, MMS mm)
|
|||||||
|
|
||||||
/* -- 64 bit integer arithmetic helpers ----------------------------------- */
|
/* -- 64 bit integer arithmetic helpers ----------------------------------- */
|
||||||
|
|
||||||
/* 64 bit integer x^k. */
|
/* Unsigned 64 bit x^k. */
|
||||||
uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned)
|
uint64_t lj_carith_powu64(uint64_t x, uint64_t k)
|
||||||
{
|
{
|
||||||
uint64_t y = 0;
|
uint64_t y;
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (!isunsigned) {
|
|
||||||
if ((int64_t)k < 0) {
|
|
||||||
if (x == 0)
|
|
||||||
return U64x(7fffffff,ffffffff);
|
|
||||||
else if (x == 1)
|
|
||||||
return 1;
|
|
||||||
else if ((int64_t)x == -1)
|
|
||||||
return (k & 1) ? -1 : 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (; (k & 1) == 0; k >>= 1) x *= x;
|
for (; (k & 1) == 0; k >>= 1) x *= x;
|
||||||
y = x;
|
y = x;
|
||||||
if ((k >>= 1) != 0) {
|
if ((k >>= 1) != 0) {
|
||||||
@ -257,4 +250,22 @@ uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned)
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signed 64 bit x^k. */
|
||||||
|
int64_t lj_carith_powi64(int64_t x, int64_t k)
|
||||||
|
{
|
||||||
|
if (k == 0)
|
||||||
|
return 1;
|
||||||
|
if (k < 0) {
|
||||||
|
if (x == 0)
|
||||||
|
return U64x(7fffffff,ffffffff);
|
||||||
|
else if (x == 1)
|
||||||
|
return 1;
|
||||||
|
else if (x == -1)
|
||||||
|
return (k & 1) ? -1 : 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int64_t)lj_carith_powu64((uint64_t)x, (uint64_t)k);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
|
LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
|
||||||
|
|
||||||
LJ_FUNC uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned);
|
LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k);
|
||||||
|
LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -689,8 +689,8 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
|
|||||||
J->postproc = LJ_POST_FIXGUARD;
|
J->postproc = LJ_POST_FIXGUARD;
|
||||||
return TREF_TRUE;
|
return TREF_TRUE;
|
||||||
} else if (mm == MM_pow) {
|
} else if (mm == MM_pow) {
|
||||||
tr = lj_ir_call(J, IRCALL_lj_carith_powi64, sp[0], sp[1],
|
tr = lj_ir_call(J, dt == IRT_I64 ? IRCALL_lj_carith_powi64 :
|
||||||
lj_ir_kint(J, (int)dt-(int)IRT_I64));
|
IRCALL_lj_carith_powu64, sp[0], sp[1]);
|
||||||
} else {
|
} else {
|
||||||
if (mm == MM_div || mm == MM_mod)
|
if (mm == MM_div || mm == MM_mod)
|
||||||
return 0; /* NYI: integer div, mod. */
|
return 0; /* NYI: integer div, mod. */
|
||||||
|
@ -251,11 +251,13 @@ typedef struct CCallInfo {
|
|||||||
#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */
|
#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */
|
||||||
#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */
|
#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */
|
||||||
#define CCI_FASTCALL 0x0800 /* Fastcall convention. */
|
#define CCI_FASTCALL 0x0800 /* Fastcall convention. */
|
||||||
|
#define CCI_STACK64 0x1000 /* Needs 64 bits per argument. */
|
||||||
|
|
||||||
/* Function definitions for CALL* instructions. */
|
/* Function definitions for CALL* instructions. */
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
#define IRCALLDEF_FFI(_) \
|
#define IRCALLDEF_FFI(_) \
|
||||||
_(lj_carith_powi64, 3, N, U64, CCI_NOFPRCLOBBER)
|
_(lj_carith_powi64, 2, N, I64, CCI_STACK64|CCI_NOFPRCLOBBER) \
|
||||||
|
_(lj_carith_powu64, 2, N, U64, CCI_STACK64|CCI_NOFPRCLOBBER)
|
||||||
#else
|
#else
|
||||||
#define IRCALLDEF_FFI(_)
|
#define IRCALLDEF_FFI(_)
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user