aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_ppc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_ppc.h')
-rw-r--r--src/lj_asm_ppc.h27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 6555312d..8e9a92a4 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -840,23 +840,30 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
840static void asm_uref(ASMState *as, IRIns *ir) 840static void asm_uref(ASMState *as, IRIns *ir)
841{ 841{
842 Reg dest = ra_dest(as, ir, RSET_GPR); 842 Reg dest = ra_dest(as, ir, RSET_GPR);
843 if (irref_isk(ir->op1)) { 843 int guarded = (irt_t(ir->t) & (IRT_GUARD|IRT_TYPE)) == (IRT_GUARD|IRT_PGC);
844 if (irref_isk(ir->op1) && !guarded) {
844 GCfunc *fn = ir_kfunc(IR(ir->op1)); 845 GCfunc *fn = ir_kfunc(IR(ir->op1));
845 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; 846 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
846 emit_lsptr(as, PPCI_LWZ, dest, v, RSET_GPR); 847 emit_lsptr(as, PPCI_LWZ, dest, v, RSET_GPR);
847 } else { 848 } else {
848 Reg uv = ra_scratch(as, RSET_GPR); 849 if (guarded) {
849 Reg func = ra_alloc1(as, ir->op1, RSET_GPR); 850 asm_guardcc(as, ir->o == IR_UREFC ? CC_NE : CC_EQ);
850 if (ir->o == IR_UREFC) {
851 asm_guardcc(as, CC_NE);
852 emit_ai(as, PPCI_CMPWI, RID_TMP, 1); 851 emit_ai(as, PPCI_CMPWI, RID_TMP, 1);
853 emit_tai(as, PPCI_ADDI, dest, uv, (int32_t)offsetof(GCupval, tv)); 852 }
854 emit_tai(as, PPCI_LBZ, RID_TMP, uv, (int32_t)offsetof(GCupval, closed)); 853 if (ir->o == IR_UREFC)
854 emit_tai(as, PPCI_ADDI, dest, dest, (int32_t)offsetof(GCupval, tv));
855 else
856 emit_tai(as, PPCI_LWZ, dest, dest, (int32_t)offsetof(GCupval, v));
857 if (guarded)
858 emit_tai(as, PPCI_LBZ, RID_TMP, dest, (int32_t)offsetof(GCupval, closed));
859 if (irref_isk(ir->op1)) {
860 GCfunc *fn = ir_kfunc(IR(ir->op1));
861 int32_t k = (int32_t)gcrefu(fn->l.uvptr[(ir->op2 >> 8)]);
862 emit_loadi(as, dest, k);
855 } else { 863 } else {
856 emit_tai(as, PPCI_LWZ, dest, uv, (int32_t)offsetof(GCupval, v)); 864 emit_tai(as, PPCI_LWZ, dest, ra_alloc1(as, ir->op1, RSET_GPR),
865 (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8));
857 } 866 }
858 emit_tai(as, PPCI_LWZ, uv, func,
859 (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8));
860 } 867 }
861} 868}
862 869