diff options
author | Mike Pall <mike> | 2023-09-21 02:48:12 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-09-21 02:48:12 +0200 |
commit | 91592899275cbb540ca67bbf95b41a2200e4fdbd (patch) | |
tree | 167610408018484e79f25102e2c6ab100c57ab54 /src | |
parent | fca1f51bf8209a41f8d7cd13ff09f113ac0d87b6 (diff) | |
download | luajit-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.h | 29 |
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 | } |