aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-10-11 18:03:25 +0200
committerMike Pall <mike>2010-10-11 19:24:12 +0200
commitcc62edebfdf3fa451a745ee2936c8df72c9e7243 (patch)
tree3a30dd96e46a8c7706308941ce7efc238e90624b /src
parent5140b40b44e8ff665f8e63293500f6dcc3c43bc7 (diff)
downloadluajit-cc62edebfdf3fa451a745ee2936c8df72c9e7243.tar.gz
luajit-cc62edebfdf3fa451a745ee2936c8df72c9e7243.tar.bz2
luajit-cc62edebfdf3fa451a745ee2936c8df72c9e7243.zip
x64: Fix type check for numbers in compiled code.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 89b569cc..563abcd4 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -130,6 +130,7 @@ static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as)
130 130
131#define emit_i8(as, i) (*--as->mcp = (MCode)(i)) 131#define emit_i8(as, i) (*--as->mcp = (MCode)(i))
132#define emit_i32(as, i) (*(int32_t *)(as->mcp-4) = (i), as->mcp -= 4) 132#define emit_i32(as, i) (*(int32_t *)(as->mcp-4) = (i), as->mcp -= 4)
133#define emit_u32(as, u) (*(uint32_t *)(as->mcp-4) = (u), as->mcp -= 4)
133 134
134#define emit_x87op(as, xo) \ 135#define emit_x87op(as, xo) \
135 (*(uint16_t *)(as->mcp-2) = (uint16_t)(xo), as->mcp -= 2) 136 (*(uint16_t *)(as->mcp-2) = (uint16_t)(xo), as->mcp -= 2)
@@ -1683,8 +1684,13 @@ static void asm_href(ASMState *as, IRIns *ir)
1683 emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n)); 1684 emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n));
1684 emit_sjcc(as, CC_A, l_next); 1685 emit_sjcc(as, CC_A, l_next);
1685 /* The type check avoids NaN penalties and complaints from Valgrind. */ 1686 /* The type check avoids NaN penalties and complaints from Valgrind. */
1687#if LJ_64
1688 emit_u32(as, LJ_TISNUM);
1689 emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it));
1690#else
1686 emit_i8(as, ~IRT_NUM); 1691 emit_i8(as, ~IRT_NUM);
1687 emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it)); 1692 emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it));
1693#endif
1688 } 1694 }
1689#if LJ_64 1695#if LJ_64
1690 } else if (irt_islightud(kt)) { 1696 } else if (irt_islightud(kt)) {
@@ -2004,10 +2010,15 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
2004 asm_fuseahuref(as, ir->op1, RSET_GPR); 2010 asm_fuseahuref(as, ir->op1, RSET_GPR);
2005 } 2011 }
2006 /* Always do the type check, even if the load result is unused. */ 2012 /* Always do the type check, even if the load result is unused. */
2007 asm_guardcc(as, irt_isnum(ir->t) ? CC_A : CC_NE);
2008 emit_i8(as, ~irt_type(ir->t));
2009 as->mrm.ofs += 4; 2013 as->mrm.ofs += 4;
2010 emit_mrm(as, XO_ARITHi8, XOg_CMP, RID_MRM); 2014 asm_guardcc(as, irt_isnum(ir->t) ? CC_A : CC_NE);
2015 if (LJ_64 && irt_isnum(ir->t)) {
2016 emit_u32(as, LJ_TISNUM);
2017 emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM);
2018 } else {
2019 emit_i8(as, ~irt_type(ir->t));
2020 emit_mrm(as, XO_ARITHi8, XOg_CMP, RID_MRM);
2021 }
2011} 2022}
2012 2023
2013static void asm_ahustore(ASMState *as, IRIns *ir) 2024static void asm_ahustore(ASMState *as, IRIns *ir)
@@ -2085,8 +2096,13 @@ static void asm_sload(ASMState *as, IRIns *ir)
2085 if ((ir->op2 & IRSLOAD_TYPECHECK)) { 2096 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
2086 /* Need type check, even if the load result is unused. */ 2097 /* Need type check, even if the load result is unused. */
2087 asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE); 2098 asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE);
2088 emit_i8(as, ~irt_type(t)); 2099 if (LJ_64 && irt_isnum(t)) {
2089 emit_rmro(as, XO_ARITHi8, XOg_CMP, base, ofs+4); 2100 emit_u32(as, LJ_TISNUM);
2101 emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4);
2102 } else {
2103 emit_i8(as, ~irt_type(t));
2104 emit_rmro(as, XO_ARITHi8, XOg_CMP, base, ofs+4);
2105 }
2090 } 2106 }
2091} 2107}
2092 2108