mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
Merge remote-tracking branch 'upstream/v2.1' into HEAD
This commit is contained in:
commit
48c3bd676c
@ -864,7 +864,7 @@ place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead.
|
||||
<p>
|
||||
The main use for parameterized types are libraries implementing abstract
|
||||
data types
|
||||
(<a href="http://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">»</span> example</a>),
|
||||
(<a href="https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8">example</a>),
|
||||
similar to what can be achieved with C++ template metaprogramming.
|
||||
Another use case are derived types of anonymous structs, which avoids
|
||||
pollution of the global struct namespace.
|
||||
|
@ -209,7 +209,7 @@ TARGET_CC= $(STATIC_CC)
|
||||
TARGET_STCC= $(STATIC_CC)
|
||||
TARGET_DYNCC= $(DYNAMIC_CC)
|
||||
TARGET_LD= $(CROSS)$(CC)
|
||||
TARGET_AR= $(CROSS)ar rcus 2>/dev/null
|
||||
TARGET_AR= $(CROSS)ar rcus
|
||||
TARGET_STRIP= $(CROSS)strip
|
||||
|
||||
TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
|
||||
@ -308,6 +308,7 @@ ifeq (Windows,$(TARGET_SYS))
|
||||
TARGET_XSHLDFLAGS= -shared
|
||||
TARGET_DYNXLDOPTS=
|
||||
else
|
||||
TARGET_AR+= 2>/dev/null
|
||||
ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-stack-protector 2>/dev/null || echo 1))
|
||||
TARGET_XCFLAGS+= -fno-stack-protector
|
||||
endif
|
||||
|
@ -347,7 +347,7 @@ void emit_asm(BuildCtx *ctx)
|
||||
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
|
||||
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
|
||||
#endif
|
||||
#if LJ_TARGET_PPC && !LJ_TARGET_PS3
|
||||
#if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP
|
||||
/* Hard-float ABI. */
|
||||
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
|
||||
#endif
|
||||
|
@ -343,7 +343,7 @@ static void *CALL_MMAP(size_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
#if LJ_64 && !LJ_GC64 && ((defined(__FreeBSD__) && __FreeBSD__ < 10) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
|
@ -254,6 +254,29 @@
|
||||
#else
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_NAME "ppc"
|
||||
|
||||
#if !defined(LJ_ARCH_HASFPU)
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#define LJ_ARCH_HASFPU 0
|
||||
#else
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ABI_SOFTFP)
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#else
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
#else
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
#endif
|
||||
|
||||
#define LJ_TARGET_PPC 1
|
||||
@ -262,7 +285,6 @@
|
||||
#define LJ_TARGET_MASKSHIFT 0
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
|
||||
#if LJ_TARGET_CONSOLE
|
||||
#define LJ_ARCH_PPC32ON64 1
|
||||
@ -337,9 +359,6 @@
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_TARGET_MIPS32 1
|
||||
#else
|
||||
#if LJ_ABI_SOFTFP || !LJ_ARCH_HASFPU
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_TARGET_MIPS64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
@ -418,16 +437,13 @@
|
||||
#error "No support for ILP32 model on ARM64"
|
||||
#endif
|
||||
#elif LJ_TARGET_PPC
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#error "No support for PowerPC CPUs without double-precision FPU"
|
||||
#endif
|
||||
#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#error "No support for little-endian PPC32"
|
||||
#endif
|
||||
#if LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_BE
|
||||
#error "No support for big-endian PPC64"
|
||||
#endif
|
||||
#ifdef __NO_FPRS__
|
||||
#if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT)
|
||||
#error "No support for PPC/e500 anymore (use LuaJIT 2.0)"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS32
|
||||
@ -512,6 +528,7 @@
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
|
||||
#define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32)
|
||||
|
||||
#if LJ_ARCH_ENDIAN == LUAJIT_BE
|
||||
#define LJ_LE 0
|
||||
|
@ -338,7 +338,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
||||
ra_modified(as, r);
|
||||
ir->r = RID_INIT; /* Do not keep any hint. */
|
||||
RA_DBGX((as, "remat $i $r", ir, r));
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
if (ir->o == IR_KNUM) {
|
||||
emit_loadk64(as, r, ir);
|
||||
} else
|
||||
@ -1305,7 +1305,7 @@ static void asm_call(ASMState *as, IRIns *ir)
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
|
||||
@ -1652,10 +1652,10 @@ static void asm_ir(ASMState *as, IRIns *ir)
|
||||
case IR_MUL: asm_mul(as, ir); break;
|
||||
case IR_MOD: asm_mod(as, ir); break;
|
||||
case IR_NEG: asm_neg(as, ir); break;
|
||||
#if LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
case IR_DIV: case IR_POW: case IR_ABS:
|
||||
case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP. */
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP32. */
|
||||
break;
|
||||
#else
|
||||
case IR_DIV: asm_div(as, ir); break;
|
||||
|
@ -65,10 +65,9 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
|
||||
static void asm_sparejump_setup(ASMState *as)
|
||||
{
|
||||
MCode *mxp = as->mcbot;
|
||||
/* Assumes sizeof(MCLink) == 8. */
|
||||
if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == 8) {
|
||||
if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {
|
||||
lua_assert(MIPSI_NOP == 0);
|
||||
memset(mxp+2, 0, MIPS_SPAREJUMP*8);
|
||||
memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode));
|
||||
mxp += MIPS_SPAREJUMP*2;
|
||||
lua_assert(mxp < as->mctop);
|
||||
lj_mcode_sync(as->mcbot, mxp);
|
||||
@ -291,7 +290,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
{
|
||||
ra_leftov(as, gpr, ref);
|
||||
gpr++;
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_SOFTFP
|
||||
fpr++;
|
||||
#endif
|
||||
}
|
||||
@ -302,7 +301,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
emit_spstore(as, ir, r, ofs);
|
||||
ofs += irt_isnum(ir->t) ? 8 : 4;
|
||||
#else
|
||||
emit_spstore(as, ir, r, ofs + ((LJ_BE && (LJ_SOFTFP || r < RID_MAX_GPR) && !irt_is64(ir->t)) ? 4 : 0));
|
||||
emit_spstore(as, ir, r, ofs + ((LJ_BE && !irt_isfp(ir->t) && !irt_is64(ir->t)) ? 4 : 0));
|
||||
ofs += 8;
|
||||
#endif
|
||||
}
|
||||
@ -313,7 +312,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
#endif
|
||||
if (gpr <= REGARG_LASTGPR) {
|
||||
gpr++;
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_SOFTFP
|
||||
fpr++;
|
||||
#endif
|
||||
} else {
|
||||
@ -462,12 +461,36 @@ static void asm_tobit(ASMState *as, IRIns *ir)
|
||||
emit_tg(as, MIPSI_MFC1, dest, tmp);
|
||||
emit_fgh(as, MIPSI_ADD_D, tmp, left, right);
|
||||
}
|
||||
#elif LJ_64 /* && LJ_SOFTFP */
|
||||
static void asm_tointg(ASMState *as, IRIns *ir, Reg r)
|
||||
{
|
||||
/* The modified regs must match with the *.dasc implementation. */
|
||||
RegSet drop = RID2RSET(REGARG_FIRSTGPR)|RID2RSET(RID_RET)|RID2RSET(RID_RET+1)|
|
||||
RID2RSET(RID_R1)|RID2RSET(RID_R12);
|
||||
if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);
|
||||
ra_evictset(as, drop);
|
||||
/* Return values are in RID_RET (converted value) and RID_RET+1 (status). */
|
||||
ra_destreg(as, ir, RID_RET);
|
||||
asm_guard(as, MIPSI_BNE, RID_RET+1, RID_ZERO);
|
||||
emit_call(as, (void *)lj_ir_callinfo[IRCALL_lj_vm_tointg].func, 0);
|
||||
if (r == RID_NONE)
|
||||
ra_leftov(as, REGARG_FIRSTGPR, ir->op1);
|
||||
else if (r != REGARG_FIRSTGPR)
|
||||
emit_move(as, REGARG_FIRSTGPR, r);
|
||||
}
|
||||
|
||||
static void asm_tobit(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
emit_dta(as, MIPSI_SLL, dest, dest, 0);
|
||||
asm_callid(as, ir, IRCALL_lj_vm_tobit);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_conv(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
int stfp = (st == IRT_NUM || st == IRT_FLOAT);
|
||||
#endif
|
||||
#if LJ_64
|
||||
@ -478,12 +501,13 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
lua_assert(!(irt_isint64(ir->t) ||
|
||||
(st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
|
||||
#endif
|
||||
#if LJ_32 && LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
/* FP conversions are handled by SPLIT. */
|
||||
lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
|
||||
/* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
|
||||
#else
|
||||
lua_assert(irt_type(ir->t) != st);
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isfp(ir->t)) {
|
||||
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||
if (stfp) { /* FP to FP conversion. */
|
||||
@ -609,6 +633,42 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
}
|
||||
}
|
||||
} else
|
||||
#else
|
||||
if (irt_isfp(ir->t)) {
|
||||
#if LJ_64 && LJ_HASFFI
|
||||
if (stfp) { /* FP to FP conversion. */
|
||||
asm_callid(as, ir, irt_isnum(ir->t) ? IRCALL_softfp_f2d :
|
||||
IRCALL_softfp_d2f);
|
||||
} else { /* Integer to FP conversion. */
|
||||
IRCallID cid = ((IRT_IS64 >> st) & 1) ?
|
||||
(irt_isnum(ir->t) ?
|
||||
(st == IRT_I64 ? IRCALL_fp64_l2d : IRCALL_fp64_ul2d) :
|
||||
(st == IRT_I64 ? IRCALL_fp64_l2f : IRCALL_fp64_ul2f)) :
|
||||
(irt_isnum(ir->t) ?
|
||||
(st == IRT_INT ? IRCALL_softfp_i2d : IRCALL_softfp_ui2d) :
|
||||
(st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f));
|
||||
asm_callid(as, ir, cid);
|
||||
}
|
||||
#else
|
||||
asm_callid(as, ir, IRCALL_softfp_i2d);
|
||||
#endif
|
||||
} else if (stfp) { /* FP to integer conversion. */
|
||||
if (irt_isguard(ir->t)) {
|
||||
/* Checked conversions are only supported from number to int. */
|
||||
lua_assert(irt_isint(ir->t) && st == IRT_NUM);
|
||||
asm_tointg(as, ir, RID_NONE);
|
||||
} else {
|
||||
IRCallID cid = irt_is64(ir->t) ?
|
||||
((st == IRT_NUM) ?
|
||||
(irt_isi64(ir->t) ? IRCALL_fp64_d2l : IRCALL_fp64_d2ul) :
|
||||
(irt_isi64(ir->t) ? IRCALL_fp64_f2l : IRCALL_fp64_f2ul)) :
|
||||
((st == IRT_NUM) ?
|
||||
(irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) :
|
||||
(irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui));
|
||||
asm_callid(as, ir, cid);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
@ -666,7 +726,7 @@ static void asm_strto(ASMState *as, IRIns *ir)
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];
|
||||
IRRef args[2];
|
||||
int32_t ofs = 0;
|
||||
#if LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
ra_evictset(as, RSET_SCRATCH);
|
||||
if (ra_used(ir)) {
|
||||
if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&
|
||||
@ -807,7 +867,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
MCLabel l_end, l_loop, l_next;
|
||||
|
||||
rset_clear(allow, tab);
|
||||
#if LJ_32 && LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
if (!isk) {
|
||||
key = ra_alloc1(as, refkey, allow);
|
||||
rset_clear(allow, key);
|
||||
@ -827,7 +887,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (irt_isnum(kt)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(kt)) {
|
||||
key = ra_alloc1(as, refkey, RSET_FPR);
|
||||
tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
|
||||
} else if (!irt_ispri(kt)) {
|
||||
@ -883,6 +943,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);
|
||||
emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);
|
||||
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
||||
} else if (LJ_SOFTFP && irt_isnum(kt)) {
|
||||
emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);
|
||||
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
||||
} else if (irt_isaddr(kt)) {
|
||||
Reg refk = tmp2;
|
||||
if (isk) {
|
||||
@ -961,7 +1024,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31);
|
||||
if (irt_isnum(kt)) {
|
||||
emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1);
|
||||
emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 0);
|
||||
emit_dta(as, MIPSI_DSRA32, tmp1, LJ_SOFTFP ? key : tmp1, 0);
|
||||
emit_dta(as, MIPSI_SLL, tmp2, LJ_SOFTFP ? key : tmp1, 0);
|
||||
#if !LJ_SOFTFP
|
||||
emit_tg(as, MIPSI_DMFC1, tmp1, key);
|
||||
@ -1124,7 +1187,7 @@ static MIPSIns asm_fxloadins(IRIns *ir)
|
||||
case IRT_U8: return MIPSI_LBU;
|
||||
case IRT_I16: return MIPSI_LH;
|
||||
case IRT_U16: return MIPSI_LHU;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_LDC1;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1;
|
||||
case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1;
|
||||
default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW;
|
||||
}
|
||||
@ -1135,7 +1198,7 @@ static MIPSIns asm_fxstoreins(IRIns *ir)
|
||||
switch (irt_type(ir->t)) {
|
||||
case IRT_I8: case IRT_U8: return MIPSI_SB;
|
||||
case IRT_I16: case IRT_U16: return MIPSI_SH;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_SDC1;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1;
|
||||
case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1;
|
||||
default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW;
|
||||
}
|
||||
@ -1200,7 +1263,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
|
||||
|
||||
static void asm_ahuvload(ASMState *as, IRIns *ir)
|
||||
{
|
||||
int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP);
|
||||
int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP);
|
||||
Reg dest = RID_NONE, type = RID_TMP, idx;
|
||||
RegSet allow = RSET_GPR;
|
||||
int32_t ofs = 0;
|
||||
@ -1213,7 +1276,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
|
||||
}
|
||||
}
|
||||
if (ra_used(ir)) {
|
||||
lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
|
||||
lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
|
||||
irt_isint(ir->t) || irt_isaddr(ir->t));
|
||||
dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
|
||||
rset_clear(allow, dest);
|
||||
@ -1262,10 +1325,10 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
|
||||
int32_t ofs = 0;
|
||||
if (ir->r == RID_SINK)
|
||||
return;
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
src = ra_alloc1(as, ir->op2, RSET_FPR);
|
||||
if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
|
||||
src = ra_alloc1(as, ir->op2, LJ_SOFTFP ? RSET_GPR : RSET_FPR);
|
||||
idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
|
||||
emit_hsi(as, MIPSI_SDC1, src, idx, ofs);
|
||||
emit_hsi(as, LJ_SOFTFP ? MIPSI_SD : MIPSI_SDC1, src, idx, ofs);
|
||||
} else {
|
||||
#if LJ_32
|
||||
if (!irt_ispri(ir->t)) {
|
||||
@ -1313,7 +1376,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
||||
IRType1 t = ir->t;
|
||||
#if LJ_32
|
||||
int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
|
||||
int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP);
|
||||
int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP);
|
||||
if (hiop)
|
||||
t.irt = IRT_NUM;
|
||||
#else
|
||||
@ -1321,7 +1384,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
||||
#endif
|
||||
lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
|
||||
lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
|
||||
#if LJ_32 && LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */
|
||||
if (hiop && ra_used(ir+1)) {
|
||||
type = ra_dest(as, ir+1, allow);
|
||||
@ -1329,29 +1392,44 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
||||
}
|
||||
#else
|
||||
if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
|
||||
dest = ra_scratch(as, RSET_FPR);
|
||||
dest = ra_scratch(as, LJ_SOFTFP ? allow : RSET_FPR);
|
||||
asm_tointg(as, ir, dest);
|
||||
t.irt = IRT_NUM; /* Continue with a regular number type check. */
|
||||
} else
|
||||
#endif
|
||||
if (ra_used(ir)) {
|
||||
lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
|
||||
lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
|
||||
irt_isint(ir->t) || irt_isaddr(ir->t));
|
||||
dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
|
||||
rset_clear(allow, dest);
|
||||
base = ra_alloc1(as, REF_BASE, allow);
|
||||
rset_clear(allow, base);
|
||||
if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) {
|
||||
if (!LJ_SOFTFP32 && (ir->op2 & IRSLOAD_CONVERT)) {
|
||||
if (irt_isint(t)) {
|
||||
Reg tmp = ra_scratch(as, RSET_FPR);
|
||||
Reg tmp = ra_scratch(as, LJ_SOFTFP ? RSET_GPR : RSET_FPR);
|
||||
#if LJ_SOFTFP
|
||||
ra_evictset(as, rset_exclude(RSET_SCRATCH, dest));
|
||||
ra_destreg(as, ir, RID_RET);
|
||||
emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_d2i].func, 0);
|
||||
if (tmp != REGARG_FIRSTGPR)
|
||||
emit_move(as, REGARG_FIRSTGPR, tmp);
|
||||
#else
|
||||
emit_tg(as, MIPSI_MFC1, dest, tmp);
|
||||
emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp);
|
||||
#endif
|
||||
dest = tmp;
|
||||
t.irt = IRT_NUM; /* Check for original type. */
|
||||
} else {
|
||||
Reg tmp = ra_scratch(as, RSET_GPR);
|
||||
#if LJ_SOFTFP
|
||||
ra_evictset(as, rset_exclude(RSET_SCRATCH, dest));
|
||||
ra_destreg(as, ir, RID_RET);
|
||||
emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_i2d].func, 0);
|
||||
emit_dta(as, MIPSI_SLL, REGARG_FIRSTGPR, tmp, 0);
|
||||
#else
|
||||
emit_fg(as, MIPSI_CVT_D_W, dest, dest);
|
||||
emit_tg(as, MIPSI_MTC1, tmp, dest);
|
||||
#endif
|
||||
dest = tmp;
|
||||
t.irt = IRT_INT; /* Check for original type. */
|
||||
}
|
||||
@ -1400,7 +1478,7 @@ dotypecheck:
|
||||
if (irt_isnum(t)) {
|
||||
asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);
|
||||
emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM);
|
||||
if (ra_hasreg(dest))
|
||||
if (!LJ_SOFTFP && ra_hasreg(dest))
|
||||
emit_hsi(as, MIPSI_LDC1, dest, base, ofs);
|
||||
} else {
|
||||
asm_guard(as, MIPSI_BNE, RID_TMP,
|
||||
@ -1410,7 +1488,7 @@ dotypecheck:
|
||||
}
|
||||
emit_tsi(as, MIPSI_LD, type, base, ofs);
|
||||
} else if (ra_hasreg(dest)) {
|
||||
if (irt_isnum(t))
|
||||
if (!LJ_SOFTFP && irt_isnum(t))
|
||||
emit_hsi(as, MIPSI_LDC1, dest, base, ofs);
|
||||
else
|
||||
emit_tsi(as, irt_isint(t) ? MIPSI_LW : MIPSI_LD, dest, base,
|
||||
@ -1549,26 +1627,40 @@ static void asm_fpunary(ASMState *as, IRIns *ir, MIPSIns mi)
|
||||
Reg left = ra_hintalloc(as, ir->op1, dest, RSET_FPR);
|
||||
emit_fg(as, mi, dest, left);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !LJ_SOFTFP32
|
||||
static void asm_fpmath(ASMState *as, IRIns *ir)
|
||||
{
|
||||
if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
|
||||
return;
|
||||
#if !LJ_SOFTFP
|
||||
if (ir->op2 <= IRFPM_TRUNC)
|
||||
asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||
else if (ir->op2 == IRFPM_SQRT)
|
||||
asm_fpunary(as, ir, MIPSI_SQRT_D);
|
||||
else
|
||||
#endif
|
||||
asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#define asm_fpadd(as, ir) asm_fparith(as, ir, MIPSI_ADD_D)
|
||||
#define asm_fpsub(as, ir) asm_fparith(as, ir, MIPSI_SUB_D)
|
||||
#define asm_fpmul(as, ir) asm_fparith(as, ir, MIPSI_MUL_D)
|
||||
#elif LJ_64 /* && LJ_SOFTFP */
|
||||
#define asm_fpadd(as, ir) asm_callid(as, ir, IRCALL_softfp_add)
|
||||
#define asm_fpsub(as, ir) asm_callid(as, ir, IRCALL_softfp_sub)
|
||||
#define asm_fpmul(as, ir) asm_callid(as, ir, IRCALL_softfp_mul)
|
||||
#endif
|
||||
|
||||
static void asm_add(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRType1 t = ir->t;
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
if (irt_isnum(t)) {
|
||||
asm_fparith(as, ir, MIPSI_ADD_D);
|
||||
asm_fpadd(as, ir);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -1590,9 +1682,9 @@ static void asm_add(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_sub(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
if (irt_isnum(ir->t)) {
|
||||
asm_fparith(as, ir, MIPSI_SUB_D);
|
||||
asm_fpsub(as, ir);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -1606,9 +1698,9 @@ static void asm_sub(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_mul(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
if (irt_isnum(ir->t)) {
|
||||
asm_fparith(as, ir, MIPSI_MUL_D);
|
||||
asm_fpmul(as, ir);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -1635,7 +1727,7 @@ static void asm_mod(ASMState *as, IRIns *ir)
|
||||
asm_callid(as, ir, IRCALL_lj_vm_modi);
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
static void asm_pow(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if LJ_64 && LJ_HASFFI
|
||||
@ -1655,7 +1747,11 @@ static void asm_div(ASMState *as, IRIns *ir)
|
||||
IRCALL_lj_carith_divu64);
|
||||
else
|
||||
#endif
|
||||
#if !LJ_SOFTFP
|
||||
asm_fparith(as, ir, MIPSI_DIV_D);
|
||||
#else
|
||||
asm_callid(as, ir, IRCALL_softfp_div);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1665,6 +1761,13 @@ static void asm_neg(ASMState *as, IRIns *ir)
|
||||
if (irt_isnum(ir->t)) {
|
||||
asm_fpunary(as, ir, MIPSI_NEG_D);
|
||||
} else
|
||||
#elif LJ_64 /* && LJ_SOFTFP */
|
||||
if (irt_isnum(ir->t)) {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
|
||||
emit_dst(as, MIPSI_XOR, dest, left,
|
||||
ra_allock(as, 0x8000000000000000ll, rset_exclude(RSET_GPR, dest)));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
@ -1674,7 +1777,17 @@ static void asm_neg(ASMState *as, IRIns *ir)
|
||||
}
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#define asm_abs(as, ir) asm_fpunary(as, ir, MIPSI_ABS_D)
|
||||
#elif LJ_64 /* && LJ_SOFTFP */
|
||||
static void asm_abs(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
emit_tsml(as, MIPSI_DEXTM, dest, left, 30, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2)
|
||||
#define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp)
|
||||
|
||||
@ -1919,15 +2032,21 @@ static void asm_bror(ASMState *as, IRIns *ir)
|
||||
}
|
||||
}
|
||||
|
||||
#if LJ_32 && LJ_SOFTFP
|
||||
#if LJ_SOFTFP
|
||||
static void asm_sfpmin_max(ASMState *as, IRIns *ir)
|
||||
{
|
||||
CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax];
|
||||
#if LJ_64
|
||||
IRRef args[2];
|
||||
args[0] = ir->op1;
|
||||
args[1] = ir->op2;
|
||||
#else
|
||||
IRRef args[4];
|
||||
args[0^LJ_BE] = ir->op1;
|
||||
args[1^LJ_BE] = (ir+1)->op1;
|
||||
args[2^LJ_BE] = ir->op2;
|
||||
args[3^LJ_BE] = (ir+1)->op2;
|
||||
#endif
|
||||
asm_setupresult(as, ir, &ci);
|
||||
emit_call(as, (void *)ci.func, 0);
|
||||
ci.func = NULL;
|
||||
@ -1937,7 +2056,10 @@ static void asm_sfpmin_max(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
||||
{
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
|
||||
#if LJ_SOFTFP
|
||||
asm_sfpmin_max(as, ir);
|
||||
#else
|
||||
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
||||
right = (left >> 8); left &= 255;
|
||||
@ -1948,6 +2070,7 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
||||
if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
|
||||
}
|
||||
emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);
|
||||
#endif
|
||||
} else {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg right, left = ra_alloc2(as, ir, RSET_GPR);
|
||||
@ -1968,18 +2091,24 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
||||
|
||||
/* -- Comparisons --------------------------------------------------------- */
|
||||
|
||||
#if LJ_32 && LJ_SOFTFP
|
||||
#if LJ_SOFTFP
|
||||
/* SFP comparisons. */
|
||||
static void asm_sfpcomp(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
Reg r;
|
||||
#if LJ_64
|
||||
IRRef args[2];
|
||||
args[0] = ir->op1;
|
||||
args[1] = ir->op2;
|
||||
#else
|
||||
IRRef args[4];
|
||||
args[LJ_LE ? 0 : 1] = ir->op1; args[LJ_LE ? 1 : 0] = (ir+1)->op1;
|
||||
args[LJ_LE ? 2 : 3] = ir->op2; args[LJ_LE ? 3 : 2] = (ir+1)->op2;
|
||||
#endif
|
||||
|
||||
for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) {
|
||||
for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+(LJ_64?1:3); r++) {
|
||||
if (!rset_test(as->freeset, r) &&
|
||||
regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR])
|
||||
rset_clear(drop, r);
|
||||
@ -2033,11 +2162,15 @@ static void asm_comp(ASMState *as, IRIns *ir)
|
||||
{
|
||||
/* ORDER IR: LT GE LE GT ULT UGE ULE UGT. */
|
||||
IROp op = ir->o;
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
|
||||
#if LJ_SOFTFP
|
||||
asm_sfpcomp(as, ir);
|
||||
#else
|
||||
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
||||
right = (left >> 8); left &= 255;
|
||||
asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
|
||||
emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right);
|
||||
#endif
|
||||
} else {
|
||||
Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
if (op == IR_ABC) op = IR_UGT;
|
||||
@ -2069,9 +2202,13 @@ static void asm_equal(ASMState *as, IRIns *ir)
|
||||
Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ?
|
||||
RSET_FPR : RSET_GPR);
|
||||
right = (left >> 8); left &= 255;
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
|
||||
#if LJ_SOFTFP
|
||||
asm_sfpcomp(as, ir);
|
||||
#else
|
||||
asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
|
||||
emit_fgh(as, MIPSI_C_EQ_D, 0, left, right);
|
||||
#endif
|
||||
} else {
|
||||
asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right);
|
||||
}
|
||||
@ -2264,7 +2401,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
if ((sn & SNAP_NORESTORE))
|
||||
continue;
|
||||
if (irt_isnum(ir->t)) {
|
||||
#if LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
Reg tmp;
|
||||
RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
|
||||
lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */
|
||||
@ -2273,6 +2410,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
|
||||
tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow);
|
||||
emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?0:4));
|
||||
#elif LJ_SOFTFP /* && LJ_64 */
|
||||
Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
|
||||
emit_tsi(as, MIPSI_SD, src, RID_BASE, ofs);
|
||||
#else
|
||||
Reg src = ra_alloc1(as, ref, RSET_FPR);
|
||||
emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs);
|
||||
@ -2466,7 +2606,11 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
MCode tjump = MIPSI_J|(((uintptr_t)target>>2)&0x03ffffffu);
|
||||
for (p++; p < pe; p++) {
|
||||
if (*p == exitload) { /* Look for load of exit number. */
|
||||
if (((p[-1] ^ (px-p)) & 0xffffu) == 0) { /* Look for exitstub branch. */
|
||||
/* Look for exitstub branch. Yes, this covers all used branch variants. */
|
||||
if (((p[-1] ^ (px-p)) & 0xffffu) == 0 &&
|
||||
((p[-1] & 0xf0000000u) == MIPSI_BEQ ||
|
||||
(p[-1] & 0xfc1e0000u) == MIPSI_BLTZ ||
|
||||
(p[-1] & 0xffe00000u) == MIPSI_BC1F)) {
|
||||
ptrdiff_t delta = target - p;
|
||||
if (((delta + 0x8000) >> 16) == 0) { /* Patch in-range branch. */
|
||||
patchbranch:
|
||||
@ -2476,7 +2620,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
if (!cstart) cstart = p-1;
|
||||
} else { /* Branch out of range. Use spare jump slot in mcarea. */
|
||||
int i;
|
||||
for (i = 2; i < 2+MIPS_SPAREJUMP*2; i += 2) {
|
||||
for (i = (int)(sizeof(MCLink)/sizeof(MCode));
|
||||
i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2);
|
||||
i += 2) {
|
||||
if (mcarea[i] == tjump) {
|
||||
delta = mcarea+i - p;
|
||||
goto patchbranch;
|
||||
|
@ -387,6 +387,7 @@ static Reg asm_fuseloadk64(ASMState *as, IRIns *ir)
|
||||
ir->i = (int32_t)(as->mctop - as->mcbot);
|
||||
as->mcbot += 8;
|
||||
as->mclim = as->mcbot + MCLIM_REDZONE;
|
||||
lj_mcode_commitbot(as->J, as->mcbot);
|
||||
}
|
||||
as->mrm.ofs = (int32_t)mcpofs(as, as->mctop - ir->i);
|
||||
as->mrm.base = RID_RIP;
|
||||
|
@ -387,6 +387,21 @@
|
||||
#define CCALL_HANDLE_COMPLEXARG \
|
||||
/* Pass complex by value in 2 or 4 GPRs. */
|
||||
|
||||
#define CCALL_HANDLE_GPR \
|
||||
/* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
|
||||
if (ctype_isinteger(d->info) || ctype_isfp(d->info)) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
else if (ngpr + n > maxgpr) \
|
||||
ngpr = maxgpr; /* Prevent reordering. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
|
||||
#if LJ_ARCH_PPC64
|
||||
#define CCALL_HANDLE_REGARG \
|
||||
if (isva) { /* only GPRs will be used on C ellipsis operator */ \
|
||||
@ -408,21 +423,13 @@
|
||||
} \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
gpr: \
|
||||
if (n > 1) { \
|
||||
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
|
||||
if (ctype_isinteger(d->info)) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
else if (ngpr + n > maxgpr) \
|
||||
ngpr = maxgpr; /* Prevent reordering. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
CCALL_HANDLE_GPR \
|
||||
} \
|
||||
}
|
||||
#else /* 32 bits */
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR
|
||||
#else
|
||||
#define CCALL_HANDLE_REGARG \
|
||||
if (isfp) { /* Try to pass argument in FPRs. */ \
|
||||
if (nfpr + 1 <= CCALL_NARG_FPR) { \
|
||||
@ -431,25 +438,17 @@
|
||||
d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
|
||||
goto done; \
|
||||
} \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
|
||||
if (ctype_isinteger(d->info)) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
else if (ngpr + n > maxgpr) \
|
||||
ngpr = maxgpr; /* Prevent reordering. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
} else { \
|
||||
CCALL_HANDLE_GPR \
|
||||
}
|
||||
#endif
|
||||
#endif /* LJ_ABI_SOFTFP */
|
||||
#endif /* LJ_ARCH_PPC64 */
|
||||
|
||||
#if !LJ_ABI_SOFTFP
|
||||
#define CCALL_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
|
||||
#endif
|
||||
|
||||
#elif LJ_TARGET_MIPS32
|
||||
/* -- MIPS o32 calling conventions ---------------------------------------- */
|
||||
@ -1117,7 +1116,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
}
|
||||
if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
|
||||
|
||||
#if LJ_TARGET_X64 || LJ_TARGET_PPC
|
||||
#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
|
||||
cc->nfpr = nfpr; /* Required for vararg functions. */
|
||||
#endif
|
||||
cc->nsp = nsp;
|
||||
|
@ -94,9 +94,9 @@ typedef union FPRArg {
|
||||
#define CCALL_SPS_FREE 0
|
||||
#else
|
||||
#define CCALL_NARG_GPR 8
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 8)
|
||||
#define CCALL_NRET_GPR 4 /* For complex double. */
|
||||
#define CCALL_NRET_FPR 1
|
||||
#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 1)
|
||||
#define CCALL_SPS_EXTRA 4
|
||||
#define CCALL_SPS_FREE 0
|
||||
#endif
|
||||
|
@ -434,6 +434,23 @@ void lj_ccallback_mcode_free(CTState *cts)
|
||||
|
||||
#elif LJ_TARGET_PPC
|
||||
|
||||
#define CALLBACK_HANDLE_GPR \
|
||||
if (n > 1) { \
|
||||
lua_assert(((LJ_ABI_SOFTFP && ctype_isnum(cta->info)) || /* double. */ \
|
||||
ctype_isinteger(cta->info)) && n == 2); /* int64_t. */ \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
sp = &cts->cb.gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
}
|
||||
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define CALLBACK_HANDLE_REGARG \
|
||||
CALLBACK_HANDLE_GPR \
|
||||
UNUSED(isfp);
|
||||
#else
|
||||
#define CALLBACK_HANDLE_REGARG \
|
||||
if (isfp) { \
|
||||
if (nfpr + 1 <= CCALL_NARG_FPR) { \
|
||||
@ -442,20 +459,15 @@ void lj_ccallback_mcode_free(CTState *cts)
|
||||
goto done; \
|
||||
} \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
sp = &cts->cb.gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
CALLBACK_HANDLE_GPR \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !LJ_ABI_SOFTFP
|
||||
#define CALLBACK_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
*(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
|
||||
#endif
|
||||
|
||||
#elif LJ_TARGET_MIPS32
|
||||
|
||||
|
@ -212,7 +212,7 @@ static void crec_copy_emit(jit_State *J, CRecMemList *ml, MSize mlp,
|
||||
ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);
|
||||
ml[i].trofs = trofs;
|
||||
i++;
|
||||
rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1;
|
||||
rwin += (LJ_SOFTFP32 && ml[i].tp == IRT_NUM) ? 2 : 1;
|
||||
if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */
|
||||
rwin = 0;
|
||||
for ( ; j < i; j++) {
|
||||
@ -1130,7 +1130,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
|
||||
else
|
||||
tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
|
||||
}
|
||||
} else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) {
|
||||
} else if (LJ_SOFTFP32 && ctype_isfp(d->info) && d->size > 4) {
|
||||
lj_needsplit(J);
|
||||
}
|
||||
#if LJ_TARGET_X86
|
||||
|
@ -80,7 +80,6 @@ typedef unsigned int uintptr_t;
|
||||
#define LJ_MIN_SBUF 32 /* Min. string buffer length. */
|
||||
#define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */
|
||||
#define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */
|
||||
#define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */
|
||||
|
||||
/* JIT compiler limits. */
|
||||
#define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */
|
||||
|
@ -12,6 +12,8 @@ static intptr_t get_k64val(IRIns *ir)
|
||||
return (intptr_t)ir_kgc(ir);
|
||||
} else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
|
||||
return (intptr_t)ir_kptr(ir);
|
||||
} else if (LJ_SOFTFP && ir->o == IR_KNUM) {
|
||||
return (intptr_t)ir_knum(ir)->u64;
|
||||
} else {
|
||||
lua_assert(ir->o == IR_KINT || ir->o == IR_KNULL);
|
||||
return ir->i; /* Sign-extended. */
|
||||
|
@ -343,9 +343,27 @@ static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr)
|
||||
emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr));
|
||||
} else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) {
|
||||
emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr));
|
||||
} else if (!checki32((intptr_t)addr) && (xo == XO_MOV || xo == XO_MOVSD)) {
|
||||
emit_rmro(as, xo, rr, rr, 0);
|
||||
emit_loadu64(as, rr, (uintptr_t)addr);
|
||||
} else if (!checki32((intptr_t)addr)) {
|
||||
Reg ra = (rr & 15);
|
||||
if (xo != XO_MOV) {
|
||||
/* We can't allocate a register here. Use and restore DISPATCH. Ugly. */
|
||||
uint64_t dispaddr = (uintptr_t)J2GG(as->J)->dispatch;
|
||||
uint8_t i8 = xo == XO_GROUP3b ? *as->mcp++ : 0;
|
||||
ra = RID_DISPATCH;
|
||||
if (checku32(dispaddr)) {
|
||||
emit_loadi(as, ra, (int32_t)dispaddr);
|
||||
} else { /* Full-size 64 bit load. */
|
||||
MCode *p = as->mcp;
|
||||
*(uint64_t *)(p-8) = dispaddr;
|
||||
p[-9] = (MCode)(XI_MOVri+(ra&7));
|
||||
p[-10] = 0x48 + ((ra>>3)&1);
|
||||
p -= 10;
|
||||
as->mcp = p;
|
||||
}
|
||||
if (xo == XO_GROUP3b) emit_i8(as, i8);
|
||||
}
|
||||
emit_rmro(as, xo, rr, ra, 0);
|
||||
emit_loadu64(as, ra, (uintptr_t)addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -1012,7 +1012,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd)
|
||||
handle_num:
|
||||
tra = lj_ir_tonum(J, tra);
|
||||
tr = lj_ir_call(J, id, tr, trsf, tra);
|
||||
if (LJ_SOFTFP) lj_needsplit(J);
|
||||
if (LJ_SOFTFP32) lj_needsplit(J);
|
||||
break;
|
||||
case STRFMT_STR:
|
||||
if (!tref_isstr(tra)) {
|
||||
|
@ -235,7 +235,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */
|
||||
#define CFRAME_OFS_L 36
|
||||
#define CFRAME_OFS_PC 32
|
||||
#define CFRAME_OFS_MULTRES 28
|
||||
#define CFRAME_SIZE 272
|
||||
#define CFRAME_SIZE (LJ_ARCH_HASFPU ? 272 : 128)
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS32
|
||||
|
@ -51,7 +51,7 @@ typedef struct CCallInfo {
|
||||
#define CCI_XARGS(ci) (((ci)->flags >> CCI_XARGS_SHIFT) & 3)
|
||||
#define CCI_XA (1u << CCI_XARGS_SHIFT)
|
||||
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)
|
||||
#define CCI_XNARGS(ci) (CCI_NARGS((ci)) + CCI_XARGS((ci)))
|
||||
#else
|
||||
#define CCI_XNARGS(ci) CCI_NARGS((ci))
|
||||
@ -78,13 +78,19 @@ typedef struct CCallInfo {
|
||||
#define IRCALLCOND_SOFTFP_FFI(x) NULL
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP && LJ_TARGET_MIPS32
|
||||
#if LJ_SOFTFP && LJ_TARGET_MIPS
|
||||
#define IRCALLCOND_SOFTFP_MIPS(x) x
|
||||
#else
|
||||
#define IRCALLCOND_SOFTFP_MIPS(x) NULL
|
||||
#endif
|
||||
|
||||
#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS32)
|
||||
#if LJ_SOFTFP && LJ_TARGET_MIPS64
|
||||
#define IRCALLCOND_SOFTFP_MIPS64(x) x
|
||||
#else
|
||||
#define IRCALLCOND_SOFTFP_MIPS64(x) NULL
|
||||
#endif
|
||||
|
||||
#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS)
|
||||
|
||||
#if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)
|
||||
#define IRCALLCOND_FP64_FFI(x) x
|
||||
@ -112,6 +118,14 @@ typedef struct CCallInfo {
|
||||
#define XA2_FP 0
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP32
|
||||
#define XA_FP32 CCI_XA
|
||||
#define XA2_FP32 (CCI_XA+CCI_XA)
|
||||
#else
|
||||
#define XA_FP32 0
|
||||
#define XA2_FP32 0
|
||||
#endif
|
||||
|
||||
#if LJ_32
|
||||
#define XA_64 CCI_XA
|
||||
#define XA2_64 (CCI_XA+CCI_XA)
|
||||
@ -181,20 +195,21 @@ typedef struct CCallInfo {
|
||||
_(ANY, pow, 2, N, NUM, XA2_FP) \
|
||||
_(ANY, atan2, 2, N, NUM, XA2_FP) \
|
||||
_(ANY, ldexp, 2, N, NUM, XA_FP) \
|
||||
_(SOFTFP, lj_vm_tobit, 2, N, INT, 0) \
|
||||
_(SOFTFP, softfp_add, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_sub, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_mul, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_div, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_cmp, 4, N, NIL, 0) \
|
||||
_(SOFTFP, lj_vm_tobit, 1, N, INT, XA_FP32) \
|
||||
_(SOFTFP, softfp_add, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP, softfp_sub, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP, softfp_mul, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP, softfp_div, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP, softfp_cmp, 2, N, NIL, XA2_FP32) \
|
||||
_(SOFTFP, softfp_i2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_d2i, 2, N, INT, 0) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmin, 4, N, NUM, 0) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmax, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_d2i, 1, N, INT, XA_FP32) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmin, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmax, 2, N, NUM, XA2_FP32) \
|
||||
_(SOFTFP_MIPS64, lj_vm_tointg, 1, N, INT, 0) \
|
||||
_(SOFTFP_FFI, softfp_ui2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP_FFI, softfp_f2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP_FFI, softfp_d2ui, 2, N, INT, 0) \
|
||||
_(SOFTFP_FFI, softfp_d2f, 2, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_d2ui, 1, N, INT, XA_FP32) \
|
||||
_(SOFTFP_FFI, softfp_d2f, 1, N, FLOAT, XA_FP32) \
|
||||
_(SOFTFP_FFI, softfp_i2f, 1, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_ui2f, 1, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_f2i, 1, N, INT, 0) \
|
||||
@ -272,7 +287,7 @@ LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1];
|
||||
#define fp64_f2l __aeabi_f2lz
|
||||
#define fp64_f2ul __aeabi_f2ulz
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS
|
||||
#elif LJ_TARGET_MIPS || LJ_TARGET_PPC
|
||||
#define softfp_add __adddf3
|
||||
#define softfp_sub __subdf3
|
||||
#define softfp_mul __muldf3
|
||||
|
@ -150,7 +150,7 @@ LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);
|
||||
/* Optimization passes. */
|
||||
LJ_FUNC void lj_opt_dce(jit_State *J);
|
||||
LJ_FUNC int lj_opt_loop(jit_State *J);
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)
|
||||
LJ_FUNC void lj_opt_split(jit_State *J);
|
||||
#else
|
||||
#define lj_opt_split(J) UNUSED(J)
|
||||
|
10
src/lj_jit.h
10
src/lj_jit.h
@ -158,6 +158,12 @@ typedef uint8_t MCode;
|
||||
typedef uint32_t MCode;
|
||||
#endif
|
||||
|
||||
/* Linked list of MCode areas. */
|
||||
typedef struct MCLink {
|
||||
MCode *next; /* Next area. */
|
||||
size_t size; /* Size of current area. */
|
||||
} MCLink;
|
||||
|
||||
/* Stack snapshot header. */
|
||||
typedef struct SnapShot {
|
||||
uint16_t mapofs; /* Offset into snapshot map. */
|
||||
@ -368,7 +374,7 @@ enum {
|
||||
((TValue *)(((intptr_t)&J->ksimd[2*(n)] + 15) & ~(intptr_t)15))
|
||||
|
||||
/* Set/reset flag to activate the SPLIT pass for the current trace. */
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)
|
||||
#define lj_needsplit(J) (J->needsplit = 1)
|
||||
#define lj_resetsplit(J) (J->needsplit = 0)
|
||||
#else
|
||||
@ -431,7 +437,7 @@ typedef struct jit_State {
|
||||
MSize sizesnapmap; /* Size of temp. snapshot map buffer. */
|
||||
|
||||
PostProc postproc; /* Required post-processing after execution. */
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)
|
||||
uint8_t needsplit; /* Need SPLIT pass. */
|
||||
#endif
|
||||
uint8_t retryrec; /* Retry recording. */
|
||||
|
@ -272,12 +272,6 @@ static void *mcode_alloc(jit_State *J, size_t sz)
|
||||
|
||||
/* -- MCode area management ----------------------------------------------- */
|
||||
|
||||
/* Linked list of MCode areas. */
|
||||
typedef struct MCLink {
|
||||
MCode *next; /* Next area. */
|
||||
size_t size; /* Size of current area. */
|
||||
} MCLink;
|
||||
|
||||
/* Allocate a new MCode area. */
|
||||
static void mcode_allocarea(jit_State *J)
|
||||
{
|
||||
|
@ -924,6 +924,9 @@ static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2)
|
||||
|
||||
#if LJ_SOFTFP
|
||||
LJ_ASMF int32_t lj_vm_tobit(double x);
|
||||
#if LJ_TARGET_MIPS64
|
||||
LJ_ASMF int32_t lj_vm_tointg(double x);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#if LJ_HASJIT && (LJ_SOFTFP || (LJ_32 && LJ_HASFFI))
|
||||
#if LJ_HASJIT && (LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI))
|
||||
|
||||
#include "lj_err.h"
|
||||
#include "lj_buf.h"
|
||||
|
@ -87,9 +87,9 @@ static void rec_check_slots(jit_State *J)
|
||||
BCReg s, nslots = J->baseslot + J->maxslot;
|
||||
int32_t depth = 0;
|
||||
cTValue *base = J->L->base - J->baseslot;
|
||||
lua_assert(J->baseslot >= 1+LJ_FR2 && J->baseslot < LJ_MAX_JSLOTS);
|
||||
lua_assert(J->baseslot >= 1+LJ_FR2);
|
||||
lua_assert(J->baseslot == 1+LJ_FR2 || (J->slot[J->baseslot-1] & TREF_FRAME));
|
||||
lua_assert(nslots < LJ_MAX_JSLOTS);
|
||||
lua_assert(nslots <= LJ_MAX_JSLOTS);
|
||||
for (s = 0; s < nslots; s++) {
|
||||
TRef tr = J->slot[s];
|
||||
if (tr) {
|
||||
@ -731,6 +731,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)
|
||||
J->framedepth++;
|
||||
J->base += func+1+LJ_FR2;
|
||||
J->baseslot += func+1+LJ_FR2;
|
||||
if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
|
||||
lj_trace_err(J, LJ_TRERR_STACKOV);
|
||||
}
|
||||
|
||||
/* Record tail call. */
|
||||
|
@ -93,7 +93,7 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)
|
||||
(ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT)
|
||||
sn |= SNAP_NORESTORE;
|
||||
}
|
||||
if (LJ_SOFTFP && irt_isnum(ir->t))
|
||||
if (LJ_SOFTFP32 && irt_isnum(ir->t))
|
||||
sn |= SNAP_SOFTFPNUM;
|
||||
map[n++] = sn;
|
||||
}
|
||||
@ -374,7 +374,7 @@ IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (LJ_SOFTFP && ir->o == IR_HIOP) {
|
||||
} else if (LJ_SOFTFP32 && ir->o == IR_HIOP) {
|
||||
ref++;
|
||||
} else if (ir->o == IR_PVAL) {
|
||||
ref = ir->op1 + REF_BIAS;
|
||||
@ -486,7 +486,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
|
||||
} else {
|
||||
IRType t = irt_type(ir->t);
|
||||
uint32_t mode = IRSLOAD_INHERIT|IRSLOAD_PARENT;
|
||||
if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;
|
||||
if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;
|
||||
if (ir->o == IR_SLOAD) mode |= (ir->op2 & IRSLOAD_READONLY);
|
||||
tr = emitir_raw(IRT(IR_SLOAD, t), s, mode);
|
||||
}
|
||||
@ -520,7 +520,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
|
||||
if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) {
|
||||
if (snap_pref(J, T, map, nent, seen, irs->op2) == 0)
|
||||
snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1);
|
||||
else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) &&
|
||||
else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) &&
|
||||
irs+1 < irlast && (irs+1)->o == IR_HIOP)
|
||||
snap_pref(J, T, map, nent, seen, (irs+1)->op2);
|
||||
}
|
||||
@ -579,10 +579,10 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
|
||||
lua_assert(irc->o == IR_CONV && irc->op2 == IRCONV_NUM_INT);
|
||||
val = snap_pref(J, T, map, nent, seen, irc->op1);
|
||||
val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
|
||||
} else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) &&
|
||||
} else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) &&
|
||||
irs+1 < irlast && (irs+1)->o == IR_HIOP) {
|
||||
IRType t = IRT_I64;
|
||||
if (LJ_SOFTFP && irt_type((irs+1)->t) == IRT_SOFTFP)
|
||||
if (LJ_SOFTFP32 && irt_type((irs+1)->t) == IRT_SOFTFP)
|
||||
t = IRT_NUM;
|
||||
lj_needsplit(J);
|
||||
if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) {
|
||||
@ -635,7 +635,7 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex,
|
||||
int32_t *sps = &ex->spill[regsp_spill(rs)];
|
||||
if (irt_isinteger(t)) {
|
||||
setintV(o, *sps);
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
} else if (irt_isnum(t)) {
|
||||
o->u64 = *(uint64_t *)sps;
|
||||
#endif
|
||||
@ -660,6 +660,9 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex,
|
||||
#if !LJ_SOFTFP
|
||||
} else if (irt_isnum(t)) {
|
||||
setnumV(o, ex->fpr[r-RID_MIN_FPR]);
|
||||
#elif LJ_64 /* && LJ_SOFTFP */
|
||||
} else if (irt_isnum(t)) {
|
||||
o->u64 = ex->gpr[r-RID_MIN_GPR];
|
||||
#endif
|
||||
#if LJ_64 && !LJ_GC64
|
||||
} else if (irt_is64(t)) {
|
||||
@ -813,7 +816,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
|
||||
val = lj_tab_set(J->L, t, &tmp);
|
||||
/* NOBARRIER: The table is new (marked white). */
|
||||
snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, val);
|
||||
if (LJ_SOFTFP && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) {
|
||||
if (LJ_SOFTFP32 && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) {
|
||||
snap_restoreval(J, T, ex, snapno, rfilt, (irs+1)->op2, &tmp);
|
||||
val->u32.hi = tmp.u32.lo;
|
||||
}
|
||||
@ -874,7 +877,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
||||
continue;
|
||||
}
|
||||
snap_restoreval(J, T, ex, snapno, rfilt, ref, o);
|
||||
if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && tvisint(o)) {
|
||||
if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM) && tvisint(o)) {
|
||||
TValue tmp;
|
||||
snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp);
|
||||
o->u32.hi = tmp.u32.lo;
|
||||
|
@ -1980,6 +1980,38 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|1:
|
||||
| jr ra
|
||||
|. move CRET1, r0
|
||||
|
|
||||
|// FP number to int conversion with a check for soft-float.
|
||||
|// Modifies CARG1, CRET1, CRET2, TMP0, AT.
|
||||
|->vm_tointg:
|
||||
|.if JIT
|
||||
| dsll CRET2, CARG1, 1
|
||||
| beqz CRET2, >2
|
||||
|. li TMP0, 1076
|
||||
| dsrl AT, CRET2, 53
|
||||
| dsubu TMP0, TMP0, AT
|
||||
| sltiu AT, TMP0, 54
|
||||
| beqz AT, >1
|
||||
|. dextm CRET2, CRET2, 0, 20
|
||||
| dinsu CRET2, AT, 21, 21
|
||||
| slt AT, CARG1, r0
|
||||
| dsrlv CRET1, CRET2, TMP0
|
||||
| dsubu CARG1, r0, CRET1
|
||||
| movn CRET1, CARG1, AT
|
||||
| li CARG1, 64
|
||||
| subu TMP0, CARG1, TMP0
|
||||
| dsllv CRET2, CRET2, TMP0 // Integer check.
|
||||
| sextw AT, CRET1
|
||||
| xor AT, CRET1, AT // Range check.
|
||||
| jr ra
|
||||
|. movz CRET2, AT, CRET2
|
||||
|1:
|
||||
| jr ra
|
||||
|. li CRET2, 1
|
||||
|2:
|
||||
| jr ra
|
||||
|. move CRET1, r0
|
||||
|.endif
|
||||
|.endif
|
||||
|
|
||||
|.macro .ffunc_bit, name
|
||||
@ -2665,6 +2697,23 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|. li CRET1, 0
|
||||
|.endif
|
||||
|
|
||||
|.macro sfmin_max, name, intins
|
||||
|->vm_sf .. name:
|
||||
|.if JIT and not FPU
|
||||
| move TMP2, ra
|
||||
| bal ->vm_sfcmpolt
|
||||
|. nop
|
||||
| move ra, TMP2
|
||||
| move TMP0, CRET1
|
||||
| move CRET1, CARG1
|
||||
| jr ra
|
||||
|. intins CRET1, CARG2, TMP0
|
||||
|.endif
|
||||
|.endmacro
|
||||
|
|
||||
| sfmin_max min, movz
|
||||
| sfmin_max max, movn
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- Miscellaneous functions --------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
1249
src/vm_ppc.dasc
1249
src/vm_ppc.dasc
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user