diff options
Diffstat (limited to 'src/lj_asm_x86.h')
-rw-r--r-- | src/lj_asm_x86.h | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 7d07336a..26705e2c 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -422,11 +422,24 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) | |||
422 | lua_assert(allow != RSET_EMPTY); | 422 | lua_assert(allow != RSET_EMPTY); |
423 | if (!(avail & (avail-1))) /* Fuse if less than two regs available. */ | 423 | if (!(avail & (avail-1))) /* Fuse if less than two regs available. */ |
424 | return asm_fuseloadk64(as, ir); | 424 | return asm_fuseloadk64(as, ir); |
425 | } else if (ir->o == IR_KINT64) { | 425 | } else if (ref == REF_BASE || ir->o == IR_KINT64) { |
426 | RegSet avail = as->freeset & ~as->modset & RSET_GPR; | 426 | RegSet avail = as->freeset & ~as->modset & RSET_GPR; |
427 | lua_assert(allow != RSET_EMPTY); | 427 | lua_assert(allow != RSET_EMPTY); |
428 | if (!(avail & (avail-1))) /* Fuse if less than two regs available. */ | 428 | if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */ |
429 | return asm_fuseloadk64(as, ir); | 429 | if (ref == REF_BASE) { |
430 | #if LJ_GC64 | ||
431 | as->mrm.ofs = (int32_t)dispofs(as, &J2G(as->J)->jit_base); | ||
432 | as->mrm.base = RID_DISPATCH; | ||
433 | #else | ||
434 | as->mrm.ofs = ptr2addr(&J2G(as->J)->jit_base); | ||
435 | as->mrm.base = RID_NONE; | ||
436 | #endif | ||
437 | as->mrm.idx = RID_NONE; | ||
438 | return RID_MRM; | ||
439 | } else { | ||
440 | return asm_fuseloadk64(as, ir); | ||
441 | } | ||
442 | } | ||
430 | } else if (mayfuse(as, ref)) { | 443 | } else if (mayfuse(as, ref)) { |
431 | RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR; | 444 | RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR; |
432 | if (ir->o == IR_SLOAD) { | 445 | if (ir->o == IR_SLOAD) { |
@@ -470,7 +483,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) | |||
470 | asm_fusefref(as, ir, RSET_EMPTY); | 483 | asm_fusefref(as, ir, RSET_EMPTY); |
471 | return RID_MRM; | 484 | return RID_MRM; |
472 | } | 485 | } |
473 | if (!(as->freeset & allow) && !irref_isk(ref) && | 486 | if (!(as->freeset & allow) && !emit_canremat(ref) && |
474 | (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) | 487 | (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) |
475 | goto fusespill; | 488 | goto fusespill; |
476 | return ra_allocref(as, ref, allow); | 489 | return ra_allocref(as, ref, allow); |