diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2022-07-22 18:02:24 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-29 08:47:04 -0700 |
commit | 8617bac950fbee712e621f79bf96ca30fa9aa2ec (patch) | |
tree | 139c7fffa7cab7c11d5cfdf528c31b6a1c4d3bc0 /yjit/src/backend | |
parent | e131b217cfa9f29a0677e65cf573494279eda8a5 (diff) | |
download | ruby-8617bac950fbee712e621f79bf96ca30fa9aa2ec.tar.gz |
Fix IncrCounter on ARM
The order of operands to LDADDAL were flipped and the destination
pointer was dereferenced instead of passed as an address.
Diffstat (limited to 'yjit/src/backend')
-rw-r--r-- | yjit/src/backend/arm64/mod.rs | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index c6cd1b882c..12cd267245 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -238,17 +238,17 @@ impl Assembler asm.push_insn(op, new_opnds, target, text, pos_marker); }, Op::IncrCounter => { - // Every operand to the IncrCounter instruction need to be a - // register once it gets there. So here we're going to load - // anything that isn't a register first. - let new_opnds: Vec<Opnd> = opnds.into_iter().map(|opnd| { - match opnd { - Opnd::Mem(_) | Opnd::Imm(_) | Opnd::UImm(_) => asm.load(opnd), - _ => opnd, - } - }).collect(); + // We'll use LDADD later which only works with registers + // ... Load pointer into register + let counter_addr = asm.lea(opnds[0]); + + // Load immediates into a register + let addend = match opnds[1] { + opnd @ Opnd::Imm(_) | opnd @ Opnd::UImm(_) => asm.load(opnd), + opnd => opnd, + }; - asm.incr_counter(new_opnds[0], new_opnds[1]); + asm.incr_counter(counter_addr, addend); }, Op::JmpOpnd => { if let Opnd::Mem(_) = opnds[0] { @@ -769,7 +769,7 @@ impl Assembler emit_conditional_jump::<{Condition::VS}>(cb, insn.target.unwrap()); }, Op::IncrCounter => { - ldaddal(cb, insn.opnds[0].into(), insn.opnds[0].into(), insn.opnds[1].into()); + ldaddal(cb, insn.opnds[1].into(), insn.opnds[1].into(), insn.opnds[0].into()); }, Op::Breakpoint => { brk(cb, A64Opnd::None); |