aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2023-09-21 02:48:12 +0200
committerMike Pall <mike>2023-09-21 02:48:12 +0200
commit91592899275cbb540ca67bbf95b41a2200e4fdbd (patch)
tree167610408018484e79f25102e2c6ab100c57ab54 /src
parentfca1f51bf8209a41f8d7cd13ff09f113ac0d87b6 (diff)
downloadluajit-91592899275cbb540ca67bbf95b41a2200e4fdbd.tar.gz
luajit-91592899275cbb540ca67bbf95b41a2200e4fdbd.tar.bz2
luajit-91592899275cbb540ca67bbf95b41a2200e4fdbd.zip
ARM64: Fix IR_HREF code generation for constant FP keys.
Reported by swarn. Fix for 435d8c63 by Peter Cawley. #1090
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm_arm64.h29
1 files 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)
787 int destused = ra_used(ir); 787 int destused = ra_used(ir);
788 Reg dest = ra_dest(as, ir, allow); 788 Reg dest = ra_dest(as, ir, allow);
789 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest)); 789 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
790 Reg key = 0, tmp = RID_TMP, type = RID_NONE, tkey; 790 Reg tmp = RID_TMP, type = RID_NONE, key, tkey;
791 IRRef refkey = ir->op2; 791 IRRef refkey = ir->op2;
792 IRIns *irkey = IR(refkey); 792 IRIns *irkey = IR(refkey);
793 int isk = irref_isk(refkey); 793 int isk = irref_isk(refkey);
@@ -797,26 +797,22 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
797 MCLabel l_end, l_loop; 797 MCLabel l_end, l_loop;
798 rset_clear(allow, tab); 798 rset_clear(allow, tab);
799 799
800 /* Allocate registers outside of the loop. */ 800 /* Allocate register for tkey outside of the loop. */
801 if (irkey->o != IR_KNUM || !(k = emit_isk12((int64_t)ir_knum(irkey)->u64))) { 801 if (isk) {
802 key = ra_alloc1(as, refkey, irt_isnum(kt) ? RSET_FPR : allow);
803 rset_clear(allow, key);
804 }
805 if (!isk) {
806 tkey = ra_scratch(as, allow);
807 rset_clear(allow, tkey);
808 } else if (irt_isnum(kt)) {
809 tkey = key; /* Assumes -0.0 is already canonicalized to +0.0. */
810 } else {
811 int64_t kk; 802 int64_t kk;
812 if (irt_isaddr(kt)) { 803 if (irt_isaddr(kt)) {
813 kk = ((int64_t)irt_toitype(kt) << 47) | irkey[1].tv.u64; 804 kk = ((int64_t)irt_toitype(kt) << 47) | irkey[1].tv.u64;
805 } else if (irt_isnum(kt)) {
806 kk = (int64_t)ir_knum(irkey)->u64;
807 /* Assumes -0.0 is already canonicalized to +0.0. */
814 } else { 808 } else {
815 lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type"); 809 lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
816 kk = ~((int64_t)~irt_toitype(kt) << 47); 810 kk = ~((int64_t)~irt_toitype(kt) << 47);
817 } 811 }
818 tkey = ra_allock(as, kk, allow); 812 k = emit_isk12(kk);
819 rset_clear(allow, tkey); 813 tkey = k ? 0 : ra_allock(as, kk, allow);
814 } else {
815 tkey = ra_scratch(as, allow);
820 } 816 }
821 817
822 /* Key not found in chain: jump to exit (if merged) or load niltv. */ 818 /* 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)
849 /* Construct tkey as canonicalized or tagged key. */ 845 /* Construct tkey as canonicalized or tagged key. */
850 if (!isk) { 846 if (!isk) {
851 if (irt_isnum(kt)) { 847 if (irt_isnum(kt)) {
848 key = ra_alloc1(as, refkey, RSET_FPR);
852 emit_dnm(as, A64I_CSELx | A64F_CC(CC_EQ), tkey, RID_ZERO, tkey); 849 emit_dnm(as, A64I_CSELx | A64F_CC(CC_EQ), tkey, RID_ZERO, tkey);
850 /* A64I_FMOV_R_D from key to tkey done below. */
853 } else { 851 } else {
854 lj_assertA(irt_isaddr(kt), "bad HREF key type"); 852 lj_assertA(irt_isaddr(kt), "bad HREF key type");
855 type = ra_allock(as, irt_toitype(kt) << 15, allow); 853 key = ra_alloc1(as, refkey, allow);
854 type = ra_allock(as, irt_toitype(kt) << 15, rset_clear(allow, key));
856 emit_dnm(as, A64I_ADDx | A64F_SH(A64SH_LSL, 32), tkey, key, type); 855 emit_dnm(as, A64I_ADDx | A64F_SH(A64SH_LSL, 32), tkey, key, type);
857 } 856 }
858 } 857 }