mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
x86: Fix register allocation for calls returning register pair.
This commit is contained in:
parent
cfca926cc2
commit
0ecdff43e8
@ -719,7 +719,7 @@ static void ra_leftov(ASMState *as, Reg dest, IRRef lref)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !LJ_TARGET_X86ORX64
|
#if !LJ_64
|
||||||
/* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
|
/* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
|
||||||
static void ra_destpair(ASMState *as, IRIns *ir)
|
static void ra_destpair(ASMState *as, IRIns *ir)
|
||||||
{
|
{
|
||||||
@ -747,9 +747,13 @@ static void ra_destpair(ASMState *as, IRIns *ir)
|
|||||||
/* Check for conflicts and shuffle the registers as needed. */
|
/* Check for conflicts and shuffle the registers as needed. */
|
||||||
if (destlo == RID_RETHI) {
|
if (destlo == RID_RETHI) {
|
||||||
if (desthi == RID_RETLO) {
|
if (desthi == RID_RETLO) {
|
||||||
|
#if LJ_TARGET_X86
|
||||||
|
*--as->mcp = XI_XCHGa + RID_RETHI;
|
||||||
|
#else
|
||||||
emit_movrr(as, ir, RID_RETHI, RID_TMP);
|
emit_movrr(as, ir, RID_RETHI, RID_TMP);
|
||||||
emit_movrr(as, ir, RID_RETLO, RID_RETHI);
|
emit_movrr(as, ir, RID_RETLO, RID_RETHI);
|
||||||
emit_movrr(as, ir, RID_TMP, RID_RETLO);
|
emit_movrr(as, ir, RID_TMP, RID_RETLO);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
emit_movrr(as, ir, RID_RETHI, RID_RETLO);
|
emit_movrr(as, ir, RID_RETHI, RID_RETLO);
|
||||||
if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
|
if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
|
||||||
|
@ -510,10 +510,13 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
|||||||
static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||||
{
|
{
|
||||||
RegSet drop = RSET_SCRATCH;
|
RegSet drop = RSET_SCRATCH;
|
||||||
|
int hiop = (LJ_32 && (ir+1)->o == IR_HIOP);
|
||||||
if ((ci->flags & CCI_NOFPRCLOBBER))
|
if ((ci->flags & CCI_NOFPRCLOBBER))
|
||||||
drop &= ~RSET_FPR;
|
drop &= ~RSET_FPR;
|
||||||
if (ra_hasreg(ir->r))
|
if (ra_hasreg(ir->r))
|
||||||
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
||||||
|
if (hiop && ra_hasreg((ir+1)->r))
|
||||||
|
rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */
|
||||||
ra_evictset(as, drop); /* Evictions must be performed first. */
|
ra_evictset(as, drop); /* Evictions must be performed first. */
|
||||||
if (ra_used(ir)) {
|
if (ra_used(ir)) {
|
||||||
if (irt_isfp(ir->t)) {
|
if (irt_isfp(ir->t)) {
|
||||||
@ -547,6 +550,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
|||||||
irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
|
irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
} else if (hiop) {
|
||||||
|
ra_destpair(as, ir);
|
||||||
} else {
|
} else {
|
||||||
lua_assert(!irt_ispri(ir->t));
|
lua_assert(!irt_ispri(ir->t));
|
||||||
ra_destreg(as, ir, RID_RET);
|
ra_destreg(as, ir, RID_RET);
|
||||||
@ -2288,9 +2293,8 @@ static void asm_hiop(ASMState *as, IRIns *ir)
|
|||||||
}
|
}
|
||||||
case IR_CALLN:
|
case IR_CALLN:
|
||||||
case IR_CALLXS:
|
case IR_CALLXS:
|
||||||
ra_destreg(as, ir, RID_RETHI);
|
|
||||||
if (!uselo)
|
if (!uselo)
|
||||||
ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark call as used. */
|
ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
|
||||||
break;
|
break;
|
||||||
case IR_CNEWI:
|
case IR_CNEWI:
|
||||||
/* Nothing to do here. Handled by CNEWI itself. */
|
/* Nothing to do here. Handled by CNEWI itself. */
|
||||||
|
@ -191,6 +191,7 @@ typedef struct {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* Fixed length opcodes. XI_* prefix. */
|
/* Fixed length opcodes. XI_* prefix. */
|
||||||
XI_NOP = 0x90,
|
XI_NOP = 0x90,
|
||||||
|
XI_XCHGa = 0x90,
|
||||||
XI_CALL = 0xe8,
|
XI_CALL = 0xe8,
|
||||||
XI_JMP = 0xe9,
|
XI_JMP = 0xe9,
|
||||||
XI_JMPs = 0xeb,
|
XI_JMPs = 0xeb,
|
||||||
|
Loading…
Reference in New Issue
Block a user