commit 49a2579ade172287209d5ba5d477cbab9d1ae3ec
parent 402214953fc203f0bfcc27a4c9c2adaf552f70fd
Author: André Bargull <andre.bargull@gmail.com>
Date: Thu, 23 Oct 2025 12:23:35 +0000
Bug 1995707 - Part 4: Do not bypass optimisations in Mov for registers. r=spidermonkey-reviewers,jandem
Backport of <https://github.com/Linaro/vixl/commit/1c78c34397f2c08c012733cc661076e8bd029eab>.
Differential Revision: https://phabricator.services.mozilla.com/D269554
Diffstat:
3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/js/src/jit/arm64/MacroAssembler-arm64.cpp b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -3799,7 +3799,10 @@ void MacroAssembler::shiftIndex32AndAdd(Register indexTemp32, int shift,
Operand(ARMRegister(indexTemp32, 64), vixl::LSL, shift));
}
-void MacroAssembler::wasmMarkCallAsSlow() { Mov(x28, x28); }
+void MacroAssembler::wasmMarkCallAsSlow() {
+ // Use mov() instead of Mov() to ensure this no-op move isn't elided.
+ vixl::MacroAssembler::mov(x28, x28);
+}
const int32_t SlowCallMarker = 0xaa1c03fc;
diff --git a/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp b/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp
@@ -480,19 +480,7 @@ void MacroAssembler::Mov(const Register& rd,
EmitExtendShift(rd, operand.reg(), operand.extend(),
operand.shift_amount());
} else {
- // Otherwise, emit a register move only if the registers are distinct, or
- // if they are not X registers.
- //
- // Note that mov(w0, w0) is not a no-op because it clears the top word of
- // x0. A flag is provided (kDiscardForSameWReg) if a move between the same W
- // registers is not required to clear the top word of the X register. In
- // this case, the instruction is discarded.
- //
- // If the sp is an operand, add #0 is emitted, otherwise, orr #0.
- if (!rd.Is(operand.reg()) || (rd.Is32Bits() &&
- (discard_mode == kDontDiscardForSameWReg))) {
- mov(rd, operand.reg());
- }
+ Mov(rd, operand.reg(), discard_mode);
}
}
diff --git a/js/src/jit/arm64/vixl/MacroAssembler-vixl.h b/js/src/jit/arm64/vixl/MacroAssembler-vixl.h
@@ -1184,9 +1184,23 @@ class MacroAssembler : public js::jit::Assembler {
SingleEmissionCheckScope guard(this);
mneg(rd, rn, rm);
}
- void Mov(const Register& rd, const Register& rn) {
- SingleEmissionCheckScope guard(this);
- mov(rd, rn);
+ void Mov(const Register& rd,
+ const Register& rn,
+ DiscardMoveMode discard_mode = kDontDiscardForSameWReg) {
+ // Emit a register move only if the registers are distinct, or if they are
+ // not X registers.
+ //
+ // Note that mov(w0, w0) is not a no-op because it clears the top word of
+ // x0. A flag is provided (kDiscardForSameWReg) if a move between the same W
+ // registers is not required to clear the top word of the X register. In
+ // this case, the instruction is discarded.
+ //
+ // If the sp is an operand, add #0 is emitted, otherwise, orr #0.
+ if (!rd.Is(rn) ||
+ (rd.Is32Bits() && (discard_mode == kDontDiscardForSameWReg))) {
+ SingleEmissionCheckScope guard(this);
+ mov(rd, rn);
+ }
}
void Movk(const Register& rd, uint64_t imm, int shift = -1) {
VIXL_ASSERT(!rd.IsZero());