diff --git a/zjit/src/asm/mod.rs b/zjit/src/asm/mod.rs index a7f2705af1..0b571f9aff 100644 --- a/zjit/src/asm/mod.rs +++ b/zjit/src/asm/mod.rs @@ -1,5 +1,5 @@ use std::collections::BTreeMap; -//use std::fmt; +use std::fmt; use std::rc::Rc; use std::cell::RefCell; use std::mem; @@ -260,6 +260,18 @@ impl CodeBlock { } } +/// Produce hex string output from the bytes in a code block +impl fmt::LowerHex for CodeBlock { + fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { + for pos in 0..self.write_pos { + let mem_block = &*self.mem_block.borrow(); + let byte = unsafe { mem_block.start_ptr().raw_ptr(mem_block).add(pos).read() }; + fmtr.write_fmt(format_args!("{:02x}", byte))?; + } + Ok(()) + } +} + #[cfg(test)] impl CodeBlock { /// Stubbed CodeBlock for testing. Can't execute generated code. diff --git a/zjit/src/assertions.rs b/zjit/src/assertions.rs new file mode 100644 index 0000000000..0dacc938fc --- /dev/null +++ b/zjit/src/assertions.rs @@ -0,0 +1,21 @@ +/// Assert that CodeBlock has the code specified with hex. In addition, if tested with +/// `cargo test --all-features`, it also checks it generates the specified disasm. +#[cfg(test)] +macro_rules! assert_disasm { + ($cb:expr, $hex:expr, $disasm:expr) => { + #[cfg(feature = "disasm")] + { + use $crate::disasm::disasm_addr_range; + use $crate::cruby::unindent; + let disasm = disasm_addr_range( + &$cb, + $cb.get_ptr(0).raw_addr(&$cb), + $cb.get_write_ptr().raw_addr(&$cb), + ); + assert_eq!(unindent(&disasm, false), unindent(&$disasm, true)); + } + assert_eq!(format!("{:x}", $cb), $hex); + }; +} +#[cfg(test)] +pub(crate) use assert_disasm; diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index e9ae8730f6..c0d73071ea 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -1751,6 +1751,15 @@ impl Assembler ret } + /// Compile with a limited number of registers. Used only for unit tests. + #[cfg(test)] + pub fn compile_with_num_regs(self, cb: &mut CodeBlock, num_regs: usize) -> (CodePtr, Vec) + { + let mut alloc_regs = Self::get_alloc_regs(); + let alloc_regs = alloc_regs.drain(0..num_regs).collect(); + self.compile_with_regs(cb, alloc_regs).unwrap() + } + /// Compile Target::SideExit and convert it into Target::CodePtr for all instructions #[must_use] pub fn compile_side_exits(&mut self) -> Option<()> { diff --git a/zjit/src/backend/x86_64/mod.rs b/zjit/src/backend/x86_64/mod.rs index cf62cdd7f5..c9a5eab0ee 100644 --- a/zjit/src/backend/x86_64/mod.rs +++ b/zjit/src/backend/x86_64/mod.rs @@ -859,20 +859,17 @@ impl Assembler } } -/* #[cfg(test)] mod tests { - use crate::disasm::assert_disasm; - #[cfg(feature = "disasm")] - use crate::disasm::{unindent, disasm_addr_range}; - + use crate::assertions::assert_disasm; use super::*; fn setup_asm() -> (Assembler, CodeBlock) { - (Assembler::new(0), CodeBlock::new_dummy(1024)) + (Assembler::new(), CodeBlock::new_dummy()) } #[test] + #[ignore] fn test_emit_add_lt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -883,6 +880,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_add_gt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -893,6 +891,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_and_lt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -903,6 +902,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_and_gt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -957,6 +957,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_or_lt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -967,6 +968,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_or_gt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -977,6 +979,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_sub_lt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -987,6 +990,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_sub_gt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -1017,6 +1021,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_xor_lt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -1027,6 +1032,7 @@ mod tests { } #[test] + #[ignore] fn test_emit_xor_gt_32_bits() { let (mut asm, mut cb) = setup_asm(); @@ -1050,6 +1056,7 @@ mod tests { } #[test] + #[ignore] fn test_merge_lea_mem() { let (mut asm, mut cb) = setup_asm(); @@ -1064,6 +1071,7 @@ mod tests { } #[test] + #[ignore] fn test_replace_cmp_0() { let (mut asm, mut cb) = setup_asm(); @@ -1216,6 +1224,7 @@ mod tests { } #[test] + #[ignore] fn test_reorder_c_args_with_insn_out() { let (mut asm, mut cb) = setup_asm(); @@ -1259,15 +1268,16 @@ mod tests { asm.compile_with_num_regs(&mut cb, 1); - assert_disasm!(cb, "48837b1001b804000000480f4f03488903", {" + assert_disasm!(cb, "48837b1001bf04000000480f4f3b48893b", {" 0x0: cmp qword ptr [rbx + 0x10], 1 - 0x5: mov eax, 4 - 0xa: cmovg rax, qword ptr [rbx] - 0xe: mov qword ptr [rbx], rax + 0x5: mov edi, 4 + 0xa: cmovg rdi, qword ptr [rbx] + 0xe: mov qword ptr [rbx], rdi "}); } #[test] + #[ignore] fn test_csel_split() { let (mut asm, mut cb) = setup_asm(); @@ -1285,5 +1295,3 @@ mod tests { "}); } } - -*/ diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs index 8ccb6ae4c1..9d139b9801 100644 --- a/zjit/src/lib.rs +++ b/zjit/src/lib.rs @@ -21,3 +21,5 @@ mod disasm; mod options; mod profile; mod invariants; +#[cfg(test)] +mod assertions;