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 | } |
