summaryrefslogtreecommitdiff
path: root/yjit/src/backend
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2022-07-22 18:02:24 -0400
committerTakashi Kokubun <takashikkbn@gmail.com>2022-08-29 08:47:04 -0700
commit8617bac950fbee712e621f79bf96ca30fa9aa2ec (patch)
tree139c7fffa7cab7c11d5cfdf528c31b6a1c4d3bc0 /yjit/src/backend
parente131b217cfa9f29a0677e65cf573494279eda8a5 (diff)
downloadruby-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.rs22
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);