From 6248d3c5f7dd196acdfce5c0da1608fed81b43cd Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 9 Aug 2020 20:49:12 -0700 Subject: inaugural 0.1.0 release! add doc comments for public items, record changelog, and lets ship this!! --- src/long_mode/mod.rs | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'src/long_mode/mod.rs') diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 23213ec..f328c72 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -19,16 +19,6 @@ pub struct RegSpec { bank: RegisterBank } -impl RegSpec { - pub fn num(&self) -> u8 { - self.num - } - - pub fn class(&self) -> RegisterClass { - RegisterClass { kind: self.bank } - } -} - use core::hash::Hash; use core::hash::Hasher; impl Hash for RegSpec { @@ -70,6 +60,16 @@ pub enum ConditionCode { #[allow(non_snake_case)] impl RegSpec { + pub fn num(&self) -> u8 { + self.num + } + + pub fn class(&self) -> RegisterClass { + RegisterClass { kind: self.bank } + } + + /// return a human-friendly name for this register. the returned name is the same as would be + /// used to render this register in an instruction. pub fn name(&self) -> &'static str { display::regspec_label(self) } @@ -465,6 +465,10 @@ impl Operand { } } + /// return the width of this operand, in bytes. register widths are determined by the + /// register's class. + /// + /// TODO: /!\ MEMORY WIDTHS ARE ALWAYS REPORTED AS 8 /!\ pub fn width(&self) -> u8 { match self { Operand::Nothing => { @@ -555,10 +559,12 @@ const REGISTER_CLASS_NAMES: &[&'static str] = &[ ]; impl RegisterClass { + /// return a human-friendly name for this register class pub fn name(&self) -> &'static str { REGISTER_CLASS_NAMES[self.kind as usize] } + /// return the size of this register class, in bytes pub fn width(&self) -> u8 { match self.kind { RegisterBank::Q => 8, @@ -3185,15 +3191,22 @@ impl Instruction { self.opcode } + /// get the `Operand` at the provided index. + /// + /// panics if the index is `>= 4`. pub fn operand(&self, i: u8) -> Operand { assert!(i < 4); Operand::from_spec(self, self.operands[i as usize]) } + /// get the number of operands in this instruction. useful in iterating an instruction's + /// operands generically. pub fn operand_count(&self) -> u8 { self.operand_count } + /// check if operand `i` is an actual operand or not. will be `false` for `i >= + /// inst.operand_count()`. pub fn operand_present(&self, i: u8) -> bool { assert!(i < 4); if i >= self.operand_count { @@ -3207,6 +3220,8 @@ impl Instruction { } } + /// build a new instruction representing nothing in particular. this is primarily useful as a + /// default to pass to `decode_into`. pub fn invalid() -> Instruction { Instruction { prefixes: Prefixes::new(0), @@ -3657,7 +3672,7 @@ enum OperandCode { DX_AL = OperandCodeBuilder::new().special_case(47).bits(), MOVQ_f30f = OperandCodeBuilder::new().special_case(48).bits(), - Unsupported = OperandCodeBuilder::new().special_case(49).bits(), +// Unsupported = OperandCodeBuilder::new().special_case(49).bits(), ModRM_0x0f00 = OperandCodeBuilder::new().read_modrm().special_case(40).bits(), ModRM_0x0f01 = OperandCodeBuilder::new().read_modrm().special_case(41).bits(), @@ -6431,9 +6446,11 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::ImmU8; instruction.operand_count = 1; } + /* OperandCode::Unsupported => { return Err(DecodeError::IncompleteDecoder); } + */ OperandCode::Iw_Ib => { instruction.disp = read_num(&mut bytes_iter, 2)? as u64; instruction.imm = read_num(&mut bytes_iter, 1)? as u64; @@ -7446,7 +7463,6 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = OperandSpec::Deref; instruction.operand_count = 2; } - // TODO: two memory operands! this is wrong!!! OperandCode::Yb_Xb => { instruction.operands[0] = OperandSpec::Deref_rdi; instruction.operands[1] = OperandSpec::Deref_rsi; @@ -8655,12 +8671,10 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: Prefixes) -> u if prefixes.rex().w() || !prefixes.operand_size() { 4 } else { 2 } }, SizeCode::vq => { - // TODO: this should be address_size - // but i'm not sure if that breaks other instructions rn if prefixes.operand_size() { 2 } else { - 8 // TODO: this 8 should be arch width. + 8 } }, SizeCode::vqp => { -- cgit v1.1