diff options
author | Mike Pall <mike> | 2023-09-09 20:57:46 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-09-09 20:57:46 +0200 |
commit | 90742d91c27d185b70d1b4a6343fb6b7c26002db (patch) | |
tree | 3b99bd38d581fdd74d440054befeb111b90b4342 /src | |
parent | ba2b34f5e82baec5f925fa89b7bf4f88ae376da9 (diff) | |
download | luajit-90742d91c27d185b70d1b4a6343fb6b7c26002db.tar.gz luajit-90742d91c27d185b70d1b4a6343fb6b7c26002db.tar.bz2 luajit-90742d91c27d185b70d1b4a6343fb6b7c26002db.zip |
ARM64: Don't fuse sign extensions into logical operands.
Thanks to Peter Cawley. #1076
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm_arm64.h | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index 05bdc78a..04834f57 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
@@ -216,16 +216,13 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow, | |||
216 | static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow) | 216 | static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow) |
217 | { | 217 | { |
218 | IRIns *ir = IR(ref); | 218 | IRIns *ir = IR(ref); |
219 | int logical = (ai & 0x1f000000) == 0x0a000000; | ||
219 | if (ra_hasreg(ir->r)) { | 220 | if (ra_hasreg(ir->r)) { |
220 | ra_noweak(as, ir->r); | 221 | ra_noweak(as, ir->r); |
221 | return A64F_M(ir->r); | 222 | return A64F_M(ir->r); |
222 | } else if (irref_isk(ref)) { | 223 | } else if (irref_isk(ref)) { |
223 | uint32_t m; | ||
224 | int64_t k = get_k64val(as, ref); | 224 | int64_t k = get_k64val(as, ref); |
225 | if ((ai & 0x1f000000) == 0x0a000000) | 225 | uint32_t m = logical ? emit_isk13(k, irt_is64(ir->t)) : emit_isk12(k); |
226 | m = emit_isk13(k, irt_is64(ir->t)); | ||
227 | else | ||
228 | m = emit_isk12(k); | ||
229 | if (m) | 226 | if (m) |
230 | return m; | 227 | return m; |
231 | } else if (mayfuse(as, ref)) { | 228 | } else if (mayfuse(as, ref)) { |
@@ -237,7 +234,7 @@ static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow) | |||
237 | (IR(ir->op2)->i & (irt_is64(ir->t) ? 63 : 31)); | 234 | (IR(ir->op2)->i & (irt_is64(ir->t) ? 63 : 31)); |
238 | IRIns *irl = IR(ir->op1); | 235 | IRIns *irl = IR(ir->op1); |
239 | if (sh == A64SH_LSL && | 236 | if (sh == A64SH_LSL && |
240 | irl->o == IR_CONV && | 237 | irl->o == IR_CONV && !logical && |
241 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && | 238 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && |
242 | shift <= 4 && | 239 | shift <= 4 && |
243 | canfuse(as, irl)) { | 240 | canfuse(as, irl)) { |
@@ -247,7 +244,7 @@ static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow) | |||
247 | Reg m = ra_alloc1(as, ir->op1, allow); | 244 | Reg m = ra_alloc1(as, ir->op1, allow); |
248 | return A64F_M(m) | A64F_SH(sh, shift); | 245 | return A64F_M(m) | A64F_SH(sh, shift); |
249 | } | 246 | } |
250 | } else if (ir->o == IR_CONV && | 247 | } else if (ir->o == IR_CONV && !logical && |
251 | ir->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT)) { | 248 | ir->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT)) { |
252 | Reg m = ra_alloc1(as, ir->op1, allow); | 249 | Reg m = ra_alloc1(as, ir->op1, allow); |
253 | return A64F_M(m) | A64F_EX(A64EX_SXTW); | 250 | return A64F_M(m) | A64F_EX(A64EX_SXTW); |