mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
MIPS64: Fix register allocation in assembly of HREF.
Contributed by James Cowgill.
This commit is contained in:
parent
06cd9fce7d
commit
99cdfbf6a1
@ -859,6 +859,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
Reg dest = ra_dest(as, ir, allow);
|
Reg dest = ra_dest(as, ir, allow);
|
||||||
Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
|
Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
|
||||||
Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2;
|
Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2;
|
||||||
|
#if LJ_64
|
||||||
|
Reg cmp64 = RID_NONE;
|
||||||
|
#endif
|
||||||
IRRef refkey = ir->op2;
|
IRRef refkey = ir->op2;
|
||||||
IRIns *irkey = IR(refkey);
|
IRIns *irkey = IR(refkey);
|
||||||
int isk = irref_isk(refkey);
|
int isk = irref_isk(refkey);
|
||||||
@ -901,6 +904,26 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
#endif
|
#endif
|
||||||
tmp2 = ra_scratch(as, allow);
|
tmp2 = ra_scratch(as, allow);
|
||||||
rset_clear(allow, tmp2);
|
rset_clear(allow, tmp2);
|
||||||
|
#if LJ_64
|
||||||
|
if (LJ_SOFTFP || !irt_isnum(kt)) {
|
||||||
|
/* Allocate cmp64 register used for 64-bit comparisons */
|
||||||
|
if (LJ_SOFTFP && irt_isnum(kt)) {
|
||||||
|
cmp64 = key;
|
||||||
|
} else if (!isk && irt_isaddr(kt)) {
|
||||||
|
cmp64 = tmp2;
|
||||||
|
} else {
|
||||||
|
int64_t k;
|
||||||
|
if (isk && irt_isaddr(kt)) {
|
||||||
|
k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
|
||||||
|
} else {
|
||||||
|
lua_assert(irt_ispri(kt) && !irt_isnil(kt));
|
||||||
|
k = ~((int64_t)~irt_toitype(ir->t) << 47);
|
||||||
|
}
|
||||||
|
cmp64 = ra_allock(as, k, allow);
|
||||||
|
rset_clear(allow, cmp64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Key not found in chain: jump to exit (if merged) or load niltv. */
|
/* Key not found in chain: jump to exit (if merged) or load niltv. */
|
||||||
l_end = emit_label(as);
|
l_end = emit_label(as);
|
||||||
@ -943,24 +966,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);
|
emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);
|
||||||
emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);
|
emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);
|
||||||
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
||||||
} else if (LJ_SOFTFP && irt_isnum(kt)) {
|
|
||||||
emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);
|
|
||||||
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
|
||||||
} else if (irt_isaddr(kt)) {
|
|
||||||
Reg refk = tmp2;
|
|
||||||
if (isk) {
|
|
||||||
int64_t k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
|
|
||||||
refk = ra_allock(as, k, allow);
|
|
||||||
rset_clear(allow, refk);
|
|
||||||
}
|
|
||||||
emit_branch(as, MIPSI_BEQ, tmp1, refk, l_end);
|
|
||||||
emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
|
|
||||||
} else {
|
} else {
|
||||||
Reg pri = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow);
|
emit_branch(as, MIPSI_BEQ, tmp1, cmp64, l_end);
|
||||||
rset_clear(allow, pri);
|
emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
|
||||||
lua_assert(irt_ispri(kt) && !irt_isnil(kt));
|
|
||||||
emit_branch(as, MIPSI_BEQ, tmp1, pri, l_end);
|
|
||||||
emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
|
|
||||||
}
|
}
|
||||||
*l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu);
|
*l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu);
|
||||||
if (!isk && irt_isaddr(kt)) {
|
if (!isk && irt_isaddr(kt)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user