aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-09-27 14:16:18 +0200
committerMike Pall <mike>2012-09-27 14:16:18 +0200
commit0ecdff43e80dcd1d489c3daca0077dbfae9042b6 (patch)
treee5b58de741d0d23ee3296ae08e2a1d86eeb13c6e /src
parentcfca926cc2e2b63e94492f0a1f5c033f6db3a6f5 (diff)
downloadluajit-0ecdff43e80dcd1d489c3daca0077dbfae9042b6.tar.gz
luajit-0ecdff43e80dcd1d489c3daca0077dbfae9042b6.tar.bz2
luajit-0ecdff43e80dcd1d489c3daca0077dbfae9042b6.zip
x86: Fix register allocation for calls returning register pair.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c6
-rw-r--r--src/lj_asm_x86.h8
-rw-r--r--src/lj_target_x86.h1
3 files changed, 12 insertions, 3 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 79097759..6afc70a0 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -719,7 +719,7 @@ static void ra_leftov(ASMState *as, Reg dest, IRRef lref)
719} 719}
720#endif 720#endif
721 721
722#if !LJ_TARGET_X86ORX64 722#if !LJ_64
723/* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */ 723/* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
724static void ra_destpair(ASMState *as, IRIns *ir) 724static void ra_destpair(ASMState *as, IRIns *ir)
725{ 725{
@@ -747,9 +747,13 @@ static void ra_destpair(ASMState *as, IRIns *ir)
747 /* Check for conflicts and shuffle the registers as needed. */ 747 /* Check for conflicts and shuffle the registers as needed. */
748 if (destlo == RID_RETHI) { 748 if (destlo == RID_RETHI) {
749 if (desthi == RID_RETLO) { 749 if (desthi == RID_RETLO) {
750#if LJ_TARGET_X86
751 *--as->mcp = XI_XCHGa + RID_RETHI;
752#else
750 emit_movrr(as, ir, RID_RETHI, RID_TMP); 753 emit_movrr(as, ir, RID_RETHI, RID_TMP);
751 emit_movrr(as, ir, RID_RETLO, RID_RETHI); 754 emit_movrr(as, ir, RID_RETLO, RID_RETHI);
752 emit_movrr(as, ir, RID_TMP, RID_RETLO); 755 emit_movrr(as, ir, RID_TMP, RID_RETLO);
756#endif
753 } else { 757 } else {
754 emit_movrr(as, ir, RID_RETHI, RID_RETLO); 758 emit_movrr(as, ir, RID_RETHI, RID_RETLO);
755 if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI); 759 if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index da4cf7e2..7288d72a 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -510,10 +510,13 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
510static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) 510static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
511{ 511{
512 RegSet drop = RSET_SCRATCH; 512 RegSet drop = RSET_SCRATCH;
513 int hiop = (LJ_32 && (ir+1)->o == IR_HIOP);
513 if ((ci->flags & CCI_NOFPRCLOBBER)) 514 if ((ci->flags & CCI_NOFPRCLOBBER))
514 drop &= ~RSET_FPR; 515 drop &= ~RSET_FPR;
515 if (ra_hasreg(ir->r)) 516 if (ra_hasreg(ir->r))
516 rset_clear(drop, ir->r); /* Dest reg handled below. */ 517 rset_clear(drop, ir->r); /* Dest reg handled below. */
518 if (hiop && ra_hasreg((ir+1)->r))
519 rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */
517 ra_evictset(as, drop); /* Evictions must be performed first. */ 520 ra_evictset(as, drop); /* Evictions must be performed first. */
518 if (ra_used(ir)) { 521 if (ra_used(ir)) {
519 if (irt_isfp(ir->t)) { 522 if (irt_isfp(ir->t)) {
@@ -547,6 +550,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
547 irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs); 550 irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
548 } 551 }
549#endif 552#endif
553 } else if (hiop) {
554 ra_destpair(as, ir);
550 } else { 555 } else {
551 lua_assert(!irt_ispri(ir->t)); 556 lua_assert(!irt_ispri(ir->t));
552 ra_destreg(as, ir, RID_RET); 557 ra_destreg(as, ir, RID_RET);
@@ -2288,9 +2293,8 @@ static void asm_hiop(ASMState *as, IRIns *ir)
2288 } 2293 }
2289 case IR_CALLN: 2294 case IR_CALLN:
2290 case IR_CALLXS: 2295 case IR_CALLXS:
2291 ra_destreg(as, ir, RID_RETHI);
2292 if (!uselo) 2296 if (!uselo)
2293 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark call as used. */ 2297 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
2294 break; 2298 break;
2295 case IR_CNEWI: 2299 case IR_CNEWI:
2296 /* Nothing to do here. Handled by CNEWI itself. */ 2300 /* Nothing to do here. Handled by CNEWI itself. */
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index cc15490b..c718bdb5 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -191,6 +191,7 @@ typedef struct {
191typedef enum { 191typedef enum {
192 /* Fixed length opcodes. XI_* prefix. */ 192 /* Fixed length opcodes. XI_* prefix. */
193 XI_NOP = 0x90, 193 XI_NOP = 0x90,
194 XI_XCHGa = 0x90,
194 XI_CALL = 0xe8, 195 XI_CALL = 0xe8,
195 XI_JMP = 0xe9, 196 XI_JMP = 0xe9,
196 XI_JMPs = 0xeb, 197 XI_JMPs = 0xeb,