diff --git a/src/lj_asm.c b/src/lj_asm.c index 0fcd8485..7ce2e5d2 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1889,6 +1889,7 @@ static void asm_head_side(ASMState *as) RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */ RegSet live = RSET_EMPTY; /* Live parent registers. */ RegSet pallow = RSET_GPR; /* Registers needed by the parent stack check. */ + Reg pbase; IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */ int32_t spadj, spdelta; int pass2 = 0; @@ -1899,7 +1900,11 @@ static void asm_head_side(ASMState *as) /* Force snap #0 alloc to prevent register overwrite in stack check. */ asm_snap_alloc(as, 0); } - allow = asm_head_side_base(as, irp, allow); + pbase = asm_head_side_base(as, irp); + if (pbase != RID_NONE) { + rset_clear(allow, pbase); + rset_clear(pallow, pbase); + } /* Scan all parent SLOADs and collect register dependencies. */ for (i = as->stopins; i > REF_BASE; i--) { diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index ba6267ec..a5ec9971 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h @@ -2167,7 +2167,7 @@ static void asm_head_root_base(ASMState *as) } /* Coalesce BASE register for a side trace. */ -static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) +static Reg asm_head_side_base(ASMState *as, IRIns *irp) { IRIns *ir; asm_head_lreg(as); @@ -2175,16 +2175,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t))) ra_spill(as, ir); if (ra_hasspill(irp->s)) { - rset_clear(allow, ra_dest(as, ir, allow)); + return ra_dest(as, ir, RSET_GPR); } else { Reg r = irp->r; lj_assertA(ra_hasreg(r), "base reg lost"); - rset_clear(allow, r); if (r != ir->r && !rset_test(as->freeset, r)) ra_restore(as, regcost_ref(as->cost[r])); ra_destreg(as, ir, r); + return r; } - return allow; } /* -- Tail of trace ------------------------------------------------------- */ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index 95138fe9..d3e4bb63 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h @@ -1915,7 +1915,7 @@ static void asm_head_root_base(ASMState *as) } /* Coalesce BASE register for a side trace. */ -static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) +static Reg asm_head_side_base(ASMState *as, IRIns *irp) { IRIns *ir; asm_head_lreg(as); @@ -1923,16 +1923,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t))) ra_spill(as, ir); if (ra_hasspill(irp->s)) { - rset_clear(allow, ra_dest(as, ir, allow)); + return ra_dest(as, ir, RSET_GPR); } else { Reg r = irp->r; lj_assertA(ra_hasreg(r), "base reg lost"); - rset_clear(allow, r); if (r != ir->r && !rset_test(as->freeset, r)) ra_restore(as, regcost_ref(as->cost[r])); ra_destreg(as, ir, r); + return r; } - return allow; } /* -- Tail of trace ------------------------------------------------------- */ diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index ac2d2662..e9cce916 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h @@ -2667,7 +2667,7 @@ static void asm_head_root_base(ASMState *as) } /* Coalesce BASE register for a side trace. */ -static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) +static Reg asm_head_side_base(ASMState *as, IRIns *irp) { IRIns *ir = IR(REF_BASE); Reg r = ir->r; @@ -2676,15 +2676,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (rset_test(as->modset, r) || irt_ismarked(ir->t)) ir->r = RID_INIT; /* No inheritance for modified BASE register. */ if (irp->r == r) { - rset_clear(allow, r); /* Mark same BASE register as coalesced. */ + return r; /* Same BASE register already coalesced. */ } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) { - rset_clear(allow, irp->r); emit_move(as, r, irp->r); /* Move from coalesced parent reg. */ + return irp->r; } else { emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */ } } - return allow; + return RID_NONE; } /* -- Tail of trace ------------------------------------------------------- */ diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index aa818745..ccc3979c 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h @@ -2186,7 +2186,7 @@ static void asm_head_root_base(ASMState *as) } /* Coalesce BASE register for a side trace. */ -static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) +static Reg asm_head_side_base(ASMState *as, IRIns *irp) { IRIns *ir = IR(REF_BASE); Reg r = ir->r; @@ -2195,15 +2195,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (rset_test(as->modset, r) || irt_ismarked(ir->t)) ir->r = RID_INIT; /* No inheritance for modified BASE register. */ if (irp->r == r) { - rset_clear(allow, r); /* Mark same BASE register as coalesced. */ + return r; /* Same BASE register already coalesced. */ } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) { - rset_clear(allow, irp->r); emit_mr(as, r, irp->r); /* Move from coalesced parent reg. */ + return irp->r; } else { emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */ } } - return allow; + return RID_NONE; } /* -- Tail of trace ------------------------------------------------------- */ diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 2bf9d939..368811fd 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h @@ -2877,7 +2877,7 @@ static void asm_head_root_base(ASMState *as) } /* Coalesce or reload BASE register for a side trace. */ -static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) +static Reg asm_head_side_base(ASMState *as, IRIns *irp) { IRIns *ir = IR(REF_BASE); Reg r = ir->r; @@ -2886,16 +2886,16 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (rset_test(as->modset, r) || irt_ismarked(ir->t)) ir->r = RID_INIT; /* No inheritance for modified BASE register. */ if (irp->r == r) { - rset_clear(allow, r); /* Mark same BASE register as coalesced. */ + return r; /* Same BASE register already coalesced. */ } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) { /* Move from coalesced parent reg. */ - rset_clear(allow, irp->r); emit_rr(as, XO_MOV, r|REX_GC64, irp->r); + return irp->r; } else { emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */ } } - return allow; + return RID_NONE; } /* -- Tail of trace ------------------------------------------------------- */