summaryrefslogtreecommitdiff
path: root/zjit/src/asm
diff options
context:
space:
mode:
Diffstat (limited to 'zjit/src/asm')
-rw-r--r--zjit/src/asm/mod.rs14
-rw-r--r--zjit/src/asm/x86_64/mod.rs10
-rw-r--r--zjit/src/asm/x86_64/tests.rs10
3 files changed, 26 insertions, 8 deletions
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/asm/x86_64/mod.rs b/zjit/src/asm/x86_64/mod.rs
index efc58dfdb8..fea66c8a3b 100644
--- a/zjit/src/asm/x86_64/mod.rs
+++ b/zjit/src/asm/x86_64/mod.rs
@@ -1024,7 +1024,10 @@ pub fn mov(cb: &mut CodeBlock, dst: X86Opnd, src: X86Opnd) {
}
let output_num_bits:u32 = if mem.num_bits > 32 { 32 } else { mem.num_bits.into() };
- assert!(imm_num_bits(imm.value) <= (output_num_bits as u8));
+ assert!(
+ mem.num_bits < 64 || imm_num_bits(imm.value) <= (output_num_bits as u8),
+ "immediate value should be small enough to survive sign extension"
+ );
cb.write_int(imm.value as u64, output_num_bits);
},
// M + UImm
@@ -1039,7 +1042,10 @@ pub fn mov(cb: &mut CodeBlock, dst: X86Opnd, src: X86Opnd) {
}
let output_num_bits = if mem.num_bits > 32 { 32 } else { mem.num_bits.into() };
- assert!(imm_num_bits(uimm.value as i64) <= (output_num_bits as u8));
+ assert!(
+ mem.num_bits < 64 || imm_num_bits(uimm.value as i64) <= (output_num_bits as u8),
+ "immediate value should be small enough to survive sign extension"
+ );
cb.write_int(uimm.value, output_num_bits);
},
// * + Imm/UImm
diff --git a/zjit/src/asm/x86_64/tests.rs b/zjit/src/asm/x86_64/tests.rs
index f2b949b7f7..ec490fd330 100644
--- a/zjit/src/asm/x86_64/tests.rs
+++ b/zjit/src/asm/x86_64/tests.rs
@@ -1,11 +1,10 @@
#![cfg(test)]
-//use crate::asm::x86_64::*;
+use crate::asm::x86_64::*;
-/*
/// Check that the bytes for an instruction sequence match a hex string
fn check_bytes<R>(bytes: &str, run: R) where R: FnOnce(&mut super::CodeBlock) {
- let mut cb = super::CodeBlock::new_dummy(4096);
+ let mut cb = super::CodeBlock::new_dummy();
run(&mut cb);
assert_eq!(format!("{:x}", cb), bytes);
}
@@ -194,6 +193,7 @@ fn test_mov() {
check_bytes("48c7470801000000", |cb| mov(cb, mem_opnd(64, RDI, 8), imm_opnd(1)));
//check_bytes("67c7400411000000", |cb| mov(cb, mem_opnd(32, EAX, 4), imm_opnd(0x34))); // We don't distinguish between EAX and RAX here - that's probably fine?
check_bytes("c7400411000000", |cb| mov(cb, mem_opnd(32, RAX, 4), imm_opnd(17)));
+ check_bytes("c7400401000080", |cb| mov(cb, mem_opnd(32, RAX, 4), uimm_opnd(0x80000001)));
check_bytes("41895814", |cb| mov(cb, mem_opnd(32, R8, 20), EBX));
check_bytes("4d8913", |cb| mov(cb, mem_opnd(64, R11, 0), R10));
check_bytes("48c742f8f4ffffff", |cb| mov(cb, mem_opnd(64, RDX, -8), imm_opnd(-12)));
@@ -439,9 +439,10 @@ fn basic_capstone_usage() -> std::result::Result<(), capstone::Error> {
}
#[test]
+#[ignore]
#[cfg(feature = "disasm")]
fn block_comments() {
- let mut cb = super::CodeBlock::new_dummy(4096);
+ let mut cb = super::CodeBlock::new_dummy();
let first_write_ptr = cb.get_write_ptr().raw_addr(&cb);
cb.add_comment("Beginning");
@@ -458,4 +459,3 @@ fn block_comments() {
assert_eq!(&vec!( "Two bytes in".to_string(), "Still two bytes in".to_string() ), cb.comments_at(second_write_ptr).unwrap());
assert_eq!(&vec!( "Ten bytes in".to_string() ), cb.comments_at(third_write_ptr).unwrap());
}
-*/