From a781322552d9fb52b7b5e51641f49f12678f682f Mon Sep 17 00:00:00 2001 From: iximeow Date: Thu, 1 Jul 2021 23:54:06 -0700 Subject: reallocate OperandCode, convert disparate registers to array also remove redundant assignments of operand_count and some OperandSpec, bulk-assign all registers and operands on entry to `read_instr`. this all, taken together, shaves off about 7 cycles per decode. --- test/long_mode/display.rs | 3 ++- test/long_mode/evex_generated.rs | 8 +++++--- test/long_mode/mod.rs | 6 ++++-- test/long_mode/operand.rs | 14 +++++++------- test/long_mode/reuse_test.rs | 10 +++++++--- test/protected_mode/display.rs | 3 ++- test/protected_mode/evex_generated.rs | 8 +++++--- test/protected_mode/mod.rs | 6 ++++-- 8 files changed, 36 insertions(+), 22 deletions(-) (limited to 'test') diff --git a/test/long_mode/display.rs b/test/long_mode/display.rs index 4ef3f74..fc59427 100644 --- a/test/long_mode/display.rs +++ b/test/long_mode/display.rs @@ -12,7 +12,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr.display_with(DisplayStyle::C)); assert!( diff --git a/test/long_mode/evex_generated.rs b/test/long_mode/evex_generated.rs index 9c23e4b..dcb4e01 100644 --- a/test/long_mode/evex_generated.rs +++ b/test/long_mode/evex_generated.rs @@ -1,6 +1,6 @@ use std::fmt::Write; -use yaxpeax_arch::{AddressBase, Decoder, LengthedInstruction}; +use yaxpeax_arch::{AddressBase, Decoder, U8Reader, LengthedInstruction}; use yaxpeax_x86::long_mode::InstDecoder; #[allow(dead_code)] @@ -9,7 +9,8 @@ fn test_invalid(data: &[u8]) { } fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { - if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { + let mut reader = U8Reader::new(data); + if let Ok(inst) = decoder.decode(&mut reader) { panic!("decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); } else { // this is fine @@ -26,7 +27,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr); assert!( diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index cbd881c..1eedfec 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -16,7 +16,8 @@ fn test_invalid(data: &[u8]) { } fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { - if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + if let Ok(inst) = decoder.decode(&mut reader) { panic!("decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); } else { // this is fine @@ -32,7 +33,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr); assert!( diff --git a/test/long_mode/operand.rs b/test/long_mode/operand.rs index f0300d6..77ce256 100644 --- a/test/long_mode/operand.rs +++ b/test/long_mode/operand.rs @@ -2,15 +2,15 @@ use yaxpeax_x86::long_mode::{Operand, RegSpec}; #[test] fn register_widths() { - assert_eq!(Operand::Register(RegSpec::rsp()).width(), 8); - assert_eq!(Operand::Register(RegSpec::esp()).width(), 4); - assert_eq!(Operand::Register(RegSpec::sp()).width(), 2); - assert_eq!(Operand::Register(RegSpec::cl()).width(), 1); - assert_eq!(Operand::Register(RegSpec::ch()).width(), 1); - assert_eq!(Operand::Register(RegSpec::gs()).width(), 2); + assert_eq!(Operand::Register(RegSpec::rsp()).width(), Some(8)); + assert_eq!(Operand::Register(RegSpec::esp()).width(), Some(4)); + assert_eq!(Operand::Register(RegSpec::sp()).width(), Some(2)); + assert_eq!(Operand::Register(RegSpec::cl()).width(), Some(1)); + assert_eq!(Operand::Register(RegSpec::ch()).width(), Some(1)); + assert_eq!(Operand::Register(RegSpec::gs()).width(), Some(2)); } #[test] fn memory_widths() { - assert_eq!(Operand::RegDeref(RegSpec::rsp()).width(), 8); + assert_eq!(Operand::RegDeref(RegSpec::rsp()).width(), None); } diff --git a/test/long_mode/reuse_test.rs b/test/long_mode/reuse_test.rs index 117f3fa..60a91e1 100644 --- a/test/long_mode/reuse_test.rs +++ b/test/long_mode/reuse_test.rs @@ -1989,17 +1989,21 @@ const INSTRUCTIONS: [&'static [u8]; 1982] = [ #[test] fn test_against_leftover_data() { use super::rand::{thread_rng, Rng}; + use yaxpeax_arch::U8Reader; let mut rng = thread_rng(); let decoder = InstDecoder::default(); for _ in 0..100000 { let first_vec = INSTRUCTIONS[rng.gen_range(0..INSTRUCTIONS.len())]; - let first_decode = decoder.decode(first_vec.to_vec().iter().cloned()).unwrap(); + let mut first_reader = U8Reader::new(first_vec); + let first_decode = decoder.decode(&mut first_reader).unwrap(); let second_vec = INSTRUCTIONS[rng.gen_range(0..INSTRUCTIONS.len())]; - let mut reused_decode = decoder.decode(second_vec.to_vec().iter().cloned()).unwrap(); - decoder.decode_into(&mut reused_decode, first_vec.to_vec().iter().cloned()).unwrap(); + let mut second_reader = U8Reader::new(second_vec); + let mut reused_decode = decoder.decode(&mut second_reader).unwrap(); + let mut first_reader = U8Reader::new(first_vec); + decoder.decode_into(&mut reused_decode, &mut first_reader).unwrap(); assert_eq!(first_decode, reused_decode); } diff --git a/test/protected_mode/display.rs b/test/protected_mode/display.rs index 8426a0a..694c38c 100644 --- a/test/protected_mode/display.rs +++ b/test/protected_mode/display.rs @@ -12,7 +12,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr.display_with(DisplayStyle::C)); assert!( diff --git a/test/protected_mode/evex_generated.rs b/test/protected_mode/evex_generated.rs index 333c3c6..236edec 100644 --- a/test/protected_mode/evex_generated.rs +++ b/test/protected_mode/evex_generated.rs @@ -1,6 +1,6 @@ use std::fmt::Write; -use yaxpeax_arch::{AddressBase, Decoder, LengthedInstruction}; +use yaxpeax_arch::{AddressBase, Decoder, U8Reader, LengthedInstruction}; use yaxpeax_x86::protected_mode::InstDecoder; #[allow(dead_code)] @@ -9,7 +9,8 @@ fn test_invalid(data: &[u8]) { } fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { - if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { + let mut reader = U8Reader::new(data); + if let Ok(inst) = decoder.decode(&mut reader) { panic!("decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); } else { // this is fine @@ -26,7 +27,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr); assert!( diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 6e2ded9..9221e7d 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -13,7 +13,8 @@ fn test_invalid(data: &[u8]) { } fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { - if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + if let Ok(inst) = decoder.decode(&mut reader) { panic!("decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); } else { // this is fine @@ -29,7 +30,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str for b in data { write!(hex, "{:02x}", b).unwrap(); } - match decoder.decode(data.into_iter().map(|x| *x)) { + let mut reader = yaxpeax_arch::U8Reader::new(data); + match decoder.decode(&mut reader) { Ok(instr) => { let text = format!("{}", instr); assert!( -- cgit v1.1