From 8b1677e14e59c8ed5c61e200863a19576034d62e Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 19 Jun 2024 11:53:25 -0700 Subject: dedup mem size prefix printing --- src/long_mode/display.rs | 173 +++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 127 deletions(-) (limited to 'src') diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 686285e..75a85bb 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1293,7 +1293,6 @@ impl BigEnoughString { struct ColorizingOperandVisitor<'a, T> { instr: &'a Instruction, - op_nr: u8, f: &'a mut T, } @@ -1434,17 +1433,6 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi Ok(()) } fn visit_abs_u32(&mut self, imm: u32) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_char(':')?; - } self.f.write_fixed_size("[")?; self.f.write_fixed_size("0x")?; self.f.write_u32(imm)?; @@ -1452,38 +1440,16 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi Ok(()) } fn visit_abs_u64(&mut self, imm: u64) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_char(':')?; - } self.f.write_fixed_size("[")?; self.f.write_fixed_size("0x")?; self.f.write_u64(imm)?; self.f.write_fixed_size("]")?; Ok(()) } - #[inline(always)] + #[cfg_attr(not(feature="profiling"), inline(always))] + #[cfg_attr(feature="profiling", inline(never))] fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_char('[')?; unsafe { self.f.write_lt_8(regspec_label(®))?; } self.f.write_fixed_size(" ")?; @@ -1500,36 +1466,12 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi self.f.write_fixed_size("]") } fn visit_deref(&mut self, reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(®))?; } self.f.write_fixed_size("]") } fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(®))?; } self.f.write_fixed_size(" * ")?; self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc @@ -1538,19 +1480,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi Ok(()) } fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(®))?; } self.f.write_fixed_size(" * ")?; self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc @@ -1569,19 +1499,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi self.f.write_char(']') } fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&base))?; } self.f.write_fixed_size(" + ")?; unsafe { self.f.write_lt_8(regspec_label(&index))?; } @@ -1590,19 +1508,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi self.f.write_fixed_size("]") } fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.instr.segment_override_for_op(self.op_nr) { - let name = prefix.name(); - self.f.write_char(' ')?; - self.f.write_char(name[0] as char)?; - self.f.write_char(name[1] as char)?; - self.f.write_fixed_size(":[")?; - } else { - self.f.write_fixed_size(" [")?; - } + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&base))?; } self.f.write_fixed_size(" + ")?; unsafe { self.f.write_lt_8(regspec_label(&index))?; } @@ -1623,8 +1529,6 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi self.f.write_fixed_size("]") } fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; self.f.write_char('[')?; unsafe { self.f.write_lt_8(regspec_label(&spec))?; } self.f.write_char(' ')?; @@ -1640,16 +1544,12 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_reg_deref_masked(&mut self, spec: RegSpec, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&spec))?; } self.f.write_fixed_size("]")?; write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_reg_scale_masked(&mut self, spec: RegSpec, scale: u8, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; write!(self.f, "[{} * {}]", regspec_label(&spec), scale @@ -1657,8 +1557,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_reg_scale_disp_masked(&mut self, spec: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" [")?; + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&spec))?; } self.f.write_fixed_size(" * ")?; self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc @@ -1675,8 +1574,6 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&base))?; } self.f.write_fixed_size(" + ")?; @@ -1685,8 +1582,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" [")?; + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&base))?; } self.f.write_fixed_size(" + ")?; unsafe { self.f.write_lt_8(regspec_label(&index))?; } @@ -1703,8 +1599,7 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" [")?; + self.f.write_fixed_size("[")?; unsafe { self.f.write_lt_8(regspec_label(&base))?; } self.f.write_fixed_size(" + ")?; unsafe { self.f.write_lt_8(regspec_label(&index))?; } @@ -1714,8 +1609,6 @@ impl crate::long_mode::OperandVisitor for ColorizingOperandVisi write!(self.f, "{{{}}}", regspec_label(&mask_reg)) } fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result { - unsafe { self.f.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(self.instr.mem_size as usize))? }; - self.f.write_fixed_size(" ")?; write!(self.f, "[{} + {} * {} ", regspec_label(&base), regspec_label(&index), @@ -4789,9 +4682,21 @@ fn contextualize_intel(instr: &Instruction, out: &mut T) -> fmt: return Ok(()); } + if instr.operands[0 as usize].is_memory() { + unsafe { out.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(instr.mem_size as usize))? }; + if let Some(prefix) = instr.segment_override_for_op(0) { + let name = prefix.name(); + out.write_char(' ')?; + out.write_char(name[0] as char)?; + out.write_char(name[1] as char)?; + out.write_fixed_size(":")?; + } else { + out.write_fixed_size(" ")?; + } + } + let mut displayer = ColorizingOperandVisitor { instr, - op_nr: 0, f: out, }; instr.visit_operand(0 as u8, &mut displayer)?; @@ -4800,18 +4705,34 @@ fn contextualize_intel(instr: &Instruction, out: &mut T) -> fmt: // don't worry about checking for `instr.operands[i] != Nothing`, it would be a bug to // reach that while iterating only to `operand_count`.. out.write_fixed_size(", ")?; + if i >= 4 { + unsafe { core::hint::unreachable_unchecked(); } + } + + if instr.operands[i as usize].is_memory() { + unsafe { out.write_lt_8(MEM_SIZE_STRINGS.get_kinda_unchecked(instr.mem_size as usize))? }; + if i >= 4 { + unsafe { core::hint::unreachable_unchecked(); } + } + if let Some(prefix) = instr.segment_override_for_op(i) { + let name = prefix.name(); + out.write_char(' ')?; + out.write_char(name[0] as char)?; + out.write_char(name[1] as char)?; + out.write_fixed_size(":")?; + } else { + out.write_fixed_size(" ")?; + } + } + let mut displayer = ColorizingOperandVisitor { instr, - op_nr: i, f: out, }; - if i >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } + instr.visit_operand(i as u8, &mut displayer)?; if let Some(evex) = instr.prefixes.evex() { - let x = Operand::from_spec(instr, instr.operands[i as usize]); - if evex.broadcast() && x.is_memory() { + if evex.broadcast() && instr.operands[i as usize].is_memory() { let scale = if instr.opcode == Opcode::VCVTPD2PS || instr.opcode == Opcode::VCVTTPD2UDQ || instr.opcode == Opcode::VCVTPD2UDQ || instr.opcode == Opcode::VCVTUDQ2PD || instr.opcode == Opcode::VCVTPS2PD || instr.opcode == Opcode::VCVTQQ2PS || instr.opcode == Opcode::VCVTDQ2PD || instr.opcode == Opcode::VCVTTPD2DQ || instr.opcode == Opcode::VFPCLASSPS || instr.opcode == Opcode::VFPCLASSPD || instr.opcode == Opcode::VCVTNEPS2BF16 || instr.opcode == Opcode::VCVTUQQ2PS || instr.opcode == Opcode::VCVTPD2DQ || instr.opcode == Opcode::VCVTTPS2UQQ || instr.opcode == Opcode::VCVTPS2UQQ || instr.opcode == Opcode::VCVTTPS2QQ || instr.opcode == Opcode::VCVTPS2QQ { if instr.opcode == Opcode::VFPCLASSPS || instr.opcode == Opcode::VCVTNEPS2BF16 { if evex.vex().l() { @@ -5271,7 +5192,6 @@ impl ShowContextual ShowContextual