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); |
