aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_arm64.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_arm64.h')
-rw-r--r--src/lj_asm_arm64.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h
index 9f165fa8..5b40f4cc 100644
--- a/src/lj_asm_arm64.h
+++ b/src/lj_asm_arm64.h
@@ -931,22 +931,30 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
931static void asm_uref(ASMState *as, IRIns *ir) 931static void asm_uref(ASMState *as, IRIns *ir)
932{ 932{
933 Reg dest = ra_dest(as, ir, RSET_GPR); 933 Reg dest = ra_dest(as, ir, RSET_GPR);
934 if (irref_isk(ir->op1)) { 934 int guarded = (irt_t(ir->t) & (IRT_GUARD|IRT_TYPE)) == (IRT_GUARD|IRT_PGC);
935 if (irref_isk(ir->op1) && !guarded) {
935 GCfunc *fn = ir_kfunc(IR(ir->op1)); 936 GCfunc *fn = ir_kfunc(IR(ir->op1));
936 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; 937 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
937 emit_lsptr(as, A64I_LDRx, dest, v); 938 emit_lsptr(as, A64I_LDRx, dest, v);
938 } else { 939 } else {
939 if (ir->o == IR_UREFC) { 940 if (guarded)
940 asm_guardcnb(as, A64I_CBZ, RID_TMP); 941 asm_guardcnb(as, ir->o == IR_UREFC ? A64I_CBZ : A64I_CBNZ, RID_TMP);
942 if (ir->o == IR_UREFC)
941 emit_opk(as, A64I_ADDx, dest, dest, 943 emit_opk(as, A64I_ADDx, dest, dest,
942 (int32_t)offsetof(GCupval, tv), RSET_GPR); 944 (int32_t)offsetof(GCupval, tv), RSET_GPR);
945 else
946 emit_lso(as, A64I_LDRx, dest, dest, (int32_t)offsetof(GCupval, v));
947 if (guarded)
943 emit_lso(as, A64I_LDRB, RID_TMP, dest, 948 emit_lso(as, A64I_LDRB, RID_TMP, dest,
944 (int32_t)offsetof(GCupval, closed)); 949 (int32_t)offsetof(GCupval, closed));
950 if (irref_isk(ir->op1)) {
951 GCfunc *fn = ir_kfunc(IR(ir->op1));
952 uint64_t k = gcrefu(fn->l.uvptr[(ir->op2 >> 8)]);
953 emit_loadu64(as, dest, k);
945 } else { 954 } else {
946 emit_lso(as, A64I_LDRx, dest, dest, (int32_t)offsetof(GCupval, v)); 955 emit_lso(as, A64I_LDRx, dest, ra_alloc1(as, ir->op1, RSET_GPR),
956 (int32_t)offsetof(GCfuncL, uvptr) + 8*(int32_t)(ir->op2 >> 8));
947 } 957 }
948 emit_lso(as, A64I_LDRx, dest, ra_alloc1(as, ir->op1, RSET_GPR),
949 (int32_t)offsetof(GCfuncL, uvptr) + 8*(int32_t)(ir->op2 >> 8));
950 } 958 }
951} 959}
952 960