diff options
Diffstat (limited to 'src/lj_asm_arm64.h')
-rw-r--r-- | src/lj_asm_arm64.h | 20 |
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) | |||
931 | static void asm_uref(ASMState *as, IRIns *ir) | 931 | static 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 | ||