Allow mcode allocations outside of the jump range to the support code.
Thank you for your patience. #285
This commit is contained in:
@@ -48,23 +48,38 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
|
||||
static void asm_exitstub_setup(ASMState *as, ExitNo nexits)
|
||||
{
|
||||
ExitNo i;
|
||||
int ind;
|
||||
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler;
|
||||
MCode *mxp = as->mctop;
|
||||
if (mxp - (nexits + 3 + MCLIM_REDZONE) < as->mclim)
|
||||
if (mxp - (nexits + 4 + MCLIM_REDZONE) < as->mclim)
|
||||
asm_mclimit(as);
|
||||
/* 1: mflr r0; bl ->vm_exit_handler; li r0, traceno; bl <1; bl <1; ... */
|
||||
ind = ((target - (uintptr_t)(mxp - nexits - 2) + 0x02000000u) >> 26) ? 2 : 0;
|
||||
/* !ind: 1: mflr r0; bl ->vm_exit_handler; li r0, traceno;
|
||||
** ind: 1: lwz r0, K32_VXH(jgl); mtctr r0; mflr r0; bctrl; li r0, traceno;
|
||||
** bl <1; bl <1; ...
|
||||
*/
|
||||
for (i = nexits-1; (int32_t)i >= 0; i--)
|
||||
*--mxp = PPCI_BL|(((-3-i)&0x00ffffffu)<<2);
|
||||
*--mxp = PPCI_BL | (((-3-ind-i) & 0x00ffffffu) << 2);
|
||||
as->mcexit = mxp;
|
||||
*--mxp = PPCI_LI|PPCF_T(RID_TMP)|as->T->traceno; /* Read by exit handler. */
|
||||
mxp--;
|
||||
*mxp = PPCI_BL|((((MCode *)(void *)lj_vm_exit_handler-mxp)&0x00ffffffu)<<2);
|
||||
*--mxp = PPCI_MFLR|PPCF_T(RID_TMP);
|
||||
if (ind) {
|
||||
*--mxp = PPCI_BCTRL;
|
||||
*--mxp = PPCI_MFLR | PPCF_T(RID_TMP);
|
||||
*--mxp = PPCI_MTCTR | PPCF_T(RID_TMP);
|
||||
*--mxp = PPCI_LWZ | PPCF_T(RID_TMP) | PPCF_A(RID_JGL) |
|
||||
jglofs(as, &as->J->k32[LJ_K32_VM_EXIT_HANDLER]);
|
||||
} else {
|
||||
mxp--;
|
||||
*mxp = PPCI_BL | ((target - (uintptr_t)mxp) & 0x03fffffcu);
|
||||
*--mxp = PPCI_MFLR | PPCF_T(RID_TMP);
|
||||
}
|
||||
as->mctop = mxp;
|
||||
}
|
||||
|
||||
static MCode *asm_exitstub_addr(ASMState *as, ExitNo exitno)
|
||||
{
|
||||
/* Keep this in-sync with exitstub_trace_addr(). */
|
||||
return as->mctop + exitno + 3;
|
||||
return as->mcexit + exitno;
|
||||
}
|
||||
|
||||
/* Emit conditional branch to exit for guard. */
|
||||
@@ -2218,34 +2233,43 @@ static Reg asm_head_side_base(ASMState *as, IRIns *irp)
|
||||
/* Fixup the tail code. */
|
||||
static void asm_tail_fixup(ASMState *as, TraceNo lnk)
|
||||
{
|
||||
MCode *p = as->mctop;
|
||||
MCode *target;
|
||||
uintptr_t target = lnk ? (uintptr_t)traceref(as->J, lnk)->mcode : (uintptr_t)(void *)lj_vm_exit_interp;
|
||||
MCode *mcp = as->mctail;
|
||||
int32_t spadj = as->T->spadjust;
|
||||
if (spadj == 0) {
|
||||
*--p = PPCI_NOP;
|
||||
*--p = PPCI_NOP;
|
||||
as->mctop = p;
|
||||
} else {
|
||||
/* Patch stack adjustment. */
|
||||
if (spadj) { /* Emit stack adjustment. */
|
||||
lj_assertA(checki16(CFRAME_SIZE+spadj), "stack adjustment out of range");
|
||||
p[-3] = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
|
||||
p[-2] = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
|
||||
*mcp++ = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
|
||||
*mcp++ = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
|
||||
}
|
||||
/* Patch exit branch. */
|
||||
target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
|
||||
p[-1] = PPCI_B|(((target-p+1)&0x00ffffffu)<<2);
|
||||
/* Emit exit branch. */
|
||||
if ((((target - (uintptr_t)mcp) + 0x02000000u) >> 26) == 0) {
|
||||
*mcp = PPCI_B | ((target - (uintptr_t)mcp) & 0x03fffffcu); mcp++;
|
||||
} else {
|
||||
*mcp++ = PPCI_LWZ | PPCF_T(RID_TMP) | PPCF_A(RID_JGL) |
|
||||
jglofs(as, &as->J->k32[LJ_K32_VM_EXIT_INTERP]);
|
||||
*mcp++ = PPCI_MTCTR | PPCF_T(RID_TMP);
|
||||
*mcp++ = PPCI_BCTR;
|
||||
}
|
||||
while (as->mctop > mcp) *--as->mctop = PPCI_NOP;
|
||||
}
|
||||
|
||||
/* Prepare tail of code. */
|
||||
static void asm_tail_prep(ASMState *as)
|
||||
static void asm_tail_prep(ASMState *as, TraceNo lnk)
|
||||
{
|
||||
MCode *p = as->mctop - 1; /* Leave room for exit branch. */
|
||||
if (as->loopref) {
|
||||
as->invmcp = as->mcp = p;
|
||||
} else {
|
||||
as->mcp = p-2; /* Leave room for stack pointer adjustment. */
|
||||
if (!lnk) {
|
||||
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_interp;
|
||||
if ((((target - (uintptr_t)p) + 0x02000000u) >> 26) ||
|
||||
(((target - (uintptr_t)(p-2)) + 0x02000000u) >> 26)) p -= 2;
|
||||
}
|
||||
p -= 2; /* Leave room for stack pointer adjustment. */
|
||||
as->mcp = p;
|
||||
as->invmcp = NULL;
|
||||
}
|
||||
as->mctail = p;
|
||||
}
|
||||
|
||||
/* -- Trace setup --------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user