mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Specialize metatables for method calls
This commit is contained in:
parent
dad04f1754
commit
b5783323ef
@ -144,6 +144,7 @@
|
|||||||
_(GSET, var, ___, str, newindex) \
|
_(GSET, var, ___, str, newindex) \
|
||||||
_(TGETV, dst, var, var, index) \
|
_(TGETV, dst, var, var, index) \
|
||||||
_(TGETS, dst, var, str, index) \
|
_(TGETS, dst, var, str, index) \
|
||||||
|
_(TGETSS, dst, var, str, index) \
|
||||||
_(TGETB, dst, var, lit, index) \
|
_(TGETB, dst, var, lit, index) \
|
||||||
_(TGETR, dst, var, var, index) \
|
_(TGETR, dst, var, var, index) \
|
||||||
_(TSETV, var, var, var, newindex) \
|
_(TSETV, var, var, var, newindex) \
|
||||||
@ -259,6 +260,8 @@ static LJ_AINLINE int bc_isret(BCOp op)
|
|||||||
return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
|
return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define bc_isalias(op) ((op) == BC_TGETSS)
|
||||||
|
|
||||||
LJ_DATA const uint16_t lj_bc_mode[];
|
LJ_DATA const uint16_t lj_bc_mode[];
|
||||||
LJ_DATA const uint16_t lj_bc_ofs[];
|
LJ_DATA const uint16_t lj_bc_ofs[];
|
||||||
|
|
||||||
|
@ -271,13 +271,10 @@ restart:
|
|||||||
return "global";
|
return "global";
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
*name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
|
*name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
|
||||||
if (ip > proto_bc(pt)) {
|
|
||||||
BCIns insp = ip[-1];
|
|
||||||
if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1+LJ_FR2 &&
|
|
||||||
bc_d(insp) == bc_b(ins))
|
|
||||||
return "method";
|
|
||||||
}
|
|
||||||
return "field";
|
return "field";
|
||||||
|
case BC_TGETSS:
|
||||||
|
*name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
|
||||||
|
return "method";
|
||||||
case BC_UGET:
|
case BC_UGET:
|
||||||
*name = lj_debug_uvname(pt, bc_d(ins));
|
*name = lj_debug_uvname(pt, bc_d(ins));
|
||||||
return "upvalue";
|
return "upvalue";
|
||||||
|
@ -225,6 +225,7 @@ static void LJ_FASTCALL recff_getmetatable(jit_State *J, RecordFFData *rd)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 0;
|
||||||
if (lj_record_mm_lookup(J, &ix, MM_metatable))
|
if (lj_record_mm_lookup(J, &ix, MM_metatable))
|
||||||
J->base[0] = ix.mobj;
|
J->base[0] = ix.mobj;
|
||||||
else
|
else
|
||||||
@ -241,6 +242,7 @@ static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 0;
|
||||||
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
|
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
|
||||||
fref = emitir(IRT(IR_FREF, IRT_PGC), tr, IRFL_TAB_META);
|
fref = emitir(IRT(IR_FREF, IRT_PGC), tr, IRFL_TAB_META);
|
||||||
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
||||||
@ -389,6 +391,7 @@ static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = J->base[0];
|
ix.tab = J->base[0];
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
|
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
|
||||||
int errcode;
|
int errcode;
|
||||||
TValue argv0;
|
TValue argv0;
|
||||||
@ -548,6 +551,7 @@ static void LJ_FASTCALL recff_next(jit_State *J, RecordFFData *rd)
|
|||||||
ix.idxchain = (J->framedepth && frame_islua(J->L->base-1) &&
|
ix.idxchain = (J->framedepth && frame_islua(J->L->base-1) &&
|
||||||
bc_b(frame_pc(J->L->base-1)[-1])-1 < 2);
|
bc_b(frame_pc(J->L->base-1)[-1])-1 < 2);
|
||||||
ix.mobj = 0; /* We don't need the next index. */
|
ix.mobj = 0; /* We don't need the next index. */
|
||||||
|
ix.mtspec = 0;
|
||||||
rd->nres = lj_record_next(J, &ix);
|
rd->nres = lj_record_next(J, &ix);
|
||||||
J->base[0] = ix.key;
|
J->base[0] = ix.key;
|
||||||
J->base[1] = ix.val;
|
J->base[1] = ix.val;
|
||||||
|
@ -675,7 +675,7 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
|
|||||||
idx = const_str(fs, key);
|
idx = const_str(fs, key);
|
||||||
if (idx <= BCMAX_C) {
|
if (idx <= BCMAX_C) {
|
||||||
bcreg_reserve(fs, 2+LJ_FR2);
|
bcreg_reserve(fs, 2+LJ_FR2);
|
||||||
bcemit_ABC(fs, BC_TGETS, func, obj, idx);
|
bcemit_ABC(fs, BC_TGETSS, func, obj, idx);
|
||||||
} else {
|
} else {
|
||||||
bcreg_reserve(fs, 3+LJ_FR2);
|
bcreg_reserve(fs, 3+LJ_FR2);
|
||||||
bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx);
|
bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx);
|
||||||
|
@ -686,6 +686,7 @@ static LoopEvent rec_itern(jit_State *J, BCReg ra, BCReg rb)
|
|||||||
copyTV(J->L, &ix.keyv, &J->L->base[ra-1]);
|
copyTV(J->L, &ix.keyv, &J->L->base[ra-1]);
|
||||||
ix.idxchain = (rb < 3); /* Omit value type check, if unused. */
|
ix.idxchain = (rb < 3); /* Omit value type check, if unused. */
|
||||||
ix.mobj = 1; /* We need the next index, too. */
|
ix.mobj = 1; /* We need the next index, too. */
|
||||||
|
ix.mtspec = 0;
|
||||||
J->maxslot = ra + lj_record_next(J, &ix);
|
J->maxslot = ra + lj_record_next(J, &ix);
|
||||||
J->needsnap = 1;
|
J->needsnap = 1;
|
||||||
if (!tref_isnil(ix.key)) { /* Looping back? */
|
if (!tref_isnil(ix.key)) { /* Looping back? */
|
||||||
@ -818,6 +819,7 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
|
|||||||
if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
|
if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
|
||||||
ix.tab = fbase[0];
|
ix.tab = fbase[0];
|
||||||
copyTV(J->L, &ix.tabv, functv);
|
copyTV(J->L, &ix.tabv, functv);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
|
if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
|
||||||
lj_trace_err(J, LJ_TRERR_NOMM);
|
lj_trace_err(J, LJ_TRERR_NOMM);
|
||||||
for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */
|
for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */
|
||||||
@ -1103,7 +1105,14 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
|
|||||||
goto nocheck;
|
goto nocheck;
|
||||||
}
|
}
|
||||||
ix->mt = mt ? mix.tab : TREF_NIL;
|
ix->mt = mt ? mix.tab : TREF_NIL;
|
||||||
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
|
if (ix->mtspec && mt) {
|
||||||
|
TRef kmt = lj_ir_ktab(J, mt);
|
||||||
|
emitir(IRTG(IR_EQ, IRT_TAB), mix.tab, kmt);
|
||||||
|
mix.tab = kmt;
|
||||||
|
ix->mt = kmt;
|
||||||
|
} else {
|
||||||
|
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
|
||||||
|
}
|
||||||
nocheck:
|
nocheck:
|
||||||
if (mt) {
|
if (mt) {
|
||||||
GCstr *mmstr = mmname_str(J2G(J), mm);
|
GCstr *mmstr = mmname_str(J2G(J), mm);
|
||||||
@ -1157,6 +1166,7 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, tv);
|
copyTV(J->L, &ix.tabv, tv);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (lj_record_mm_lookup(J, &ix, MM_len)) {
|
if (lj_record_mm_lookup(J, &ix, MM_len)) {
|
||||||
BCReg func = rec_mm_prep(J, lj_cont_ra);
|
BCReg func = rec_mm_prep(J, lj_cont_ra);
|
||||||
TRef *base = J->base + func;
|
TRef *base = J->base + func;
|
||||||
@ -2086,6 +2096,7 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|||||||
ix.tab = top[-1];
|
ix.tab = top[-1];
|
||||||
ix.key = top[0];
|
ix.key = top[0];
|
||||||
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
||||||
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
||||||
return 0; /* No result yet. */
|
return 0; /* No result yet. */
|
||||||
@ -2290,6 +2301,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
rc = lj_ir_kint(J, 0);
|
rc = lj_ir_kint(J, 0);
|
||||||
ta = IRT_INT;
|
ta = IRT_INT;
|
||||||
} else {
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_comp(J, &ix, (int)op);
|
rec_mm_comp(J, &ix, (int)op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2313,10 +2325,12 @@ void lj_record_ins(jit_State *J)
|
|||||||
int diff;
|
int diff;
|
||||||
rec_comp_prep(J);
|
rec_comp_prep(J);
|
||||||
diff = lj_record_objcmp(J, ra, rc, rav, rcv);
|
diff = lj_record_objcmp(J, ra, rc, rav, rcv);
|
||||||
if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
|
if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra))) {
|
||||||
rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
|
rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
|
||||||
else if (diff == 1) /* Only check __eq if different, but same type. */
|
} else if (diff == 1) { /* Only check __eq if different, but same type. */
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_equal(J, &ix, (int)op);
|
rec_mm_equal(J, &ix, (int)op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2367,6 +2381,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
} else {
|
} else {
|
||||||
ix.tab = rc;
|
ix.tab = rc;
|
||||||
copyTV(J->L, &ix.tabv, rcv);
|
copyTV(J->L, &ix.tabv, rcv);
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_unm);
|
rc = rec_mm_arith(J, &ix, MM_unm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2383,27 +2398,33 @@ void lj_record_ins(jit_State *J)
|
|||||||
case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
|
case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
|
||||||
case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
|
case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
|
||||||
MMS mm = bcmode_mm(op);
|
MMS mm = bcmode_mm(op);
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
|
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
|
||||||
(int)mm - (int)MM_add + (int)IR_ADD);
|
(int)mm - (int)MM_add + (int)IR_ADD);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, mm);
|
rc = rec_mm_arith(J, &ix, mm);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BC_MODVN: case BC_MODVV:
|
case BC_MODVN: case BC_MODVV:
|
||||||
recmod:
|
recmod:
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
|
rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_mod);
|
rc = rec_mm_arith(J, &ix, MM_mod);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_POW:
|
case BC_POW:
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
|
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_pow);
|
rc = rec_mm_arith(J, &ix, MM_pow);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -- Miscellaneous ops ------------------------------------------------- */
|
/* -- Miscellaneous ops ------------------------------------------------- */
|
||||||
@ -2457,6 +2478,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
|
settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
|
||||||
ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
|
ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
|
||||||
ix.idxchain = LJ_MAX_IDXCHAIN;
|
ix.idxchain = LJ_MAX_IDXCHAIN;
|
||||||
|
ix.mtspec = 0;
|
||||||
rc = lj_record_idx(J, &ix);
|
rc = lj_record_idx(J, &ix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2466,6 +2488,12 @@ void lj_record_ins(jit_State *J)
|
|||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
|
case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
|
||||||
ix.idxchain = LJ_MAX_IDXCHAIN;
|
ix.idxchain = LJ_MAX_IDXCHAIN;
|
||||||
|
ix.mtspec = 0;
|
||||||
|
rc = lj_record_idx(J, &ix);
|
||||||
|
break;
|
||||||
|
case BC_TGETSS:
|
||||||
|
ix.idxchain = LJ_MAX_IDXCHAIN;
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = lj_record_idx(J, &ix);
|
rc = lj_record_idx(J, &ix);
|
||||||
break;
|
break;
|
||||||
case BC_TGETR: case BC_TSETR:
|
case BC_TGETR: case BC_TSETR:
|
||||||
|
@ -23,7 +23,8 @@ typedef struct RecordIndex {
|
|||||||
TRef val; /* Value reference for a store or 0 for a load. */
|
TRef val; /* Value reference for a store or 0 for a load. */
|
||||||
TRef mt; /* Metatable reference. */
|
TRef mt; /* Metatable reference. */
|
||||||
TRef mobj; /* Metamethod object reference. */
|
TRef mobj; /* Metamethod object reference. */
|
||||||
int idxchain; /* Index indirections left or 0 for raw lookup. */
|
short idxchain; /* Index indirections left or 0 for raw lookup. */
|
||||||
|
short mtspec; /* Specialize to metatable. */
|
||||||
} RecordIndex;
|
} RecordIndex;
|
||||||
|
|
||||||
LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
|
LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
|
||||||
|
@ -2592,6 +2592,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -3542,6 +3546,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| b ->vmeta_tgetv
|
| b ->vmeta_tgetv
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| decode_RB8 RB, INS
|
| decode_RB8 RB, INS
|
||||||
| and RC, RC, #255
|
| and RC, RC, #255
|
||||||
| // RA = dst*8, RB = table*8, RC = str_const (~)
|
| // RA = dst*8, RB = table*8, RC = str_const (~)
|
||||||
|
@ -2226,6 +2226,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -2992,6 +2996,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| b ->BC_TGETS_Z
|
| b ->BC_TGETS_Z
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| decode_RB RB, INS
|
| decode_RB RB, INS
|
||||||
| and RC, RC, #255
|
| and RC, RC, #255
|
||||||
| // RA = dst, RB = table, RC = str_const (~)
|
| // RA = dst, RB = table, RC = str_const (~)
|
||||||
|
@ -2981,6 +2981,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -4076,6 +4080,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
|. nop
|
|. nop
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| // RA = dst*8, RB = table*8, RC = str_const*4 (~)
|
| // RA = dst*8, RB = table*8, RC = str_const*4 (~)
|
||||||
| decode_RB8a RB, INS
|
| decode_RB8a RB, INS
|
||||||
| decode_RB8b RB
|
| decode_RB8b RB
|
||||||
|
@ -3104,6 +3104,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -4290,6 +4294,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
|. nop
|
|. nop
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| // RA = dst*8, RB = table*8, RC = str_const*8 (~)
|
| // RA = dst*8, RB = table*8, RC = str_const*8 (~)
|
||||||
| decode_RB8a RB, INS
|
| decode_RB8a RB, INS
|
||||||
| decode_RB8b RB
|
| decode_RB8b RB
|
||||||
|
@ -3310,6 +3310,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -4563,6 +4567,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| b ->BC_TGETS_Z // String key?
|
| b ->BC_TGETS_Z // String key?
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| // RA = dst*8, RB = table*8, RC = str_const*8 (~)
|
| // RA = dst*8, RB = table*8, RC = str_const*8 (~)
|
||||||
| lwzux CARG1, RB, BASE
|
| lwzux CARG1, RB, BASE
|
||||||
| srwi TMP1, RC, 1
|
| srwi TMP1, RC, 1
|
||||||
|
@ -2796,6 +2796,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|// Note: aligning all instructions does not pay off.
|
|// Note: aligning all instructions does not pay off.
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
@ -3678,6 +3682,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| jmp ->BC_TGETS_Z
|
| jmp ->BC_TGETS_Z
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| ins_ABC // RA = dst, RB = table, RC = str const (~)
|
| ins_ABC // RA = dst, RB = table, RC = str const (~)
|
||||||
| mov TAB:RB, [BASE+RB*8]
|
| mov TAB:RB, [BASE+RB*8]
|
||||||
| not RC
|
| not RC
|
||||||
|
@ -3381,6 +3381,10 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||||
{
|
{
|
||||||
int vk = 0;
|
int vk = 0;
|
||||||
|
|
||||||
|
if (bc_isalias(op))
|
||||||
|
return;
|
||||||
|
|
||||||
|// Note: aligning all instructions does not pay off.
|
|// Note: aligning all instructions does not pay off.
|
||||||
|=>defop:
|
|=>defop:
|
||||||
|
|
||||||
@ -4309,6 +4313,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| jmp ->BC_TGETS_Z
|
| jmp ->BC_TGETS_Z
|
||||||
break;
|
break;
|
||||||
case BC_TGETS:
|
case BC_TGETS:
|
||||||
|
|=>BC_TGETSS:
|
||||||
| ins_ABC // RA = dst, RB = table, RC = str const (~)
|
| ins_ABC // RA = dst, RB = table, RC = str const (~)
|
||||||
| not RCa
|
| not RCa
|
||||||
| mov STR:RC, [KBASE+RC*4]
|
| mov STR:RC, [KBASE+RC*4]
|
||||||
|
Loading…
Reference in New Issue
Block a user