From 91592899275cbb540ca67bbf95b41a2200e4fdbd Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Thu, 21 Sep 2023 02:48:12 +0200 Subject: [PATCH] ARM64: Fix IR_HREF code generation for constant FP keys. Reported by swarn. Fix for 435d8c63 by Peter Cawley. #1090 --- src/lj_asm_arm64.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index 8673f7df..82f14405 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h @@ -787,7 +787,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) int destused = ra_used(ir); Reg dest = ra_dest(as, ir, allow); 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; IRIns *irkey = IR(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; rset_clear(allow, tab); - /* Allocate registers outside of the loop. */ - if (irkey->o != IR_KNUM || !(k = emit_isk12((int64_t)ir_knum(irkey)->u64))) { - 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 { + /* Allocate register for tkey outside of the loop. */ + if (isk) { int64_t kk; if (irt_isaddr(kt)) { 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 { lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type"); kk = ~((int64_t)~irt_toitype(kt) << 47); } - tkey = ra_allock(as, kk, allow); - rset_clear(allow, tkey); + k = emit_isk12(kk); + 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. */ @@ -849,10 +845,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) /* Construct tkey as canonicalized or tagged key. */ if (!isk) { if (irt_isnum(kt)) { + key = ra_alloc1(as, refkey, RSET_FPR); emit_dnm(as, A64I_CSELx | A64F_CC(CC_EQ), tkey, RID_ZERO, tkey); + /* A64I_FMOV_R_D from key to tkey done below. */ } else { 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); } }