summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yjit/src/asm/arm64/arg/bitmask_imm.rs10
-rw-r--r--yjit/src/backend/arm64/mod.rs13
2 files changed, 15 insertions, 8 deletions
diff --git a/yjit/src/asm/arm64/arg/bitmask_imm.rs b/yjit/src/asm/arm64/arg/bitmask_imm.rs
index 220a7d697e..b3a821fe94 100644
--- a/yjit/src/asm/arm64/arg/bitmask_imm.rs
+++ b/yjit/src/asm/arm64/arg/bitmask_imm.rs
@@ -43,7 +43,7 @@ impl TryFrom<u64> for BitmaskImmediate {
fn try_from(value: u64) -> Result<Self, Self::Error> {
// 0 is not encodable as a bitmask immediate. Immediately return here so
// that we don't have any issues with underflow.
- if value == 0 {
+ if value == 0 || value == u64::MAX {
return Err(());
}
@@ -137,7 +137,7 @@ impl From<BitmaskImmediate> for u32 {
0
| (((bitmask.n as u32) & 1) << 12)
| ((bitmask.immr as u32) << 6)
- | bitmask.imms as u32
+ | (bitmask.imms as u32)
}
}
@@ -260,4 +260,10 @@ mod tests {
let bitmask = BitmaskImmediate::try_from(0xfffffffffffffffe);
assert!(matches!(bitmask, Ok(BitmaskImmediate { n: 1, immr: 0b111111, imms: 0b111110 })));
}
+
+ #[test]
+ fn test_size_64_invalid() {
+ let bitmask = BitmaskImmediate::try_from(u64::MAX);
+ assert!(matches!(bitmask, Err(())));
+ }
}
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs
index 57943ce58f..9726a0f8f2 100644
--- a/yjit/src/backend/arm64/mod.rs
+++ b/yjit/src/backend/arm64/mod.rs
@@ -295,9 +295,10 @@ impl Assembler
let opnd0 = split_store(asm, opnds[0]);
asm.store(opnd0, value);
},
- _ => {
+ Opnd::Reg(_) => {
asm.mov(opnds[0], value);
- }
+ },
+ _ => unreachable!()
};
},
Op::Not => {
@@ -488,7 +489,7 @@ impl Assembler
// offset. We're going to assume we can fit into a single
// b.cond instruction. It will panic otherwise.
cb.label_ref(label_idx, 4, |cb, src_addr, dst_addr| {
- bcond(cb, CONDITION, A64Opnd::new_imm(dst_addr - src_addr));
+ bcond(cb, CONDITION, A64Opnd::new_imm(dst_addr - (src_addr - 4)));
});
},
Target::FunPtr(_) => unreachable!()
@@ -595,8 +596,8 @@ impl Assembler
// references to GC'd Value operands. If the value
// being loaded is a heap object, we'll report that
// back out to the gc_offsets list.
- ldr(cb, insn.out.into(), 1);
- b(cb, A64Opnd::new_imm((SIZEOF_VALUE as i64) / 4));
+ ldr(cb, insn.out.into(), 2);
+ b(cb, A64Opnd::new_imm(1 + (SIZEOF_VALUE as i64) / 4));
cb.write_bytes(&value.as_u64().to_le_bytes());
if !value.special_const_p() {
@@ -743,7 +744,7 @@ impl Assembler
// to assume we can fit into a single b instruction.
// It will panic otherwise.
cb.label_ref(label_idx, 4, |cb, src_addr, dst_addr| {
- b(cb, A64Opnd::new_imm((dst_addr - src_addr) / 4 + 1));
+ b(cb, A64Opnd::new_imm((dst_addr - (src_addr - 4)) / 4));
});
},
_ => unreachable!()