diff options
-rw-r--r-- | src/lj_asm_arm64.h | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index b771d2f1..372429db 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
@@ -232,7 +232,7 @@ static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow) | |||
232 | irl->o == IR_CONV && | 232 | irl->o == IR_CONV && |
233 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && | 233 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && |
234 | shift <= 4 && | 234 | shift <= 4 && |
235 | !neverfuse(as)) { | 235 | canfuse(as, irl)) { |
236 | Reg m = ra_alloc1(as, irl->op1, allow); | 236 | Reg m = ra_alloc1(as, irl->op1, allow); |
237 | return A64F_M(m) | A64F_EXSH(A64EX_SXTW, shift); | 237 | return A64F_M(m) | A64F_EXSH(A64EX_SXTW, shift); |
238 | } else { | 238 | } else { |
@@ -278,7 +278,7 @@ static void asm_fusexref(ASMState *as, A64Ins ai, Reg rd, IRRef ref, | |||
278 | } | 278 | } |
279 | if (irl->o == IR_CONV && | 279 | if (irl->o == IR_CONV && |
280 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && | 280 | irl->op2 == ((IRT_I64<<IRCONV_DSH)|IRT_INT|IRCONV_SEXT) && |
281 | !neverfuse(as)) { | 281 | canfuse(as, irl)) { |
282 | lref = irl->op1; | 282 | lref = irl->op1; |
283 | ai |= A64I_LS_SXTWx; | 283 | ai |= A64I_LS_SXTWx; |
284 | } else { | 284 | } else { |
@@ -351,10 +351,10 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air) | |||
351 | /* Fuse BAND + BSHL/BSHR into UBFM. */ | 351 | /* Fuse BAND + BSHL/BSHR into UBFM. */ |
352 | static int asm_fuseandshift(ASMState *as, IRIns *ir) | 352 | static int asm_fuseandshift(ASMState *as, IRIns *ir) |
353 | { | 353 | { |
354 | IRIns *irl = IR(ir->op1); | ||
354 | lua_assert(ir->o == IR_BAND); | 355 | lua_assert(ir->o == IR_BAND); |
355 | if (!neverfuse(as) && irref_isk(ir->op2)) { | 356 | if (canfuse(as, irl) && irref_isk(ir->op2)) { |
356 | uint64_t mask = get_k64val(IR(ir->op2)); | 357 | uint64_t mask = get_k64val(IR(ir->op2)); |
357 | IRIns *irl = IR(ir->op1); | ||
358 | if (irref_isk(irl->op2) && (irl->o == IR_BSHR || irl->o == IR_BSHL)) { | 358 | if (irref_isk(irl->op2) && (irl->o == IR_BSHR || irl->o == IR_BSHL)) { |
359 | int32_t shmask = irt_is64(irl->t) ? 63 : 31; | 359 | int32_t shmask = irt_is64(irl->t) ? 63 : 31; |
360 | int32_t shift = (IR(irl->op2)->i & shmask); | 360 | int32_t shift = (IR(irl->op2)->i & shmask); |
@@ -383,8 +383,9 @@ static int asm_fuseorshift(ASMState *as, IRIns *ir) | |||
383 | { | 383 | { |
384 | IRIns *irl = IR(ir->op1), *irr = IR(ir->op2); | 384 | IRIns *irl = IR(ir->op1), *irr = IR(ir->op2); |
385 | lua_assert(ir->o == IR_BOR); | 385 | lua_assert(ir->o == IR_BOR); |
386 | if (!neverfuse(as) && ((irl->o == IR_BSHR && irr->o == IR_BSHL) || | 386 | if (canfuse(as, irl) && canfuse(as, irr) && |
387 | (irl->o == IR_BSHL && irr->o == IR_BSHR))) { | 387 | ((irl->o == IR_BSHR && irr->o == IR_BSHL) || |
388 | (irl->o == IR_BSHL && irr->o == IR_BSHR))) { | ||
388 | if (irref_isk(irl->op2) && irref_isk(irr->op2)) { | 389 | if (irref_isk(irl->op2) && irref_isk(irr->op2)) { |
389 | IRRef lref = irl->op1, rref = irr->op1; | 390 | IRRef lref = irl->op1, rref = irr->op1; |
390 | uint32_t lshift = IR(irl->op2)->i, rshift = IR(irr->op2)->i; | 391 | uint32_t lshift = IR(irl->op2)->i, rshift = IR(irr->op2)->i; |
@@ -1511,11 +1512,11 @@ static void asm_bitshift(ASMState *as, IRIns *ir, A64Ins ai, A64Shift sh) | |||
1511 | if (irref_isk(ir->op2)) { /* Constant shifts. */ | 1512 | if (irref_isk(ir->op2)) { /* Constant shifts. */ |
1512 | Reg left, dest = ra_dest(as, ir, RSET_GPR); | 1513 | Reg left, dest = ra_dest(as, ir, RSET_GPR); |
1513 | int32_t shift = (IR(ir->op2)->i & shmask); | 1514 | int32_t shift = (IR(ir->op2)->i & shmask); |
1515 | IRIns *irl = IR(ir->op1); | ||
1514 | if (shmask == 63) ai += A64I_UBFMx - A64I_UBFMw; | 1516 | if (shmask == 63) ai += A64I_UBFMx - A64I_UBFMw; |
1515 | 1517 | ||
1516 | /* Fuse BSHL + BSHR/BSAR into UBFM/SBFM aka UBFX/SBFX/UBFIZ/SBFIZ. */ | 1518 | /* Fuse BSHL + BSHR/BSAR into UBFM/SBFM aka UBFX/SBFX/UBFIZ/SBFIZ. */ |
1517 | if (!neverfuse(as) && (sh == A64SH_LSR || sh == A64SH_ASR)) { | 1519 | if ((sh == A64SH_LSR || sh == A64SH_ASR) && canfuse(as, irl)) { |
1518 | IRIns *irl = IR(ir->op1); | ||
1519 | if (irl->o == IR_BSHL && irref_isk(irl->op2)) { | 1520 | if (irl->o == IR_BSHL && irref_isk(irl->op2)) { |
1520 | int32_t shift2 = (IR(irl->op2)->i & shmask); | 1521 | int32_t shift2 = (IR(irl->op2)->i & shmask); |
1521 | shift = ((shift - shift2) & shmask); | 1522 | shift = ((shift - shift2) & shmask); |