mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
ARM64: Fix IR_HREF code generation for constant FP keys.
Reported by swarn. Fix for 435d8c63
by Peter Cawley. #1090
This commit is contained in:
parent
fca1f51bf8
commit
9159289927
@ -787,7 +787,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
int destused = ra_used(ir);
|
int destused = ra_used(ir);
|
||||||
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 = 0, tmp = RID_TMP, type = RID_NONE, tkey;
|
Reg tmp = RID_TMP, type = RID_NONE, key, tkey;
|
||||||
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);
|
||||||
@ -797,26 +797,22 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
MCLabel l_end, l_loop;
|
MCLabel l_end, l_loop;
|
||||||
rset_clear(allow, tab);
|
rset_clear(allow, tab);
|
||||||
|
|
||||||
/* Allocate registers outside of the loop. */
|
/* Allocate register for tkey outside of the loop. */
|
||||||
if (irkey->o != IR_KNUM || !(k = emit_isk12((int64_t)ir_knum(irkey)->u64))) {
|
if (isk) {
|
||||||
key = ra_alloc1(as, refkey, irt_isnum(kt) ? RSET_FPR : allow);
|
|
||||||
rset_clear(allow, key);
|
|
||||||
}
|
|
||||||
if (!isk) {
|
|
||||||
tkey = ra_scratch(as, allow);
|
|
||||||
rset_clear(allow, tkey);
|
|
||||||
} else if (irt_isnum(kt)) {
|
|
||||||
tkey = key; /* Assumes -0.0 is already canonicalized to +0.0. */
|
|
||||||
} else {
|
|
||||||
int64_t kk;
|
int64_t kk;
|
||||||
if (irt_isaddr(kt)) {
|
if (irt_isaddr(kt)) {
|
||||||
kk = ((int64_t)irt_toitype(kt) << 47) | irkey[1].tv.u64;
|
kk = ((int64_t)irt_toitype(kt) << 47) | irkey[1].tv.u64;
|
||||||
|
} else if (irt_isnum(kt)) {
|
||||||
|
kk = (int64_t)ir_knum(irkey)->u64;
|
||||||
|
/* Assumes -0.0 is already canonicalized to +0.0. */
|
||||||
} else {
|
} else {
|
||||||
lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
|
lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
|
||||||
kk = ~((int64_t)~irt_toitype(kt) << 47);
|
kk = ~((int64_t)~irt_toitype(kt) << 47);
|
||||||
}
|
}
|
||||||
tkey = ra_allock(as, kk, allow);
|
k = emit_isk12(kk);
|
||||||
rset_clear(allow, tkey);
|
tkey = k ? 0 : ra_allock(as, kk, allow);
|
||||||
|
} else {
|
||||||
|
tkey = ra_scratch(as, allow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
@ -849,10 +845,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
|||||||
/* Construct tkey as canonicalized or tagged key. */
|
/* Construct tkey as canonicalized or tagged key. */
|
||||||
if (!isk) {
|
if (!isk) {
|
||||||
if (irt_isnum(kt)) {
|
if (irt_isnum(kt)) {
|
||||||
|
key = ra_alloc1(as, refkey, RSET_FPR);
|
||||||
emit_dnm(as, A64I_CSELx | A64F_CC(CC_EQ), tkey, RID_ZERO, tkey);
|
emit_dnm(as, A64I_CSELx | A64F_CC(CC_EQ), tkey, RID_ZERO, tkey);
|
||||||
|
/* A64I_FMOV_R_D from key to tkey done below. */
|
||||||
} else {
|
} else {
|
||||||
lj_assertA(irt_isaddr(kt), "bad HREF key type");
|
lj_assertA(irt_isaddr(kt), "bad HREF key type");
|
||||||
type = ra_allock(as, irt_toitype(kt) << 15, allow);
|
key = ra_alloc1(as, refkey, allow);
|
||||||
|
type = ra_allock(as, irt_toitype(kt) << 15, rset_clear(allow, key));
|
||||||
emit_dnm(as, A64I_ADDx | A64F_SH(A64SH_LSL, 32), tkey, key, type);
|
emit_dnm(as, A64I_ADDx | A64F_SH(A64SH_LSL, 32), tkey, key, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user