summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2025-07-15 20:13:53 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2025-07-16 14:10:22 -0400
commit0c26dea5bb49ab98d2248f02cbbae82393a3c844 (patch)
treef697688c7da523212c7494c2571dec7fbde7ff67
parent7df8e9e4276afd9f14a6b6d650b8031de1dd8408 (diff)
ZJIT: A64: Fix the optimization merging `asm.add(reg, imm)` with Mov
The raw bytes didn't disassemble to the disassembly, but we missed this since CI didn't run `make zjit-test` with the disasm feature. Fixes: 1317377fa74 ("ZJIT: A64: Have add/sub to SP be single-instruction")
-rw-r--r--zjit/src/backend/arm64/mod.rs13
1 files changed, 8 insertions, 5 deletions
diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs
index db4fc5f710..25b0a525fd 100644
--- a/zjit/src/backend/arm64/mod.rs
+++ b/zjit/src/backend/arm64/mod.rs
@@ -421,13 +421,16 @@ impl Assembler
(Opnd::Reg(_) | Opnd::VReg { .. }, Opnd::Reg(_) | Opnd::VReg { .. }) => {
merge_three_reg_mov(&live_ranges, &mut iterator, left, right, out);
asm.push_insn(insn);
- },
+ }
(reg_opnd @ (Opnd::Reg(_) | Opnd::VReg { .. }), other_opnd) |
(other_opnd, reg_opnd @ (Opnd::Reg(_) | Opnd::VReg { .. })) => {
*left = reg_opnd;
*right = split_shifted_immediate(asm, other_opnd);
+ // Now `right` is either a register or an immediate, both can try to
+ // merge with a subsequent mov.
+ merge_three_reg_mov(&live_ranges, &mut iterator, left, left, out);
asm.push_insn(insn);
- },
+ }
_ => {
*left = split_load_operand(asm, *left);
*right = split_shifted_immediate(asm, *right);
@@ -1381,12 +1384,12 @@ mod tests {
asm.mov(sp, new_sp);
let new_sp = asm.sub(sp, 0x20.into());
asm.mov(sp, new_sp);
- asm.compile_with_num_regs(&mut cb, 2);
- assert_disasm!(cb, "e08300b11f000091e08300f11f000091", {"
+ asm.compile_with_num_regs(&mut cb, 2);
+ assert_disasm!(cb, "ff830091ff8300d1", "
0x0: add sp, sp, #0x20
0x4: sub sp, sp, #0x20
- "});
+ ");
}
#[test]