aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-03-03 04:26:31 +0100
committerMike Pall <mike>2010-03-03 04:26:31 +0100
commit15c3bd7725e97e450f4cb5be7888bbea2133f90d (patch)
treee1613de35d03a34241fa9d296e120f1f13577fda /src
parent5fdb6e2e2035fe811821a7fb998ab810b21bba21 (diff)
downloadluajit-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.c45
-rw-r--r--src/lj_tab.c2
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 */
387static 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 */
386static void emit_loadn(ASMState *as, Reg r, cTValue *tv) 399static 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
1755static void asm_newref(ASMState *as, IRIns *ir) 1794static 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. */