Refactor IR_VLOAD to take an offset.

This commit is contained in:
Mike Pall 2021-09-19 17:18:16 +02:00
parent f2d333c1ac
commit 9211f0b03b
9 changed files with 19 additions and 13 deletions

View File

@ -1133,6 +1133,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
} }
idx = asm_fuseahuref(as, ir->op1, &ofs, allow, idx = asm_fuseahuref(as, ir->op1, &ofs, allow,
(!LJ_SOFTFP && t == IRT_NUM) ? 1024 : 4096); (!LJ_SOFTFP && t == IRT_NUM) ? 1024 : 4096);
if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
if (!hiop || type == RID_NONE) { if (!hiop || type == RID_NONE) {
rset_clear(allow, idx); rset_clear(allow, idx);
if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 && if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 &&

View File

@ -1078,6 +1078,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
} }
type = ra_scratch(as, rset_clear(gpr, tmp)); type = ra_scratch(as, rset_clear(gpr, tmp));
idx = asm_fuseahuref(as, ir->op1, &ofs, rset_clear(gpr, type), A64I_LDRx); idx = asm_fuseahuref(as, ir->op1, &ofs, rset_clear(gpr, type), A64I_LDRx);
if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
/* Always do the type check, even if the load result is unused. */ /* Always do the type check, even if the load result is unused. */
asm_guardcc(as, irt_isnum(ir->t) ? CC_LS : CC_NE); asm_guardcc(as, irt_isnum(ir->t) ? CC_LS : CC_NE);
if (irt_type(ir->t) >= IRT_NUM) { if (irt_type(ir->t) >= IRT_NUM) {

View File

@ -1417,6 +1417,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
#endif #endif
} }
idx = asm_fuseahuref(as, ir->op1, &ofs, allow); idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
rset_clear(allow, idx); rset_clear(allow, idx);
if (irt_isnum(t)) { if (irt_isnum(t)) {
asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);

View File

@ -1019,6 +1019,10 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
rset_clear(allow, dest); rset_clear(allow, dest);
} }
idx = asm_fuseahuref(as, ir->op1, &ofs, allow); idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
if (ir->o == IR_VLOAD) {
ofs = ofs != AHUREF_LSX ? ofs + 8 * ir->op2 :
ir->op2 ? 8 * ir->op2 : AHUREF_LSX;
}
if (irt_isnum(t)) { if (irt_isnum(t)) {
Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, rset_exclude(allow, idx)); Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, rset_exclude(allow, idx));
asm_guardcc(as, CC_GE); asm_guardcc(as, CC_GE);

View File

@ -227,9 +227,6 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
#endif #endif
return; return;
default: default:
lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO ||
ir->o == IR_KKPTR,
"bad IR op %d", ir->o);
break; break;
} }
} }
@ -490,6 +487,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
} }
} else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) { } else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) {
asm_fuseahuref(as, ir->op1, xallow); asm_fuseahuref(as, ir->op1, xallow);
as->mrm.ofs += 8 * ir->op2;
return RID_MRM; return RID_MRM;
} }
} }
@ -1550,6 +1548,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
Reg dest = asm_load_lightud64(as, ir, 1); Reg dest = asm_load_lightud64(as, ir, 1);
if (ra_hasreg(dest)) { if (ra_hasreg(dest)) {
asm_fuseahuref(as, ir->op1, RSET_GPR); asm_fuseahuref(as, ir->op1, RSET_GPR);
if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM); emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM);
} }
return; return;
@ -1559,6 +1558,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR; RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
Reg dest = ra_dest(as, ir, allow); Reg dest = ra_dest(as, ir, allow);
asm_fuseahuref(as, ir->op1, RSET_GPR); asm_fuseahuref(as, ir->op1, RSET_GPR);
if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
#if LJ_GC64 #if LJ_GC64
if (irt_isaddr(ir->t)) { if (irt_isaddr(ir->t)) {
emit_shifti(as, XOg_SHR|REX_64, dest, 17); emit_shifti(as, XOg_SHR|REX_64, dest, 17);
@ -1586,6 +1586,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
} }
#endif #endif
asm_fuseahuref(as, ir->op1, gpr); asm_fuseahuref(as, ir->op1, gpr);
if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
} }
/* Always do the type check, even if the load result is unused. */ /* Always do the type check, even if the load result is unused. */
as->mrm.ofs += 4; as->mrm.ofs += 4;

View File

@ -1317,7 +1317,7 @@ static void LJ_FASTCALL recff_buffer_method_decode(jit_State *J, RecordFFData *r
trr = lj_ir_call(J, IRCALL_lj_serialize_get, trbuf, tmp); trr = lj_ir_call(J, IRCALL_lj_serialize_get, trbuf, tmp);
/* No IR_USE needed, since the call is a store. */ /* No IR_USE needed, since the call is a store. */
t = (IRType)lj_serialize_peektype(bufV(&rd->argv[0])); t = (IRType)lj_serialize_peektype(bufV(&rd->argv[0]));
J->base[0] = lj_record_vload(J, tmp, t); J->base[0] = lj_record_vload(J, tmp, 0, t);
/* The sbx->r store must be after the VLOAD type check, in case it fails. */ /* The sbx->r store must be after the VLOAD type check, in case it fails. */
recff_sbufx_set_ptr(J, ud, IRFL_SBUF_R, trr); recff_sbufx_set_ptr(J, ud, IRFL_SBUF_R, trr);
} }
@ -1350,7 +1350,7 @@ static void LJ_FASTCALL recff_buffer_decode(jit_State *J, RecordFFData *rd)
memset(&sbx, 0, sizeof(SBufExt)); memset(&sbx, 0, sizeof(SBufExt));
lj_bufx_set_cow(J->L, &sbx, strdata(str), str->len); lj_bufx_set_cow(J->L, &sbx, strdata(str), str->len);
t = (IRType)lj_serialize_peektype(&sbx); t = (IRType)lj_serialize_peektype(&sbx);
J->base[0] = lj_record_vload(J, tmp, t); J->base[0] = lj_record_vload(J, tmp, 0, t);
} /* else: Interpreter will throw. */ } /* else: Interpreter will throw. */
} }

View File

@ -106,7 +106,7 @@
_(FLOAD, L , ref, lit) \ _(FLOAD, L , ref, lit) \
_(XLOAD, L , ref, lit) \ _(XLOAD, L , ref, lit) \
_(SLOAD, L , lit, lit) \ _(SLOAD, L , lit, lit) \
_(VLOAD, L , ref, ___) \ _(VLOAD, L , ref, lit) \
_(ALEN, L , ref, ref) \ _(ALEN, L , ref, ref) \
\ \
_(ASTORE, S , ref, ref) \ _(ASTORE, S , ref, ref) \

View File

@ -260,9 +260,9 @@ TRef lj_record_constify(jit_State *J, cTValue *o)
} }
/* Emit a VLOAD with the correct type. */ /* Emit a VLOAD with the correct type. */
TRef lj_record_vload(jit_State *J, TRef ref, IRType t) TRef lj_record_vload(jit_State *J, TRef ref, MSize idx, IRType t)
{ {
TRef tr = emitir(IRTG(IR_VLOAD, t), ref, 0); TRef tr = emitir(IRTG(IR_VLOAD, t), ref, idx);
if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */
return tr; return tr;
} }
@ -1848,9 +1848,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8)); vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8));
for (i = 0; i < nload; i++) { for (i = 0; i < nload; i++) {
IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]); IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]);
TRef aref = emitir(IRT(IR_AREF, IRT_PGC), J->base[dst+i] = lj_record_vload(J, vbase, i, t);
vbase, lj_ir_kint(J, (int32_t)i));
J->base[dst+i] = lj_record_vload(J, aref, t);
} }
} else { } else {
emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs)); emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs));
@ -1897,7 +1895,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
lj_ir_kint(J, frofs-(8<<LJ_FR2))); lj_ir_kint(J, frofs-(8<<LJ_FR2)));
t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]); t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]);
aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx);
tr = lj_record_vload(J, aref, t); tr = lj_record_vload(J, aref, 0, t);
} }
J->base[dst-2-LJ_FR2] = tr; J->base[dst-2-LJ_FR2] = tr;
J->maxslot = dst-1-LJ_FR2; J->maxslot = dst-1-LJ_FR2;

View File

@ -30,7 +30,7 @@ LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
cTValue *av, cTValue *bv); cTValue *av, cTValue *bv);
LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk); LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk);
LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o); LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o);
LJ_FUNC TRef lj_record_vload(jit_State *J, TRef ref, IRType t); LJ_FUNC TRef lj_record_vload(jit_State *J, TRef ref, MSize idx, IRType t);
LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs); LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs);
LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs); LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs);