diff options
author | Mike Pall <mike> | 2010-03-03 04:26:31 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-03-03 04:26:31 +0100 |
commit | 15c3bd7725e97e450f4cb5be7888bbea2133f90d (patch) | |
tree | e1613de35d03a34241fa9d296e120f1f13577fda /src | |
parent | 5fdb6e2e2035fe811821a7fb998ab810b21bba21 (diff) | |
download | luajit-15c3bd7725e97e450f4cb5be7888bbea2133f90d.tar.gz luajit-15c3bd7725e97e450f4cb5be7888bbea2133f90d.tar.bz2 luajit-15c3bd7725e97e450f4cb5be7888bbea2133f90d.zip |
Improve performance of HREF/HREFK on x64.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 45 | ||||
-rw-r--r-- | src/lj_tab.c | 2 |
2 files changed, 43 insertions, 4 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 14d7dbd4..9f33cfd9 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -382,6 +382,19 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) | |||
382 | #define emit_loada(as, r, addr) \ | 382 | #define emit_loada(as, r, addr) \ |
383 | emit_loadi(as, (r), ptr2addr((addr))) | 383 | emit_loadi(as, (r), ptr2addr((addr))) |
384 | 384 | ||
385 | #if LJ_64 | ||
386 | /* mov r, imm64 */ | ||
387 | static void emit_loadu64(ASMState *as, Reg r, uint64_t i) | ||
388 | { | ||
389 | MCode *p = as->mcp; | ||
390 | *(uint64_t *)(p-8) = i; | ||
391 | p[-9] = (MCode)(XI_MOVri+(r&7)); | ||
392 | p[-10] = 0x48 + ((r>>3)&1); | ||
393 | p -= 10; | ||
394 | as->mcp = p; | ||
395 | } | ||
396 | #endif | ||
397 | |||
385 | /* movsd r, [&tv->n] / xorps r, r */ | 398 | /* movsd r, [&tv->n] / xorps r, r */ |
386 | static void emit_loadn(ASMState *as, Reg r, cTValue *tv) | 399 | static void emit_loadn(ASMState *as, Reg r, cTValue *tv) |
387 | { | 400 | { |
@@ -1558,7 +1571,7 @@ static uint32_t ir_khash(IRIns *ir) | |||
1558 | return ir_kstr(ir)->hash; | 1571 | return ir_kstr(ir)->hash; |
1559 | } else if (irt_isnum(ir->t)) { | 1572 | } else if (irt_isnum(ir->t)) { |
1560 | lo = ir_knum(ir)->u32.lo; | 1573 | lo = ir_knum(ir)->u32.lo; |
1561 | hi = ir_knum(ir)->u32.hi & 0x7fffffff; | 1574 | hi = ir_knum(ir)->u32.hi << 1; |
1562 | } else if (irt_ispri(ir->t)) { | 1575 | } else if (irt_ispri(ir->t)) { |
1563 | lua_assert(!irt_isnil(ir->t)); | 1576 | lua_assert(!irt_isnil(ir->t)); |
1564 | return irt_type(ir->t)-IRT_FALSE; | 1577 | return irt_type(ir->t)-IRT_FALSE; |
@@ -1696,9 +1709,15 @@ static void asm_href(ASMState *as, IRIns *ir) | |||
1696 | emit_shifti(as, XOg_ROL, dest, 14); | 1709 | emit_shifti(as, XOg_ROL, dest, 14); |
1697 | emit_rr(as, XO_ARITH(XOg_XOR), tmp, dest); | 1710 | emit_rr(as, XO_ARITH(XOg_XOR), tmp, dest); |
1698 | if (irt_isnum(kt)) { | 1711 | if (irt_isnum(kt)) { |
1699 | emit_rmro(as, XO_ARITH(XOg_AND), dest, RID_ESP, ra_spill(as, irkey)+4); | 1712 | emit_rr(as, XO_ARITH(XOg_ADD), dest, dest); |
1700 | emit_loadi(as, dest, 0x7fffffff); | 1713 | #if LJ_64 |
1714 | emit_shifti(as, XOg_SHR|REX_64, dest, 32); | ||
1715 | emit_rr(as, XO_MOV, tmp, dest); | ||
1716 | emit_rr(as, XO_MOVDto, key|REX_64, dest); | ||
1717 | #else | ||
1718 | emit_rmro(as, XO_MOV, dest, RID_ESP, ra_spill(as, irkey)+4); | ||
1701 | emit_rr(as, XO_MOVDto, key, tmp); | 1719 | emit_rr(as, XO_MOVDto, key, tmp); |
1720 | #endif | ||
1702 | } else { | 1721 | } else { |
1703 | emit_rr(as, XO_MOV, tmp, key); | 1722 | emit_rr(as, XO_MOV, tmp, key); |
1704 | emit_rmro(as, XO_LEA, dest, key, -0x04c11db7); | 1723 | emit_rmro(as, XO_LEA, dest, key, -0x04c11db7); |
@@ -1714,7 +1733,9 @@ static void asm_hrefk(ASMState *as, IRIns *ir) | |||
1714 | int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node)); | 1733 | int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node)); |
1715 | Reg dest = ra_used(ir) ? ra_dest(as, ir, RSET_GPR) : RID_NONE; | 1734 | Reg dest = ra_used(ir) ? ra_dest(as, ir, RSET_GPR) : RID_NONE; |
1716 | Reg node = ra_alloc1(as, ir->op1, RSET_GPR); | 1735 | Reg node = ra_alloc1(as, ir->op1, RSET_GPR); |
1736 | #if !LJ_64 | ||
1717 | MCLabel l_exit; | 1737 | MCLabel l_exit; |
1738 | #endif | ||
1718 | lua_assert(ofs % sizeof(Node) == 0); | 1739 | lua_assert(ofs % sizeof(Node) == 0); |
1719 | if (ra_hasreg(dest)) { | 1740 | if (ra_hasreg(dest)) { |
1720 | if (ofs != 0) { | 1741 | if (ofs != 0) { |
@@ -1727,6 +1748,23 @@ static void asm_hrefk(ASMState *as, IRIns *ir) | |||
1727 | } | 1748 | } |
1728 | } | 1749 | } |
1729 | asm_guardcc(as, CC_NE); | 1750 | asm_guardcc(as, CC_NE); |
1751 | #if LJ_64 | ||
1752 | if (!irt_ispri(irkey->t)) { | ||
1753 | Reg key = ra_scratch(as, rset_exclude(RSET_GPR, node)); | ||
1754 | emit_rmro(as, XO_CMP, key|REX_64, node, | ||
1755 | ofs + (int32_t)offsetof(Node, key.u64)); | ||
1756 | lua_assert(irt_isnum(irkey->t) || irt_isgcv(irkey->t)); | ||
1757 | /* Assumes -0.0 is already canonicalized to +0.0. */ | ||
1758 | emit_loadu64(as, key, irt_isnum(irkey->t) ? ir_knum(irkey)->u64 : | ||
1759 | ((uint64_t)~irt_type(irkey->t) << 32) | | ||
1760 | (uint64_t)(uint32_t)ptr2addr(ir_kgc(irkey))); | ||
1761 | } else { | ||
1762 | lua_assert(!irt_isnil(irkey->t)); | ||
1763 | emit_i8(as, ~irt_type(irkey->t)); | ||
1764 | emit_rmro(as, XO_ARITHi8, XOg_CMP, node, | ||
1765 | ofs + (int32_t)offsetof(Node, key.it)); | ||
1766 | } | ||
1767 | #else | ||
1730 | l_exit = emit_label(as); | 1768 | l_exit = emit_label(as); |
1731 | if (irt_isnum(irkey->t)) { | 1769 | if (irt_isnum(irkey->t)) { |
1732 | /* Assumes -0.0 is already canonicalized to +0.0. */ | 1770 | /* Assumes -0.0 is already canonicalized to +0.0. */ |
@@ -1750,6 +1788,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir) | |||
1750 | emit_rmro(as, XO_ARITHi8, XOg_CMP, node, | 1788 | emit_rmro(as, XO_ARITHi8, XOg_CMP, node, |
1751 | ofs + (int32_t)offsetof(Node, key.it)); | 1789 | ofs + (int32_t)offsetof(Node, key.it)); |
1752 | } | 1790 | } |
1791 | #endif | ||
1753 | } | 1792 | } |
1754 | 1793 | ||
1755 | static void asm_newref(ASMState *as, IRIns *ir) | 1794 | static void asm_newref(ASMState *as, IRIns *ir) |
diff --git a/src/lj_tab.c b/src/lj_tab.c index 427b6118..fc44fdb4 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c | |||
@@ -22,7 +22,7 @@ | |||
22 | /* String hashes are precomputed when they are interned. */ | 22 | /* String hashes are precomputed when they are interned. */ |
23 | #define hashstr(t, s) hashmask(t, (s)->hash) | 23 | #define hashstr(t, s) hashmask(t, (s)->hash) |
24 | 24 | ||
25 | #define hashnum(t, o) hashrot(t, (o)->u32.lo, (o)->u32.hi&0x7fffffff) | 25 | #define hashnum(t, o) hashrot(t, (o)->u32.lo, ((o)->u32.hi << 1)) |
26 | #define hashgcref(t, r) hashrot(t, gcrefu(r), gcrefu(r)-0x04c11db7) | 26 | #define hashgcref(t, r) hashrot(t, gcrefu(r), gcrefu(r)-0x04c11db7) |
27 | 27 | ||
28 | /* Scramble the bits of numbers and pointers. */ | 28 | /* Scramble the bits of numbers and pointers. */ |