mirror of
https://github.com/love2d/megasource.git
synced 2026-08-12 00:20:55 +02:00
update luajit to LuaJIT/LuaJIT@2460b3f
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
1781602682
|
||||
1784580905
|
||||
|
||||
@@ -377,6 +377,7 @@ are allowed.</li>
|
||||
<li><tt>pairs()</tt> and <tt>ipairs()</tt> check for <tt>__pairs</tt> and
|
||||
<tt>__ipairs</tt>.</li>
|
||||
<li><tt>coroutine.running()</tt> returns two results.</li>
|
||||
<li><tt>string.find()</tt> returns <tt>nil</tt> for out-of-range position.</li>
|
||||
<li><tt>table.pack()</tt> and <tt>table.unpack()</tt>
|
||||
(same as <tt>unpack()</tt>).</li>
|
||||
<li><tt>io.write()</tt> and <tt>file:write()</tt> return file handle
|
||||
@@ -385,7 +386,6 @@ instead of <tt>true</tt>.</li>
|
||||
exit status.</li>
|
||||
<li><tt>debug.setmetatable()</tt> returns object.</li>
|
||||
<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>
|
||||
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>
|
||||
<li><tt>package.searchers</tt>.</li>
|
||||
<li><tt>module()</tt> returns the module table.</li>
|
||||
</ul>
|
||||
@@ -411,6 +411,34 @@ LuaJIT supports some extensions from Lua 5.3:
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="lj30_bp_syntax">Backported Syntax Extensions from LuaJIT 3.0</h2>
|
||||
<p>
|
||||
LuaJIT 2.1 supports some
|
||||
<a href="https://github.com/LuaJIT/LuaJIT/issues/1475#issuecomment-4769582883"><span class="ext">»</span> syntax extensions backported from LuaJIT 3.0</a>:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Bit Operators: unary <tt>~</tt>, binary <tt>& | ~ << >> ~>></tt></li>
|
||||
<li>Customary Operators: <tt>! && || !=</tt></li>
|
||||
<li>Ternary <tt>?:</tt> conditional operator</li>
|
||||
<li>Safe Navigation Operator <tt>?.</tt></li>
|
||||
<li>nil-Coalescing Operator <tt>??</tt></li>
|
||||
<li>Compound Assignment Operators: <tt>+= -= *= /= %= &= |= ~= <<= >>= ~>>= ..=</tt></li>
|
||||
<li><tt>continue</tt> Statement</li>
|
||||
<li><tt>const</tt> Declaration</li>
|
||||
<li>Short Function Expression</li>
|
||||
<li>Underscores in Number Literals</li>
|
||||
</ul>
|
||||
<p>
|
||||
Not backported are:
|
||||
bit operator metamethods,
|
||||
floor division operator <tt>//</tt>,
|
||||
compound assignment metamethods,
|
||||
named vararg parameter <tt>...name</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Bytecode that uses a bit operator can only be loaded by LuaJIT 2.1.1784535649 or higher.
|
||||
</p>
|
||||
|
||||
<h2 id="exceptions">C++ Exception Interoperability</h2>
|
||||
<p>
|
||||
LuaJIT has built-in support for interoperating with C++ exceptions.
|
||||
|
||||
@@ -1409,7 +1409,7 @@ local map_op = {
|
||||
dppd_3 = "rmio:660F3A41rMU",
|
||||
dpps_3 = "rmio:660F3A40rMU",
|
||||
extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
|
||||
insertps_3 = "rrio:660F3A41rMU|rxi/od:",
|
||||
insertps_3 = "rrio:660F3A21rMU|rxi/od:",
|
||||
movntdqa_2 = "rxo:660F382ArM",
|
||||
mpsadbw_3 = "rmio:660F3A42rMU",
|
||||
packusdw_2 = "rmo:660F382BrM",
|
||||
|
||||
@@ -372,7 +372,7 @@ ifneq ($(HOST_SYS),$(TARGET_SYS))
|
||||
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
|
||||
else
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX -DTARGET_OS_IPHONE=1
|
||||
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX -DLUAJIT_TARGET_IPHONE=1
|
||||
else
|
||||
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
|
||||
endif
|
||||
|
||||
@@ -149,7 +149,8 @@ lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_prng.h lj_vm.h
|
||||
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
|
||||
lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
|
||||
lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h lj_ctype.h lj_cdata.h \
|
||||
lj_carith.h
|
||||
lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
|
||||
lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_ir.h lj_jit.h lj_iropt.h
|
||||
@@ -181,9 +182,9 @@ lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
|
||||
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
|
||||
lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \
|
||||
lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h
|
||||
lj_ctype.h lj_gc.h lj_crecord.h lj_jit.h lj_ir.h lj_ffrecord.h lj_ff.h \
|
||||
lj_ffdef.h lj_debug.h lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h \
|
||||
lj_traceerr.h lj_record.h lj_snap.h lj_vm.h lj_prng.h
|
||||
lj_serialize.o: lj_serialize.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
|
||||
lj_udata.h lj_ctype.h lj_cdata.h lj_ir.h lj_serialize.h
|
||||
|
||||
@@ -230,6 +230,7 @@ LJLIB_CF(os_date)
|
||||
LJLIB_CF(os_time)
|
||||
{
|
||||
time_t t;
|
||||
errno = 0;
|
||||
if (lua_isnoneornil(L, 1)) { /* called without args? */
|
||||
t = time(NULL); /* get current time */
|
||||
} else {
|
||||
@@ -243,7 +244,6 @@ LJLIB_CF(os_time)
|
||||
ts.tm_mon = (int)((unsigned int)getfield(L, "month", -1) - 1u);
|
||||
ts.tm_year = (int)((unsigned int)getfield(L, "year", -1) - 1900u);
|
||||
ts.tm_isdst = getboolfield(L, "isdst");
|
||||
errno = 0;
|
||||
t = mktime(&ts);
|
||||
}
|
||||
if (t == (time_t)(-1) && errno != 0)
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
#define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX
|
||||
|
||||
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || LUAJIT_TARGET_IPHONE
|
||||
#define LJ_TARGET_IOS 1
|
||||
#else
|
||||
#define LJ_TARGET_IOS 0
|
||||
|
||||
@@ -1549,7 +1549,8 @@ static void asm_bitshift(ASMState *as, IRIns *ir, A64Ins ai, A64Shift sh)
|
||||
int32_t shmask = irt_is64(ir->t) ? 63 : 31;
|
||||
if (irref_isk(ir->op2)) { /* Constant shifts. */
|
||||
Reg left, dest = ra_dest(as, ir, RSET_GPR);
|
||||
int32_t shift = (IR(ir->op2)->i & shmask);
|
||||
IRIns *irr = IR(ir->op2);
|
||||
int32_t shift = ((irr->o == IR_KINT ? irr->i : (int32_t)ir_kint64(irr)->u64) & shmask);
|
||||
IRIns *irl = IR(ir->op1);
|
||||
if (shmask == 63) ai += A64I_UBFMx - A64I_UBFMw;
|
||||
|
||||
|
||||
@@ -2089,7 +2089,8 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
if (irref_isk(ir->op2)) { /* Constant shifts. */
|
||||
uint32_t shift = (uint32_t)IR(ir->op2)->i;
|
||||
IRIns *irr = IR(ir->op2);
|
||||
uint32_t shift = (uint32_t)(LJ_32 || irr->o == IR_KINT) ? (uint32_t)irr->i : (uint32_t)ir_kint64(irr)->u64;
|
||||
if (LJ_64 && irt_is64(ir->t)) mik |= (shift & 32) ? MIPSI_D32 : MIPSI_D;
|
||||
emit_dta(as, mik, dest, ra_hintalloc(as, ir->op1, dest, RSET_GPR),
|
||||
(shift & 31));
|
||||
|
||||
@@ -1112,10 +1112,12 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
|
||||
} else {
|
||||
#if LJ_GC64
|
||||
if (irref_isk(ref)) {
|
||||
Reg tmp;
|
||||
TValue k;
|
||||
lj_ir_kvalue(as->J->L, &k, ir);
|
||||
emit_movmroi(as, dest, 4, k.u32.hi);
|
||||
emit_movmroi(as, dest, 0, k.u32.lo);
|
||||
tmp = ra_scratch(as, rset_exclude(RSET_GPR, dest));
|
||||
emit_rmro(as, XO_MOVto, tmp|REX_64, dest, 0);
|
||||
emit_loadu64(as, tmp, k.u64);
|
||||
} else {
|
||||
/* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
|
||||
Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
|
||||
@@ -2318,9 +2320,10 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs, x86Op xv)
|
||||
IRIns *irr = IR(rref);
|
||||
Reg dest;
|
||||
if (irref_isk(rref)) { /* Constant shifts. */
|
||||
int shift;
|
||||
int32_t shift;
|
||||
dest = ra_dest(as, ir, RSET_GPR);
|
||||
shift = irr->i & (irt_is64(ir->t) ? 63 : 31);
|
||||
shift = (LJ_32 || irr->o == IR_KINT) ? irr->i : (int32_t)ir_kint64(irr)->u64;
|
||||
shift &= (irt_is64(ir->t) ? 63 : 31);
|
||||
if (!xv && shift && (as->flags & JIT_F_BMI2)) {
|
||||
Reg left = asm_fuseloadm(as, ir->op1, RSET_GPR, irt_is64(ir->t));
|
||||
if (left != dest) { /* BMI2 rotate right by constant. */
|
||||
@@ -2786,8 +2789,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
emit_i32(as, -1);
|
||||
emit_rmro(as, XO_MOVmi, REX_64, RID_BASE, ofs);
|
||||
} else {
|
||||
emit_movmroi(as, RID_BASE, ofs+4, k.u32.hi);
|
||||
emit_movmroi(as, RID_BASE, ofs, k.u32.lo);
|
||||
Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, RID_BASE));
|
||||
emit_rmro(as, XO_MOVto, tmp|REX_64, RID_BASE, ofs);
|
||||
emit_loadu64(as, tmp, k.u64);
|
||||
}
|
||||
#else
|
||||
} else if (!irt_ispri(ir->t)) {
|
||||
|
||||
+10
-1
@@ -98,7 +98,7 @@
|
||||
_(UNM, dst, ___, var, unm) \
|
||||
_(LEN, dst, ___, var, len) \
|
||||
\
|
||||
/* Binary ops. ORDER OPR. VV last, POW must be next. */ \
|
||||
/* Binary ops. ORDER OPR. ORDER ARITH. VV last, POW must be next. */ \
|
||||
_(ADDVN, dst, var, num, add) \
|
||||
_(SUBVN, dst, var, num, sub) \
|
||||
_(MULVN, dst, var, num, mul) \
|
||||
@@ -186,6 +186,15 @@
|
||||
\
|
||||
_(JMP, rbase, ___, jump, ___) \
|
||||
\
|
||||
/* Bit operators. ORDER OPR. ORDER BIT. */ \
|
||||
_(BNOT, dst, ___, var, ___) \
|
||||
_(BAND, dst, var, var, ___) \
|
||||
_(BOR, dst, var, var, ___) \
|
||||
_(BXOR, dst, var, var, ___) \
|
||||
_(BSHL, dst, var, var, ___) \
|
||||
_(BSHR, dst, var, var, ___) \
|
||||
_(BSAR, dst, var, var, ___) \
|
||||
\
|
||||
/* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
|
||||
_(FUNCF, rbase, ___, ___, ___) \
|
||||
_(IFUNCF, rbase, ___, ___, ___) \
|
||||
|
||||
@@ -43,8 +43,9 @@
|
||||
#define BCDUMP_F_STRIP 0x02
|
||||
#define BCDUMP_F_FFI 0x04
|
||||
#define BCDUMP_F_FR2 0x08
|
||||
#define BCDUMP_F_BITOP 0x10
|
||||
|
||||
#define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1)
|
||||
#define BCDUMP_F_KNOWN (BCDUMP_F_BITOP*2-1)
|
||||
|
||||
#define BCDUMP_F_DETERMINISTIC 0x80000000
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
|
||||
p += 5; /* Leave room for final size. */
|
||||
|
||||
/* Write prototype header. */
|
||||
*p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI));
|
||||
*p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI|PROTO_BITOP));
|
||||
*p++ = pt->numparams;
|
||||
*p++ = pt->framesize;
|
||||
*p++ = pt->sizeuv;
|
||||
@@ -397,7 +397,8 @@ static void bcwrite_header(BCWriteCtx *ctx)
|
||||
*p++ = BCDUMP_VERSION;
|
||||
*p++ = (ctx->flags & (BCDUMP_F_STRIP | BCDUMP_F_FR2)) +
|
||||
LJ_BE*BCDUMP_F_BE +
|
||||
((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0);
|
||||
((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0) +
|
||||
((ctx->pt->flags & PROTO_BITOP) ? BCDUMP_F_BITOP : 0);
|
||||
if (!(ctx->flags & BCDUMP_F_STRIP)) {
|
||||
p = lj_strfmt_wuleb128(p, len);
|
||||
p = lj_buf_wmem(p, name, len);
|
||||
|
||||
@@ -353,6 +353,37 @@ uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check bit operator arguments. No coercion from strings. */
|
||||
uint64_t lj_carith_checkbit64(lua_State *L, cTValue *o, CTypeID *id)
|
||||
{
|
||||
if (tviscdata(o)) {
|
||||
CTState *cts = ctype_cts(L);
|
||||
uint8_t *sp = (uint8_t *)cdataptr(cdataV(o));
|
||||
CTypeID sid = cdataV(o)->ctypeid;
|
||||
CType *s = ctype_get(cts, sid);
|
||||
uint64_t x;
|
||||
if (ctype_isref(s->info)) {
|
||||
sp = *(void **)sp;
|
||||
sid = ctype_cid(s->info);
|
||||
}
|
||||
s = ctype_raw(cts, sid);
|
||||
if (ctype_isenum(s->info)) s = ctype_child(cts, s);
|
||||
if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
|
||||
CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8)
|
||||
*id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
|
||||
else if (!*id)
|
||||
*id = CTID_INT64; /* Use int64_t, unless already set. */
|
||||
lj_cconv_ct_ct(cts, ctype_get(cts, *id), s,
|
||||
(uint8_t *)&x, sp, 0);
|
||||
return x;
|
||||
} else if (LJ_LIKELY(tvisint(o))) {
|
||||
return (uint64_t)intV(o); /* Sign-extended. */
|
||||
} else {
|
||||
if (!tvisnum(o)) lj_err_optype(L, o, LJ_ERR_OPARITH);
|
||||
return (uint64_t)lj_num2bit(numV(o)); /* Sign-extended. */
|
||||
}
|
||||
}
|
||||
|
||||
/* -- 64 bit integer arithmetic helpers ----------------------------------- */
|
||||
|
||||
#if LJ_32 && LJ_HASJIT
|
||||
|
||||
@@ -21,6 +21,7 @@ LJ_FUNC uint64_t lj_carith_ror64(uint64_t x, int32_t sh);
|
||||
#endif
|
||||
LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op);
|
||||
LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id);
|
||||
LJ_FUNC uint64_t lj_carith_checkbit64(lua_State *L, cTValue *o, CTypeID *id);
|
||||
|
||||
#if LJ_32 && LJ_HASJIT
|
||||
LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
|
||||
|
||||
@@ -1091,7 +1091,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
if (CCALL_ALIGN_STACKARG) { /* Align argument on stack. */
|
||||
MSize align = (1u << ctype_align(ccall_struct_align(cts, d))) - 1;
|
||||
#if LJ_TARGET_ARM64 && LJ_TARGET_OSX
|
||||
isva = ctype_isstruct(d->info);
|
||||
isva |= ctype_isstruct(d->info);
|
||||
#endif
|
||||
if (rp || (CCALL_PACK_STACKARG && isva && align < CTSIZE_PTR-1))
|
||||
align = CTSIZE_PTR-1;
|
||||
|
||||
@@ -704,6 +704,10 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
|
||||
if (ctr->size <= 4 &&
|
||||
(LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info)))
|
||||
*(int64_t *)dp = (int64_t)*(int32_t *)dp;
|
||||
#elif LJ_TARGET_X64
|
||||
/* Always zero-extend results to 64 bits. */
|
||||
if (ctr->size <= 4 && ctype_isinteger_or_bool(ctr->info))
|
||||
*(uint64_t *)dp = (uint64_t)*(uint32_t *)dp;
|
||||
#endif
|
||||
#if LJ_TARGET_X86
|
||||
if (ctype_isfp(ctr->info))
|
||||
|
||||
@@ -1884,24 +1884,23 @@ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
|
||||
int recff_bit64_shift(jit_State *J, TRef *rb, TRef *rc,
|
||||
TValue *rbv, TValue *rcv, IROp op)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(J));
|
||||
CTypeID id;
|
||||
TRef tsh = 0;
|
||||
if (J->base[0] && tref_iscdata(J->base[1])) {
|
||||
tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64),
|
||||
J->base[1], &rd->argv[1]);
|
||||
if (*rb && tref_iscdata(*rc)) {
|
||||
tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), *rc, rcv);
|
||||
if (LJ_32 && !tref_isinteger(tsh))
|
||||
tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
|
||||
J->base[1] = tsh;
|
||||
*rc = tsh;
|
||||
}
|
||||
id = crec_bit64_type(cts, &rd->argv[0]);
|
||||
id = crec_bit64_type(cts, rbv);
|
||||
if (id) {
|
||||
TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]);
|
||||
uint32_t op = rd->data;
|
||||
TRef tr = crec_bit64_arg(J, ctype_get(cts, id), *rb, rbv);
|
||||
IRType t;
|
||||
if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
|
||||
if (!tsh) tsh = lj_opt_narrow_tobit(J, *rc);
|
||||
t = tref_isinteger(tsh) ? IRT_INT : tref_type(tsh);
|
||||
if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
|
||||
!tref_isk(tsh))
|
||||
@@ -1913,7 +1912,7 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
|
||||
}
|
||||
#endif
|
||||
tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
|
||||
J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
|
||||
*rb = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1955,6 +1954,22 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
|
||||
return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
|
||||
}
|
||||
|
||||
TRef recff_bit64_bitop(jit_State *J, TRef rb, TRef rc,
|
||||
TValue *rbv, TValue *rcv, IROp op)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(J));
|
||||
CTypeID id = crec_bit64_type(cts, rbv);
|
||||
CTypeID id2 = rcv ? crec_bit64_type(cts, rcv) : 0;
|
||||
CType *ct;
|
||||
TRef tr, tr2;
|
||||
if (id < id2) id = id2;
|
||||
ct = ctype_get(cts, id);
|
||||
tr = crec_bit64_arg(J, ct, rb, rbv);
|
||||
tr2 = rcv ? crec_bit64_arg(J, ct, rc, rcv) : 0;
|
||||
tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tr2);
|
||||
return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
|
||||
}
|
||||
|
||||
/* -- Miscellaneous library functions ------------------------------------- */
|
||||
|
||||
void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
|
||||
|
||||
@@ -29,8 +29,11 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int recff_bit64_shift(jit_State *J, TRef *rb, TRef *rc,
|
||||
TValue *rbv, TValue *rcv, IROp op);
|
||||
LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr);
|
||||
LJ_FUNC TRef recff_bit64_bitop(jit_State *J, TRef rb, TRef rc,
|
||||
TValue *rbv, TValue *rcv, IROp op);
|
||||
|
||||
LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o);
|
||||
|
||||
@@ -49,6 +49,7 @@ extern double __divdf3(double a, double b);
|
||||
_(lj_dispatch_profile) _(lj_err_throw) \
|
||||
_(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
|
||||
_(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
|
||||
_(lj_meta_bitop) \
|
||||
_(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
|
||||
_(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \
|
||||
_(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \
|
||||
|
||||
@@ -140,9 +140,13 @@ ERRDEF(XDOTS, "cannot use " LUA_QL("...") " outside a vararg function")
|
||||
ERRDEF(XSYNTAX, "syntax error")
|
||||
ERRDEF(XFOR, LUA_QL("=") " or " LUA_QL("in") " expected")
|
||||
ERRDEF(XBREAK, "no loop to break")
|
||||
ERRDEF(XCONT, "no loop to continue")
|
||||
ERRDEF(XLUNDEF, "undefined label " LUA_QS)
|
||||
ERRDEF(XLDUP, "duplicate label " LUA_QS)
|
||||
ERRDEF(XGSCOPE, "<goto %s> jumps into the scope of local " LUA_QS)
|
||||
ERRDEF(XCSCOPE, "<continue> jumps into the scope of local " LUA_QS)
|
||||
ERRDEF(XCONSTA, "attempt to assign to const variable " LUA_QS)
|
||||
ERRDEF(XCONSTR, "attempt to re-declare const variable " LUA_QS)
|
||||
|
||||
/* Bytecode reader errors. */
|
||||
ERRDEF(BCFMT, "cannot load incompatible bytecode")
|
||||
|
||||
@@ -745,7 +745,7 @@ static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
|
||||
static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
if (recff_bit64_shift(J, rd))
|
||||
if (recff_bit64_shift(J, &J->base[0], &J->base[1], &rd->argv[0], &rd->argv[1], rd->data))
|
||||
return;
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
_(KINT64, N , cst, ___) \
|
||||
_(KSLOT, N , ref, lit) \
|
||||
\
|
||||
/* Bit ops. */ \
|
||||
/* Bit ops. ORDER BIT */ \
|
||||
_(BNOT, N , ref, ___) \
|
||||
_(BSWAP, N , ref, ___) \
|
||||
_(BAND, C , ref, ref) \
|
||||
|
||||
@@ -97,12 +97,18 @@ static void lex_number(LexState *ls, TValue *tv)
|
||||
StrScanFmt fmt;
|
||||
LexChar c, xp = 'e';
|
||||
lj_assertLS(lj_char_isdigit(ls->c), "bad usage");
|
||||
if ((c = ls->c) == '0' && (lex_savenext(ls) | 0x20) == 'x')
|
||||
xp = 'p';
|
||||
if ((c = ls->c) == '0') {
|
||||
lex_save(ls, c);
|
||||
do { c = lex_next(ls); } while (c == '_');
|
||||
if ((c | 0x20) == 'x') xp = 'p';
|
||||
}
|
||||
while (lj_char_isident(ls->c) || ls->c == '.' ||
|
||||
((ls->c == '-' || ls->c == '+') && (c | 0x20) == xp)) {
|
||||
c = ls->c;
|
||||
lex_savenext(ls);
|
||||
if (LJ_LIKELY(ls->c != '_')) {
|
||||
c = ls->c;
|
||||
lex_save(ls, ls->c);
|
||||
}
|
||||
lex_next(ls);
|
||||
}
|
||||
lex_save(ls, '\0');
|
||||
fmt = lj_strscan_scan((const uint8_t *)ls->sb.b, sbuflen(&ls->sb)-1, tv,
|
||||
@@ -321,7 +327,9 @@ static LexToken lex_scan(LexState *ls, TValue *tv)
|
||||
continue;
|
||||
case '-':
|
||||
lex_next(ls);
|
||||
if (ls->c != '-') return '-';
|
||||
if (ls->c != '-') {
|
||||
if (ls->c != '>') return '-'; else { lex_next(ls); return TK_arrow; }
|
||||
}
|
||||
lex_next(ls);
|
||||
if (ls->c == '[') { /* Long comment "--[=*[...]=*]". */
|
||||
int sep = lex_skipeq(ls);
|
||||
@@ -353,16 +361,41 @@ static LexToken lex_scan(LexState *ls, TValue *tv)
|
||||
if (ls->c != '=') return '='; else { lex_next(ls); return TK_eq; }
|
||||
case '<':
|
||||
lex_next(ls);
|
||||
if (ls->c != '=') return '<'; else { lex_next(ls); return TK_le; }
|
||||
if (ls->c == '=') { lex_next(ls); return TK_le; }
|
||||
if (ls->c == '<') { lex_next(ls); return TK_shl; }
|
||||
return '<';
|
||||
case '>':
|
||||
lex_next(ls);
|
||||
if (ls->c != '=') return '>'; else { lex_next(ls); return TK_ge; }
|
||||
if (ls->c == '=') { lex_next(ls); return TK_ge; }
|
||||
if (ls->c == '>') { lex_next(ls); return TK_shr; }
|
||||
return '>';
|
||||
case '~':
|
||||
lex_next(ls);
|
||||
if (ls->c != '=') return '~'; else { lex_next(ls); return TK_ne; }
|
||||
if (ls->c == '=') { lex_next(ls); return TK_ne; }
|
||||
if (ls->c == '>') {
|
||||
lex_next(ls);
|
||||
if (ls->c != '>') lj_lex_error(ls, '~', LJ_ERR_XSYMBOL);
|
||||
lex_next(ls);
|
||||
return TK_sar;
|
||||
}
|
||||
return '~';
|
||||
case '!':
|
||||
lex_next(ls);
|
||||
if (ls->c != '=') return '!'; else { lex_next(ls); return TK_ne_; }
|
||||
case ':':
|
||||
lex_next(ls);
|
||||
if (ls->c != ':') return ':'; else { lex_next(ls); return TK_label; }
|
||||
case '?':
|
||||
lex_next(ls);
|
||||
if (ls->c == '.') { lex_next(ls); return TK_nav; }
|
||||
if (ls->c == '?') { lex_next(ls); return TK_coal; }
|
||||
return '?';
|
||||
case '&':
|
||||
lex_next(ls);
|
||||
if (ls->c != '&') return '&'; else { lex_next(ls); return TK_and_; }
|
||||
case '|':
|
||||
lex_next(ls);
|
||||
if (ls->c != '|') return '|'; else { lex_next(ls); return TK_or_; }
|
||||
case '"':
|
||||
case '\'':
|
||||
lex_string(ls, tv);
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
|
||||
/* Lua lexer tokens. */
|
||||
#define TKDEF(_, __) \
|
||||
_(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \
|
||||
_(and) _(break) _(const) _(continue) _(do) _(else) _(elseif) _(end) _(false) \
|
||||
_(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \
|
||||
_(repeat) _(return) _(then) _(true) _(until) _(while) \
|
||||
__(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \
|
||||
__(nav, ?.) __(coal, \?\?) __(shl, <<) __(shr, >>) __(sar, ~>>) \
|
||||
__(and_, &&) __(or_, ||) __(ne_, !=) __(arrow, ->) \
|
||||
__(label, ::) __(number, <number>) __(name, <name>) __(string, <string>) \
|
||||
__(eof, <eof>)
|
||||
|
||||
@@ -39,6 +41,12 @@ typedef struct BCInsLine {
|
||||
BCLine line; /* Line number for this bytecode. */
|
||||
} BCInsLine;
|
||||
|
||||
/* Index into variable stack. */
|
||||
typedef uint16_t VarIndex;
|
||||
|
||||
#define LJ_VINDEX_HSIZE 32 /* Hash table size. Must be a power of 2. */
|
||||
#define LJ_VINDEX_MASK (LJ_VINDEX_HSIZE-1)
|
||||
|
||||
/* Info for local variables. Only used during bytecode generation. */
|
||||
typedef struct VarInfo {
|
||||
GCRef name; /* Local variable name or goto/label name. */
|
||||
@@ -46,6 +54,7 @@ typedef struct VarInfo {
|
||||
BCPos endpc; /* First point where the local variable is dead. */
|
||||
uint8_t slot; /* Variable slot. */
|
||||
uint8_t info; /* Variable/goto/label info. */
|
||||
VarIndex prev; /* Previous entry in variable hash chain. */
|
||||
} VarInfo;
|
||||
|
||||
/* Lua lexer state. */
|
||||
@@ -75,6 +84,7 @@ typedef struct LexState {
|
||||
uint32_t level; /* Syntactical nesting level. */
|
||||
int endmark; /* Trust bytecode end marker, even if not at EOF. */
|
||||
int fr2; /* Generate bytecode for LJ_FR2 mode. */
|
||||
VarIndex vhash[LJ_VINDEX_HSIZE]; /* Variable hash chain anchors. */
|
||||
} LexState;
|
||||
|
||||
LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
#include "lj_strscan.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_lib.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#include "lj_cdata.h"
|
||||
#include "lj_carith.h"
|
||||
#endif
|
||||
|
||||
/* -- Metamethod handling ------------------------------------------------- */
|
||||
|
||||
@@ -234,6 +239,76 @@ TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for bit operators. No bitop metamethods in v2.1. */
|
||||
void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc, BCReg op)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0, id_ignore = 0;
|
||||
uint64_t b = lj_carith_checkbit64(L, rb, &id);
|
||||
uint64_t c = lj_carith_checkbit64(L, rc, op >= BC_BSHL ? &id_ignore : &id);
|
||||
if (id) {
|
||||
if (tvisnum(rb)) {
|
||||
b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : lj_num2i64(numV(rb));
|
||||
}
|
||||
if (tvisnum(rc)) {
|
||||
c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : lj_num2i64(numV(rc));
|
||||
}
|
||||
}
|
||||
switch (op) {
|
||||
case BC_BNOT: b = ~b; break;
|
||||
case BC_BAND: b &= c; break;
|
||||
case BC_BOR: b |= c; break;
|
||||
case BC_BXOR: b ^= c; break;
|
||||
default:
|
||||
if (id) {
|
||||
b = lj_carith_shift64(b, (int32_t)c, op-BC_BSHL);
|
||||
} else if (op == BC_BSHL) {
|
||||
b = (uint64_t)((uint32_t)b << ((uint32_t)c & 31));
|
||||
} else if (op == BC_BSHR) {
|
||||
b = (uint64_t)((uint32_t)b >> ((uint32_t)c & 31));
|
||||
} else {
|
||||
lj_assertL(op == BC_BSAR, "bad bytecode op %d", op);
|
||||
b = (uint64_t)(uint32_t)((int32_t)b >> ((uint32_t)c & 31));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (id) {
|
||||
GCcdata *cd = lj_cdata_new_(L, id, 8);
|
||||
*(uint64_t *)cdataptr(cd) = b;
|
||||
setcdataV(L, ra, cd);
|
||||
} else {
|
||||
setintV(ra, (int32_t)b);
|
||||
}
|
||||
#else
|
||||
#if LJ_DUALNUM
|
||||
uint32_t b = 0, c = 0;
|
||||
if (tvisint(rb)) b = (uint32_t)intV(rb);
|
||||
else if (tvisnum(rb)) b = (uint32_t)lj_num2bit(numV(rb));
|
||||
else goto err;
|
||||
if (tvisint(rc)) c = (uint32_t)intV(rc);
|
||||
else if (tvisnum(rc)) c = (uint32_t)lj_num2bit(numV(rc));
|
||||
else goto err;
|
||||
switch (op) {
|
||||
case BC_BNOT: b = ~b; break;
|
||||
case BC_BAND: b &= c; break;
|
||||
case BC_BOR: b |= c; break;
|
||||
case BC_BXOR: b ^= c; break;
|
||||
case BC_BSHL: b <<= (c & 31); break;
|
||||
case BC_BSHR: b >>= (c & 31); break;
|
||||
case BC_BSAR: b = (uint32_t)((int32_t)b >> (c & 31)); break;
|
||||
default:
|
||||
lj_assertL(0, "bad bytecode op %d", op);
|
||||
break;
|
||||
}
|
||||
setintV(ra, (int32_t)b);
|
||||
return;
|
||||
err:
|
||||
#endif
|
||||
UNUSED(ra); UNUSED(op);
|
||||
lj_err_optype(L, tvisnumber(rb) ? rc : rb, LJ_ERR_OPARITH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
|
||||
TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@ LJ_FUNCA cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k);
|
||||
LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k);
|
||||
LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb,
|
||||
cTValue *rc, BCReg op);
|
||||
LJ_FUNCA void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb,
|
||||
cTValue *rc, BCReg op);
|
||||
LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left);
|
||||
LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o);
|
||||
LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne);
|
||||
|
||||
@@ -401,6 +401,7 @@ typedef struct GCproto {
|
||||
#define PROTO_FFI 0x04 /* Uses BC_KCDATA for FFI datatypes. */
|
||||
#define PROTO_NOJIT 0x08 /* JIT disabled for this function. */
|
||||
#define PROTO_ILOOP 0x10 /* Patched bytecode with ILOOP etc. */
|
||||
#define PROTO_BITOP 0x80 /* Uses bit operator bytecodes. */
|
||||
/* Only used during parsing. */
|
||||
#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */
|
||||
#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */
|
||||
|
||||
@@ -382,8 +382,8 @@ static uint64_t kfold_int64arith(jit_State *J, uint64_t k1, uint64_t k2,
|
||||
case IR_BSAR: k1 = (uint64_t)((int64_t)k1 >> (k2 & 63)); break;
|
||||
case IR_BROL: k1 = lj_rol(k1, (k2 & 63)); break;
|
||||
case IR_BROR: k1 = lj_ror(k1, (k2 & 63)); break;
|
||||
default: lj_assertJ(0, "bad IR op %d", op); break;
|
||||
#endif
|
||||
default: lj_assertJ(0, "bad IR op %d", op); break;
|
||||
}
|
||||
return k1;
|
||||
}
|
||||
|
||||
+578
-199
File diff suppressed because it is too large
Load Diff
@@ -359,6 +359,7 @@ LUA_API void luaJIT_profile_stop(lua_State *L)
|
||||
ProfileState *ps = &profile_state;
|
||||
global_State *g = ps->g;
|
||||
if (G(L) == g) { /* Only stop profiler if started by this VM. */
|
||||
ps->g = NULL;
|
||||
profile_timer_stop(ps);
|
||||
g->hookmask &= ~HOOK_PROFILE;
|
||||
lj_dispatch_update(g, 0);
|
||||
@@ -368,7 +369,6 @@ LUA_API void luaJIT_profile_stop(lua_State *L)
|
||||
#endif
|
||||
lj_buf_free(g, &ps->sb);
|
||||
ps->sb.w = ps->sb.e = NULL;
|
||||
ps->g = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "lj_frame.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#include "lj_crecord.h"
|
||||
#endif
|
||||
#include "lj_bc.h"
|
||||
#include "lj_ff.h"
|
||||
@@ -2505,6 +2506,45 @@ void lj_record_ins(jit_State *J)
|
||||
rc = rec_mm_arith(J, &ix, MM_pow);
|
||||
break;
|
||||
|
||||
/* -- Bit operators ----------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
#if LJ_HASFFI
|
||||
if (tref_iscdata(rc)) {
|
||||
rc = recff_bit64_bitop(J, rc, 0, rcv, NULL, IR_BNOT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
rc = lj_opt_narrow_tobit(J, rc);
|
||||
rc = emitir(IRTI(IR_BNOT), rc, 0);
|
||||
break;
|
||||
|
||||
case BC_BAND: case BC_BOR: case BC_BXOR:
|
||||
#if LJ_HASFFI
|
||||
if (tref_iscdata(rb) || tref_iscdata(rc)) {
|
||||
rc = recff_bit64_bitop(J, rb, rc, rbv, rcv, (int)op - (int)BC_BAND + (int)IR_BAND);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
recbit:
|
||||
rb = lj_opt_narrow_tobit(J, rb);
|
||||
rc = lj_opt_narrow_tobit(J, rc);
|
||||
rc = emitir(IRTI((int)op - (int)BC_BAND + (int)IR_BAND), rb, rc);
|
||||
break;
|
||||
|
||||
case BC_BSHL: case BC_BSHR: case BC_BSAR:
|
||||
#if LJ_HASFFI
|
||||
{
|
||||
TRef xrb = rb, xrc = rc;
|
||||
if (recff_bit64_shift(J, &xrb, &xrc, rbv, rcv, (int)op - (int)BC_BSHL + (int)IR_BSHL)) {
|
||||
rc = xrb;
|
||||
break;
|
||||
}
|
||||
rc = xrc; /* Shift amount may have been converted. */
|
||||
}
|
||||
#endif
|
||||
goto recbit;
|
||||
|
||||
/* -- Miscellaneous ops ------------------------------------------------- */
|
||||
|
||||
case BC_CAT:
|
||||
|
||||
@@ -848,6 +848,26 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
| b ->vmeta_binop // Binop call for compatibility.
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| add CARG3, BASE, RC
|
||||
| mov CARG4, CARG3
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_bitop:
|
||||
| add CARG3, BASE, RB
|
||||
| add CARG4, BASE, RC
|
||||
|1:
|
||||
| decode_OP OP, INS
|
||||
| add CARG2, BASE, RA
|
||||
| str BASE, L->base
|
||||
| mov CARG1, L
|
||||
| str PC, SAVE_PC
|
||||
| str OP, ARG5
|
||||
| bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| b ->cont_nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -3376,6 +3396,61 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next3
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| // RA = dst, RC = src
|
||||
| lsl RC, RC, #3
|
||||
| ldrd CARG12, [BASE, RC]
|
||||
| checktp CARG1, LJ_TISNUM
|
||||
| bne ->vmeta_bnot
|
||||
| mvn CARG1, CARG1
|
||||
| mvn CARG2, #~LJ_TISNUM
|
||||
| ins_next1
|
||||
| ins_next2
|
||||
| strd CARG12, [BASE, RA]
|
||||
| ins_next3
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins, shop
|
||||
| decode_RB8 RB, INS
|
||||
| decode_RC8 RC, INS
|
||||
| // RA = dst*8, RB = src1*8, RC = src2*8
|
||||
| ldrd CARG12, [BASE, RB]
|
||||
| ldrd CARG34, [BASE, RC]
|
||||
| checktp CARG2, LJ_TISNUM
|
||||
| checktpeq CARG4, LJ_TISNUM
|
||||
| bne ->vmeta_bitop
|
||||
|.if shop == 1
|
||||
| and CARG3, CARG3, #31
|
||||
|.endif
|
||||
| ins CARG1, CARG1, CARG3
|
||||
| mvn CARG2, #~LJ_TISNUM
|
||||
| ins_next1
|
||||
| ins_next2
|
||||
| strd CARG12, [BASE, RA]
|
||||
| ins_next3
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and, 0
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop orr, 0
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop eor, 0
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop lsl, 1
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop lsr, 1
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop asr, 1
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
@@ -920,6 +920,25 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
| b ->vmeta_binop // Binop call for compatibility.
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| add CARG3, BASE, RC, lsl #3
|
||||
| mov CARG4, CARG3
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_bitop:
|
||||
| add CARG3, BASE, RB, lsl #3
|
||||
| add CARG4, BASE, RC, lsl #3
|
||||
|1:
|
||||
| uxtb CARG5w, INSw
|
||||
| add CARG2, BASE, RA, lsl #3
|
||||
| str BASE, L->base
|
||||
| mov CARG1, L
|
||||
| str PC, SAVE_PC
|
||||
| bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| b ->cont_nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -2878,6 +2897,51 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| // RA = dst, RC = src
|
||||
| ldr CARG1, [BASE, RC, lsl #3]
|
||||
| checkint CARG1, ->vmeta_bnot
|
||||
| mvn CARG1w, CARG1w
|
||||
| add_TISNUM CARG1, CARG1
|
||||
| str CARG1, [BASE, RA, lsl #3]
|
||||
| ins_next
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins
|
||||
| decode_RB RB, INS
|
||||
| and RC, RC, #255
|
||||
| // RA = dst, RB = src1, RC = src2
|
||||
| ldr CARG1, [BASE, RB, lsl #3]
|
||||
| ldr CARG2, [BASE, RC, lsl #3]
|
||||
| checkint CARG1, ->vmeta_bitop
|
||||
| checkint CARG2, ->vmeta_bitop
|
||||
| ins CARG1w, CARG1w, CARG2w
|
||||
| add_TISNUM CARG1, CARG1
|
||||
| str CARG1, [BASE, RA, lsl #3]
|
||||
| ins_next
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop orr
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop eor
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop lsl
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop lsr
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop asr
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
@@ -981,6 +981,25 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| b ->vmeta_binop // Binop call for compatibility.
|
||||
|. nop
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| move RC, RB
|
||||
|
|
||||
|->vmeta_bitop:
|
||||
| load_got lj_meta_bitop
|
||||
| decode_OP1 TMP0, INS
|
||||
| sw BASE, L->base
|
||||
| move CARG2, RA
|
||||
| sw PC, SAVE_PC
|
||||
| move CARG3, RB
|
||||
| move CARG4, RC
|
||||
| sw TMP0, ARG5
|
||||
| call_intern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
|. move CARG1, L
|
||||
| b ->cont_nop
|
||||
|. nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -3886,6 +3905,62 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| // RA = dst*8, RD = src*8
|
||||
| addu RB, BASE, RD
|
||||
| lw TMP0, HI(RB)
|
||||
| lw CRET1, LO(RB)
|
||||
| bne TMP0, TISNUM, ->vmeta_bnot
|
||||
|. addu RA, BASE, RA
|
||||
| not CRET1, CRET1
|
||||
| ins_next1
|
||||
| sw TISNUM, HI(RA)
|
||||
| sw CRET1, LO(RA)
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins
|
||||
| // RA = dst*8, RB = src1*8, RC = src2*8
|
||||
| decode_RB8a RB, INS
|
||||
| decode_RB8b RB
|
||||
| decode_RDtoRC8 RC, RD
|
||||
| addu RB, BASE, RB
|
||||
| addu RC, BASE, RC
|
||||
| lw TMP0, HI(RB)
|
||||
| lw TMP1, HI(RC)
|
||||
| lw CRET1, LO(RB)
|
||||
| bne TMP0, TISNUM, ->vmeta_bitop
|
||||
|. addu RA, BASE, RA
|
||||
| lw CRET2, LO(RC)
|
||||
| bne TMP1, TISNUM, ->vmeta_bitop
|
||||
|. ins CRET1, CRET1, CRET2
|
||||
| ins_next1
|
||||
| sw TISNUM, HI(RA)
|
||||
| sw CRET1, LO(RA)
|
||||
| ins_next2
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop or
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop xor
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop sllv
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop srlv
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop srav
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
@@ -1027,6 +1027,24 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| b ->vmeta_binop // Binop call for compatibility.
|
||||
|. nop
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| move RC, RB
|
||||
|
|
||||
|->vmeta_bitop:
|
||||
| load_got lj_meta_bitop
|
||||
| sd BASE, L->base
|
||||
| move CARG2, RA
|
||||
| sd PC, SAVE_PC
|
||||
| move CARG3, RB
|
||||
| move CARG4, RC
|
||||
| decode_OP1 CARG5, INS // CARG5 == RB.
|
||||
| call_intern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
|. move CARG1, L
|
||||
| b ->cont_nop
|
||||
|. nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -4113,6 +4131,65 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| // RA = dst*8, RD = src*8
|
||||
| daddu RB, BASE, RD
|
||||
| ld CRET1, 0(RB)
|
||||
| gettp TMP0, CRET1
|
||||
| bne TMP0, TISNUM, ->vmeta_bnot
|
||||
|. daddu RA, BASE, RA
|
||||
| not CRET1, CRET1
|
||||
| zextw CRET1, CRET1
|
||||
| settp CRET1, TISNUM
|
||||
| ins_next1
|
||||
| sd CRET1, 0(RA)
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins
|
||||
| // RA = dst*8, RB = table*8, RC = key*8
|
||||
| decode_RB8a RB, INS
|
||||
| decode_RB8b RB
|
||||
| decode_RDtoRC8 RC, RD
|
||||
| daddu RB, BASE, RB
|
||||
| daddu RC, BASE, RC
|
||||
| ld CRET1, 0(RB)
|
||||
| ld CRET2, 0(RC)
|
||||
| gettp TMP0, CRET1
|
||||
| daddu RA, BASE, RA
|
||||
| bne TMP0, TISNUM, ->vmeta_bitop
|
||||
|. gettp TMP1, CRET2
|
||||
| sextw CRET1, CRET1
|
||||
| bne TMP1, TISNUM, ->vmeta_bitop
|
||||
|. ins CRET1, CRET1, CRET2
|
||||
| zextw CRET1, CRET1
|
||||
| settp CRET1, TISNUM
|
||||
| ins_next1
|
||||
| sd CRET1, 0(RA)
|
||||
| ins_next2
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop or
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop xor
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop sllv
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop srlv
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop srav
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
@@ -1268,6 +1268,25 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
| b ->vmeta_binop // Binop call for compatibility.
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| mr CARG3, RD
|
||||
| mr CARG4, RD
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_bitop:
|
||||
| mr CARG3, RB
|
||||
| mr CARG4, RC
|
||||
|1:
|
||||
| add CARG2, BASE, RA
|
||||
| stp BASE, L->base
|
||||
| mr CARG1, L
|
||||
| stw PC, SAVE_PC
|
||||
| decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS.
|
||||
| bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| b ->cont_nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -4357,6 +4376,87 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| lwzux CARG1, RD, BASE
|
||||
|.if DUALNUM
|
||||
| lwz CARG2, 4(RD)
|
||||
| checknum cr0, CARG1
|
||||
| bne ->vmeta_bnot
|
||||
|.else
|
||||
| lfd FARG1, 0(RD)
|
||||
| checknum cr0, CARG1
|
||||
| bge ->vmeta_bnot
|
||||
| fadd FARG1, FARG1, TOBIT
|
||||
| stfd FARG1, TMPD
|
||||
| lwz CARG2, TMPD_LO
|
||||
|.endif
|
||||
| not CARG2, CARG2
|
||||
|7:
|
||||
|.if DUALNUM
|
||||
| ins_next1
|
||||
| stwux TISNUM, RA, BASE
|
||||
| stw CARG2, 4(RA)
|
||||
|.else
|
||||
| tonum_u FARG1, CARG2
|
||||
| ins_next1
|
||||
| stfdx FARG1, BASE, RA
|
||||
|.endif
|
||||
| ins_next2
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins, shmod
|
||||
| // RA = dst*8, RB = src1*8, RC = src2*8
|
||||
| lwzux CARG1, RB, BASE
|
||||
| lwzux CARG3, RC, BASE
|
||||
|.if DUALNUM
|
||||
| lwz CARG2, 4(RB)
|
||||
| lwz CARG4, 4(RC)
|
||||
| checknum cr0, CARG1
|
||||
| checknum cr1, CARG3
|
||||
| bne ->vmeta_bitop
|
||||
| bne cr1, ->vmeta_bitop
|
||||
|.else
|
||||
| lfd FARG1, 0(RB)
|
||||
| lfd FARG2, 0(RC)
|
||||
| checknum cr0, CARG1
|
||||
| checknum cr1, CARG3
|
||||
| bge ->vmeta_bitop
|
||||
| bge cr1, ->vmeta_bitop
|
||||
| fadd FARG1, FARG1, TOBIT
|
||||
| fadd FARG2, FARG2, TOBIT
|
||||
| stfd FARG1, TMPD
|
||||
| lwz CARG2, TMPD_LO
|
||||
| stfd FARG2, TMPD
|
||||
| lwz CARG4, TMPD_LO
|
||||
|.endif
|
||||
|.if shmod == 1
|
||||
| rlwinm CARG4, CARG4, 0, 27, 31
|
||||
|.endif
|
||||
| ins CARG2, CARG2, CARG4
|
||||
| b <7
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and, 0
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop or, 0
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop xor, 0
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop slw, 1
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop srw, 1
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop sraw, 1
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
+124
-1
@@ -1092,6 +1092,47 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
| jmp ->vmeta_binop // Binop call for compatibility.
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| mov RB, RA
|
||||
| lea RC, [BASE+RD*8]
|
||||
| mov RA, RC
|
||||
| jmp >2
|
||||
|
|
||||
|// Caveat: ra=RB rb=RC rc=RA.
|
||||
|->vmeta_bitop:
|
||||
|.if DUALNUM
|
||||
| movzx RCd, PC_RB
|
||||
| movzx RAd, PC_RC
|
||||
|.endif
|
||||
| lea RC, [BASE+RC*8]
|
||||
| lea RA, [BASE+RA*8]
|
||||
|2:
|
||||
|.if X64WIN
|
||||
| mov CARG3, RC
|
||||
| mov CARG4, RA
|
||||
| lea RA, [BASE+RB*8]
|
||||
| movzx RC, PC_OP
|
||||
| mov ARG5, RC
|
||||
| mov L:RB, SAVE_L
|
||||
| mov L:RB->base, BASE // Caveat: CARG2d == BASE.
|
||||
| mov CARG2, RA
|
||||
| mov CARG1, L:RB // Caveat: CARG1d == RA.
|
||||
|.else
|
||||
| lea CARG2, [BASE+RB*8]
|
||||
| // CARG4 == RA.
|
||||
| movzx CARG5, PC_OP
|
||||
| mov L:CARG1, SAVE_L
|
||||
| mov L:CARG1->base, BASE // Caveat: CARG3d == BASE.
|
||||
| mov CARG3, RC
|
||||
| mov L:RB, L:CARG1
|
||||
|.endif
|
||||
| mov SAVE_PC, PC
|
||||
| call extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| mov BASE, L:RB->base
|
||||
| jmp ->cont_nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -3416,7 +3457,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
|.if DUALNUM
|
||||
| ins_arithdn intins
|
||||
|.else
|
||||
| ins_arith, sseins
|
||||
| ins_arith sseins
|
||||
|.endif
|
||||
|.endmacro
|
||||
|
||||
@@ -3476,6 +3517,88 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| ins_AD // RA = dst, RD = src
|
||||
|.if DUALNUM
|
||||
| mov RB, [BASE+RD*8]
|
||||
| checkint RB, ->vmeta_bnot
|
||||
| not RBd
|
||||
| setint RB
|
||||
| mov [BASE+RA*8], RB
|
||||
| ins_next
|
||||
|.else
|
||||
| checknumtp [BASE+RD*8], ->vmeta_bnot
|
||||
| movsd xmm0, qword [BASE+RD*8]
|
||||
| sseconst_tobit xmm1, RB
|
||||
| addsd xmm0, xmm1
|
||||
| movd RBd, xmm0
|
||||
| not RBd
|
||||
| cvtsi2sd xmm0, RBd
|
||||
| movsd qword [BASE+RA*8], xmm0
|
||||
| ins_next
|
||||
|.endif
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins, shift
|
||||
| ins_A // Really ins_ABC. RB = dst, RC = src1, RA = src2
|
||||
| // Swap registers around to avoid reloading RA.
|
||||
| mov RB, RA
|
||||
| movzx RAd, RCL // Really src2 (C).
|
||||
| movzx RCd, RCH // Really src1 (B).
|
||||
|.if DUALNUM
|
||||
| mov RA, [BASE+RA*8]
|
||||
| mov RC, [BASE+RC*8]
|
||||
| checkint RA, ->vmeta_bitop
|
||||
| checkint RC, ->vmeta_bitop
|
||||
|.if shift == 1
|
||||
| ins RCd, cl // Assumes RA is ecx.
|
||||
|.else
|
||||
| ins RCd, RAd
|
||||
|.endif
|
||||
| setint RC
|
||||
| mov [BASE+RB*8], RC
|
||||
|.else
|
||||
| checknumtp [BASE+RA*8], ->vmeta_bitop
|
||||
| checknumtp [BASE+RC*8], ->vmeta_bitop
|
||||
| movsd xmm0, qword [BASE+RA*8]
|
||||
| movsd xmm1, qword [BASE+RC*8]
|
||||
| sseconst_tobit xmm2, RC
|
||||
| addsd xmm0, xmm2
|
||||
| addsd xmm1, xmm2
|
||||
| movd RAd, xmm0
|
||||
| movd RCd, xmm1
|
||||
|.if shift == 1
|
||||
| ins RCd, cl // Assumes RA is ecx.
|
||||
|.else
|
||||
| ins RCd, RAd
|
||||
|.endif
|
||||
| cvtsi2sd xmm0, RCd
|
||||
| movsd qword [BASE+RB*8], xmm0
|
||||
|.endif
|
||||
| ins_next
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and, 0
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop or, 0
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop xor, 0
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop shl, 1
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop shr, 1
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop sar, 1
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
+131
-1
@@ -1337,6 +1337,53 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
| jmp ->vmeta_binop // Binop call for compatibility.
|
||||
#endif
|
||||
|
|
||||
|//-- Bit operator metamethods -------------------------------------------
|
||||
|
|
||||
|->vmeta_bnot:
|
||||
| mov RB, RA
|
||||
| lea RC, [BASE+RD*8]
|
||||
| mov RA, RC
|
||||
| jmp >2
|
||||
|
|
||||
|// Caveat: ra=RB rb=RC rc=RA.
|
||||
|->vmeta_bitop:
|
||||
| lea RC, [BASE+RC*8]
|
||||
| lea RA, [BASE+RA*8]
|
||||
|2:
|
||||
|.if X64WIN
|
||||
| mov CARG3d, RC
|
||||
| mov CARG4d, RA
|
||||
| lea RA, [BASE+RB*8]
|
||||
| movzx RC, PC_OP
|
||||
| mov ARG5d, RC
|
||||
| mov L:RB, SAVE_L
|
||||
| mov L:RB->base, BASE // Caveat: CARG2d == BASE.
|
||||
| mov CARG2d, RA
|
||||
| mov CARG1d, L:RB // Caveat: CARG1d == RA.
|
||||
|.elif X64
|
||||
| lea CARG2, [BASE+RB*8]
|
||||
| // CARG4d == RA.
|
||||
| movzx CARG5d, PC_OP
|
||||
| mov L:CARG1d, SAVE_L
|
||||
| mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
|
||||
| mov CARG3d, RC
|
||||
| mov L:RB, L:CARG1d
|
||||
|.else
|
||||
| lea RB, [BASE+RB*8]
|
||||
| mov ARG3, RC
|
||||
| movzx RC, PC_OP
|
||||
| mov ARG2, RB
|
||||
| mov L:RB, SAVE_L
|
||||
| mov ARG4, RA
|
||||
| mov ARG5, RC
|
||||
| mov ARG1, L:RB
|
||||
| mov L:RB->base, BASE
|
||||
|.endif
|
||||
| mov SAVE_PC, PC
|
||||
| call extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| mov BASE, L:RB->base
|
||||
| jmp ->cont_nop
|
||||
|
|
||||
|//-- Call metamethod ----------------------------------------------------
|
||||
|
|
||||
@@ -4006,7 +4053,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
|.if DUALNUM
|
||||
| ins_arithdn intins
|
||||
|.else
|
||||
| ins_arith, sseins
|
||||
| ins_arith sseins
|
||||
|.endif
|
||||
|.endmacro
|
||||
|
||||
@@ -4092,6 +4139,89 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next
|
||||
break;
|
||||
|
||||
/* -- Bit ops ----------------------------------------------------------- */
|
||||
|
||||
case BC_BNOT:
|
||||
| ins_AD // RA = dst, RD = src
|
||||
|.if DUALNUM
|
||||
| checkint RD, ->vmeta_bnot
|
||||
| mov RB, [BASE+RD*8]
|
||||
| not RB
|
||||
| mov dword [BASE+RA*8+4], LJ_TISNUM
|
||||
| mov dword [BASE+RA*8], RB
|
||||
| ins_next
|
||||
|.else
|
||||
| checknum RD, ->vmeta_bnot
|
||||
| movsd xmm0, qword [BASE+RD*8]
|
||||
| sseconst_tobit xmm1, RBa
|
||||
| addsd xmm0, xmm1
|
||||
| movd RB, xmm0
|
||||
| not RB
|
||||
| cvtsi2sd xmm0, RB
|
||||
| movsd qword [BASE+RA*8], xmm0
|
||||
| ins_next
|
||||
|.endif
|
||||
break;
|
||||
|
||||
|.macro ins_bitop, ins, shift
|
||||
| ins_A // Really ins_ABC. RB = dst, RC = src1, RA = src2
|
||||
| // Swap registers around to avoid reloading RA.
|
||||
| mov RB, RA
|
||||
| movzx RA, RCL // Really src2 (C).
|
||||
| movzx RC, RCH // Really src1 (B).
|
||||
|.if DUALNUM
|
||||
| checkint RA, ->vmeta_bitop
|
||||
| checkint RC, ->vmeta_bitop
|
||||
|.if shift == 1
|
||||
| mov RA, [BASE+RA*8]
|
||||
| mov RC, [BASE+RC*8]
|
||||
| ins RC, cl // Assumes RA is ecx.
|
||||
|.else
|
||||
| mov RC, [BASE+RC*8]
|
||||
| ins RC, [BASE+RA*8]
|
||||
|.endif
|
||||
| mov dword [BASE+RB*8+4], LJ_TISNUM
|
||||
| mov dword [BASE+RB*8], RC
|
||||
|.else
|
||||
| checknum RA, ->vmeta_bitop
|
||||
| checknum RC, ->vmeta_bitop
|
||||
| movsd xmm0, qword [BASE+RA*8]
|
||||
| movsd xmm1, qword [BASE+RC*8]
|
||||
| sseconst_tobit xmm2, RCa
|
||||
| addsd xmm0, xmm2
|
||||
| addsd xmm1, xmm2
|
||||
| movd RA, xmm0
|
||||
| movd RC, xmm1
|
||||
|.if shift == 1
|
||||
| ins RC, cl // Assumes RA is ecx.
|
||||
|.else
|
||||
| ins RC, RA
|
||||
|.endif
|
||||
| cvtsi2sd xmm0, RC
|
||||
| movsd qword [BASE+RB*8], xmm0
|
||||
|.endif
|
||||
| ins_next
|
||||
|.endmacro
|
||||
|
||||
case BC_BAND:
|
||||
| ins_bitop and, 0
|
||||
break;
|
||||
case BC_BOR:
|
||||
| ins_bitop or, 0
|
||||
break;
|
||||
case BC_BXOR:
|
||||
| ins_bitop xor, 0
|
||||
break;
|
||||
case BC_BSHL:
|
||||
| ins_bitop shl, 1
|
||||
break;
|
||||
case BC_BSHR:
|
||||
| ins_bitop shr, 1
|
||||
break;
|
||||
case BC_BSAR:
|
||||
| ins_bitop sar, 1
|
||||
break;
|
||||
|
||||
/* -- Constant ops ------------------------------------------------------ */
|
||||
|
||||
case BC_KSTR:
|
||||
|
||||
Reference in New Issue
Block a user