aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2023-09-09 18:01:37 +0200
committerMike Pall <mike>2023-09-09 18:01:37 +0200
commitb8c6ccd50c61b7a2df5123ddc5a85ac7d089542b (patch)
tree32767fb37df6e3a9aed971fc75de32226b78a7a7 /src
parent0705ef6ce41320b097cfb4f3c9a2a876c1949e86 (diff)
downloadluajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.tar.gz
luajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.tar.bz2
luajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.zip
ARM64: Fix LDP/STP fusion (again).
Reported and analyzed by Zhongwei Yao. Fix by Peter Cawley. #1075
Diffstat (limited to 'src')
-rw-r--r--src/lj_emit_arm64.h17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h
index d4c54255..9161c958 100644
--- a/src/lj_emit_arm64.h
+++ b/src/lj_emit_arm64.h
@@ -113,6 +113,17 @@ static int emit_checkofs(A64Ins ai, int64_t ofs)
113 } 113 }
114} 114}
115 115
116static LJ_AINLINE uint32_t emit_lso_pair_candidate(A64Ins ai, int ofs, int sc)
117{
118 if (ofs >= 0) {
119 return ai | A64F_U12(ofs>>sc); /* Subsequent lj_ror checks ofs. */
120 } else if (ofs >= -256) {
121 return (ai^A64I_LS_U) | A64F_S9(ofs & 0x1ff);
122 } else {
123 return A64F_D(31); /* Will mismatch prev. */
124 }
125}
126
116static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs) 127static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs)
117{ 128{
118 int ot = emit_checkofs(ai, ofs), sc = (ai >> 30) & 3; 129 int ot = emit_checkofs(ai, ofs), sc = (ai >> 30) & 3;
@@ -124,11 +135,9 @@ static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs)
124 uint32_t prev = *as->mcp & ~A64F_D(31); 135 uint32_t prev = *as->mcp & ~A64F_D(31);
125 int ofsm = ofs - (1<<sc), ofsp = ofs + (1<<sc); 136 int ofsm = ofs - (1<<sc), ofsp = ofs + (1<<sc);
126 A64Ins aip; 137 A64Ins aip;
127 if (prev == (ai | A64F_N(rn) | A64F_U12(ofsm>>sc)) || 138 if (prev == emit_lso_pair_candidate(ai | A64F_N(rn), ofsm, sc)) {
128 prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsm&0x1ff))) {
129 aip = (A64F_A(rd) | A64F_D(*as->mcp & 31)); 139 aip = (A64F_A(rd) | A64F_D(*as->mcp & 31));
130 } else if (prev == (ai | A64F_N(rn) | A64F_U12(ofsp>>sc)) || 140 } else if (prev == emit_lso_pair_candidate(ai | A64F_N(rn), ofsp, sc)) {
131 prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsp&0x1ff))) {
132 aip = (A64F_D(rd) | A64F_A(*as->mcp & 31)); 141 aip = (A64F_D(rd) | A64F_A(*as->mcp & 31));
133 ofsm = ofs; 142 ofsm = ofs;
134 } else { 143 } else {