diff options
Diffstat (limited to 'src/long_mode/display.rs')
-rw-r--r-- | src/long_mode/display.rs | 1098 |
1 files changed, 0 insertions, 1098 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 0188361..84b0894 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1281,8 +1281,6 @@ struct ColorizingOperandVisitor<'a, T> { f: &'a mut T, } -use core::mem::MaybeUninit; - impl <T: DisplaySink> crate::long_mode::OperandVisitor for ColorizingOperandVisitor<'_, T> { type Ok = (); type Error = core::fmt::Error; @@ -4732,1102 +4730,6 @@ fn c_to_hex(c: u8) -> u8 { } impl Instruction { -// pub fn write_2<T, U: Writable<T>>(&self, out: &mut alloc::string::String) -> fmt::Result { - #[cfg_attr(feature="profiling", inline(never))] - pub fn write_2(&self, out: &mut alloc::string::String) -> fmt::Result { - use core::fmt::Write; - - fn anguished_string_write(out: &mut alloc::string::String, label: &str) { - let new_bytes = label.as_bytes(); - let buf = unsafe { out.as_mut_vec() }; - anguished_bstring_write(buf, new_bytes); - } - fn anguished_bstring_write(buf: &mut alloc::vec::Vec<u8>, new_bytes: &[u8]) { - if new_bytes.len() >= 32 { - unsafe { core::hint::unreachable_unchecked() } - } - buf.reserve(new_bytes.len()); - for i in 0..new_bytes.len() { - unsafe { - buf.as_mut_ptr().offset(buf.len() as isize).offset(i as isize).write_volatile(new_bytes[i]); - } - } - unsafe { - buf.set_len(buf.len() + new_bytes.len()); - } - } - - fn danger_anguished_string_write(out: &mut alloc::string::String, label: &str) { - let new_bytes = label.as_bytes(); - let buf = unsafe { out.as_mut_vec() }; - danger_anguished_bstring_write(buf, new_bytes); - } - fn danger_anguished_bstring_write(buf: &mut alloc::vec::Vec<u8>, new_bytes: &[u8]) { - if new_bytes.len() >= 16 { - unsafe { core::hint::unreachable_unchecked() } - } - - unsafe { - let dest = buf.as_mut_ptr().offset(buf.len() as isize); - let src = new_bytes.as_ptr(); - - let mut rem = new_bytes.len() as isize; - unsafe { - buf.set_len(buf.len() + new_bytes.len()); - } - /* - while rem % 4 > 0 { - dest.offset(rem - 1).write_unaligned(src.offset(rem - 1).read_unaligned()); - rem -= 1; - } - - while rem > 0 { - (dest.offset(rem - 4) as *mut u32).write_unaligned(unsafe { - *core::mem::transmute::<&u8, &u32>(&new_bytes[rem as usize - 4]) - }); - rem -= 4; - } - */ - /* - unsafe { - core::arch::asm!( - "7:", - "cmp {rem}, 4", - "jb 8f", - "sub {rem}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jmp 7b", - "8:", - "test {rem}, {rem}", - "jz 10f", - "sub {rem}, 1", - "mov {buf:l}, byte ptr [{src} + {rem}]", - "mov byte ptr [{dest} + {rem}], {buf:l}", - "jnz 8b", - "10:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, -// tmp = out(reg) _, - buf = out(reg) _, - options(nostack), - ); - } - */ - /* - unsafe { - core::arch::asm!( - "mov {tmp}, {rem}", - "and {tmp}, 3", - "je 3f", - "sub {rem}, {tmp}", - "2:", - "mov {buf:l}, byte ptr [{src}]", - "mov byte ptr [{dest}], {buf:l}", - "add {src}, 1", - "add {dest}, 1", - "sub {tmp}, 1", - "jnz 2b", - "3:", - "test {rem}, {rem}", - "jz 5f", - "4:", - "sub {rem}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jnz 4b", - "5:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, - tmp = out(reg) _, - buf = out(reg) _, - ); - } - */ - /* - */ - dest.offset(0 as isize).write(new_bytes[0]); - for i in 1..new_bytes.len() { - unsafe { - dest.offset(i as isize).write(new_bytes[i]); - } - } - // } - } - } - - fn danger_anguished_variable_length_string_write(out: &mut alloc::string::String, label: &str) { - let new_bytes = label.as_bytes(); - let buf = unsafe { out.as_mut_vec() }; - danger_anguished_variable_length_bstring_write(buf, new_bytes); - } - #[cfg_attr(feature="profiling", inline(never))] - fn danger_anguished_variable_length_bstring_write(buf: &mut alloc::vec::Vec<u8>, new_bytes: &[u8]) { - if new_bytes.len() >= 16 { - unsafe { core::hint::unreachable_unchecked() } - } - if new_bytes.len() == 0 { - unsafe { core::hint::unreachable_unchecked() } - } - - unsafe { - let dest = buf.as_mut_ptr().offset(buf.len() as isize); - let src = new_bytes.as_ptr(); - - let mut rem = new_bytes.len() as isize; - unsafe { - buf.set_len(buf.len() + new_bytes.len()); - } - /* - while rem % 4 > 0 { - dest.offset(rem - 1).write_unaligned(src.offset(rem - 1).read_unaligned()); - rem -= 1; - } - - while rem > 0 { - (dest.offset(rem - 4) as *mut u32).write_unaligned(unsafe { - *core::mem::transmute::<&u8, &u32>(&new_bytes[rem as usize - 4]) - }); - rem -= 4; - } - */ - unsafe { - /* - if rem >= 8 { - rem -= 8; - (dest.offset(rem) as *mut u64).write_unaligned((src.offset(rem) as *const u64).read_unaligned()) - } - if rem >= 4 { - rem -= 4; - (dest.offset(rem) as *mut u32).write_unaligned((src.offset(rem) as *const u32).read_unaligned()); - if rem == 0 { - return; - } - } - if rem >= 2 { - rem -= 2; - (dest.offset(rem) as *mut u16).write_unaligned((src.offset(rem) as *const u16).read_unaligned()); - if rem == 0 { - return; - } - } - if rem >= 1 { - rem -= 1; - (dest.offset(rem) as *mut u8).write_unaligned((src.offset(rem) as *const u8).read_unaligned()) - } - */ - core::arch::asm!( - "7:", - "cmp {rem:e}, 8", - "jb 8f", - "mov {buf:r}, qword ptr [{src} + {rem} - 8]", - "mov qword ptr [{dest} + {rem} - 8], {buf:r}", - "sub {rem:e}, 8", - "jz 11f", - "8:", - "cmp {rem:e}, 4", - "jb 9f", - "mov {buf:e}, dword ptr [{src} + {rem} - 4]", - "mov dword ptr [{dest} + {rem} - 4], {buf:e}", - "sub {rem:e}, 4", - "jz 11f", - "9:", - "cmp {rem:e}, 2", - "jb 10f", - "mov {buf:x}, word ptr [{src} + {rem} - 2]", - "mov word ptr [{dest} + {rem} - 2], {buf:x}", - "sub {rem:e}, 2", - "jz 11f", - "10:", - "cmp {rem:e}, 1", - "jb 11f", - "mov {buf:l}, byte ptr [{src} + {rem} - 1]", - "mov byte ptr [{dest} + {rem} - 1], {buf:l}", - "11:", - src = in(reg) src, - dest = in(reg) dest, - rem = inout(reg) rem => _, -// tmp = out(reg) _, - buf = out(reg) _, - options(nostack), - ); - } - /* - unsafe { - core::arch::asm!( - "7:", - "cmp {rem:e}, 4", - "jb 8f", - "sub {rem:e}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jmp 7b", - "8:", - "test {rem:e}, {rem:e}", - "jz 10f", - "sub {rem:e}, 1", - "mov {buf:l}, byte ptr [{src} + {rem}]", - "mov byte ptr [{dest} + {rem}], {buf:l}", - "jnz 8b", - "10:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, -// tmp = out(reg) _, - buf = out(reg) _, - options(nostack), - ); - } - */ - /* - unsafe { - core::arch::asm!( - "mov {tmp}, {rem}", - "and {tmp}, 3", - "je 3f", - "sub {rem}, {tmp}", - "2:", - "mov {buf:l}, byte ptr [{src}]", - "mov byte ptr [{dest}], {buf:l}", - "add {src}, 1", - "add {dest}, 1", - "sub {tmp}, 1", - "jnz 2b", - "3:", - "test {rem}, {rem}", - "jz 5f", - "4:", - "sub {rem}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jnz 4b", - "5:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, - tmp = out(reg) _, - buf = out(reg) _, - ); - } - */ - /* - for i in 0..new_bytes.len() { - unsafe { - buf.as_mut_ptr().offset(buf.len() as isize).offset(i as isize).write_volatile(new_bytes[i]); - } - } - */ - } - } - fn danger_anguished_smaller_variable_length_bstring_write(buf: &mut alloc::vec::Vec<u8>, new_bytes: &[u8]) { - if new_bytes.len() >= 8 { - unsafe { core::hint::unreachable_unchecked() } - } - if new_bytes.len() == 0 { - unsafe { core::hint::unreachable_unchecked() } - } - - unsafe { - let dest = buf.as_mut_ptr().offset(buf.len() as isize); - let src = new_bytes.as_ptr(); - - let mut rem = new_bytes.len() as isize; - unsafe { - buf.set_len(buf.len() + new_bytes.len()); - } - /* - while rem % 4 > 0 { - dest.offset(rem - 1).write_unaligned(src.offset(rem - 1).read_unaligned()); - rem -= 1; - } - - while rem > 0 { - (dest.offset(rem - 4) as *mut u32).write_unaligned(unsafe { - *core::mem::transmute::<&u8, &u32>(&new_bytes[rem as usize - 4]) - }); - rem -= 4; - } - */ - unsafe { - /* - if rem >= 4 { - rem -= 4; - (dest.offset(rem as isize) as *mut u32).write_unaligned((src.offset(rem as isize) as *const u32).read_unaligned()); - if rem == 0 { - return; - } - } - if rem >= 2 { - rem -= 2; - (dest.offset(rem as isize) as *mut u16).write_unaligned((src.offset(rem as isize) as *const u16).read_unaligned()); - if rem == 0 { - return; - } - } - if rem >= 1 { - rem -= 1; - (dest.offset(rem as isize) as *mut u8).write_unaligned((src.offset(rem as isize) as *const u8).read_unaligned()) - } - */ - core::arch::asm!( - "8:", - "cmp {rem:e}, 4", - "jb 9f", - "mov {buf:e}, dword ptr [{src} + {rem} - 4]", - "mov dword ptr [{dest} + {rem} - 4], {buf:e}", - "sub {rem:e}, 4", - "jz 11f", - "9:", - "cmp {rem:e}, 2", - "jb 10f", - "mov {buf:x}, word ptr [{src} + {rem} - 2]", - "mov word ptr [{dest} + {rem} - 2], {buf:x}", - "sub {rem:e}, 2", - "jz 11f", - "10:", - "cmp {rem:e}, 1", - "jb 11f", - "mov {buf:l}, byte ptr [{src} + {rem} - 1]", - "mov byte ptr [{dest} + {rem} - 1], {buf:l}", - "11:", - src = in(reg) src, - dest = in(reg) dest, - rem = inout(reg) rem => _, -// tmp = out(reg) _, - buf = out(reg) _, - options(nostack), - ); - } - /* - unsafe { - core::arch::asm!( - "7:", - "cmp {rem:e}, 4", - "jb 8f", - "sub {rem:e}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jmp 7b", - "8:", - "test {rem:e}, {rem:e}", - "jz 10f", - "sub {rem:e}, 1", - "mov {buf:l}, byte ptr [{src} + {rem}]", - "mov byte ptr [{dest} + {rem}], {buf:l}", - "jnz 8b", - "10:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, -// tmp = out(reg) _, - buf = out(reg) _, - options(nostack), - ); - } - */ - /* - unsafe { - core::arch::asm!( - "mov {tmp}, {rem}", - "and {tmp}, 3", - "je 3f", - "sub {rem}, {tmp}", - "2:", - "mov {buf:l}, byte ptr [{src}]", - "mov byte ptr [{dest}], {buf:l}", - "add {src}, 1", - "add {dest}, 1", - "sub {tmp}, 1", - "jnz 2b", - "3:", - "test {rem}, {rem}", - "jz 5f", - "4:", - "sub {rem}, 4", - "mov {buf:e}, dword ptr [{src} + {rem}]", - "mov dword ptr [{dest} + {rem}], {buf:e}", - "jnz 4b", - "5:", - src = in(reg) src, - dest = in(reg) dest, - rem = in(reg) rem, - tmp = out(reg) _, - buf = out(reg) _, - ); - } - */ - /* - for i in 0..new_bytes.len() { - unsafe { - buf.as_mut_ptr().offset(buf.len() as isize).offset(i as isize).write_volatile(new_bytes[i]); - } - } - */ - } - } - - let address: u64 = 0; - let context = Some(&NoContext); - let colors = &NoColors; - if self.prefixes.rep_any() { - if self.xacquire() { - danger_anguished_string_write(out, "xacquire "); - } - if self.xrelease() { - danger_anguished_string_write(out, "xrelease "); - } - - if self.opcode.can_rep() { - if self.prefixes.rep() { - danger_anguished_string_write(out, "rep "); - } else if self.prefixes.repnz() { - danger_anguished_string_write(out, "repnz "); - } - } - } - - if self.prefixes.lock() { - danger_anguished_string_write(out, "lock "); - } - - use core::mem::MaybeUninit; - - danger_anguished_variable_length_string_write(out, self.opcode.name()); - - if self.operand_count > 0 { - danger_anguished_string_write(out, " "); - - let rel_res = { - let out = unsafe { core::mem::transmute::<&mut alloc::string::String, &mut BigEnoughString>(out) }; - self.visit_operand(0, &mut RelativeBranchPrinter { - inst: &self, - out: &mut NoColorsSink { - out: out, - }, - })? - }; - if rel_res { - return Ok(()); - } - - fn display_op<Y: YaxColors>(inst: &Instruction, op_nr: u8, colors: &Y, out: &mut alloc::string::String) -> fmt::Result { - struct OperandPrinter<'a, Y: YaxColors> { - out: &'a mut alloc::string::String, - op_nr: u8, - colors: &'a Y, - inst: &'a Instruction, - } - - impl<'a, Y: YaxColors> crate::long_mode::OperandVisitor for OperandPrinter<'a, Y> { - type Ok = (); - type Error = fmt::Error; - - #[cfg_attr(feature="profiling", inline(never))] - fn visit_reg(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error> { - let label = regspec_label(®); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); -// danger_anguished_variable_length_string_write(self.out, label); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); -// self.out.write_str(" ")?; - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_string_write(self.out, " "); - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); -// self.out.write_str(":")?; - danger_anguished_string_write(self.out, ":["); - } else { -// self.out.write_str("[")?; - danger_anguished_string_write(self.out, " ["); - } - let label = regspec_label(®); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); -// self.out.write_str("]") - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_string_write(self.out, " "); - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); - danger_anguished_string_write(self.out, ":["); - } else { - danger_anguished_string_write(self.out, " ["); - } - let label = regspec_label(®); - if label.len() < 2 { - unsafe { core::hint::unreachable_unchecked(); } - } - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - // write!(self.out, "{}", self.colors.number(signed_i32_hex(disp)))?; - let mut v = disp as u32; - if disp < 0 { - danger_anguished_string_write(self.out, " - 0x"); - v = -disp as u32; - } else { - danger_anguished_string_write(self.out, " + 0x"); - } - if v == 0 { - danger_anguished_string_write(self.out, "0"); - } else { - let lzcnt = v.leading_zeros(); - let mut digits = 8 - (lzcnt/8); - while digits > 0 { - let digit = (v >> (digits * 8)) & 0xf; - let c = c_to_hex(digit as u8); - danger_anguished_bstring_write(unsafe {self.out.as_mut_vec()}, &[c]); - digits -= 1; - } - } - /* - let mut buf = [MaybeUninit::<u8>::uninit(); 8]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - static CHARSET: &'static [u8; 16] = b"0123456789abcdef"; - let c = CHARSET[digit as usize]; - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_string_write(&mut self.out, s); - */ - danger_anguished_string_write(&mut self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_i8(&mut self, imm: i8) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u8; - if imm < 0 { - danger_anguished_string_write(&mut self.out, "-"); - v = -imm as u8; - } - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 2]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s: &str = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_string_write(&mut self.out, s); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_u8(&mut self, imm: u8) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u8; - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 2]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s: &str = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_string_write(&mut self.out, s); - Ok(()) - - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_i16(&mut self, imm: i16) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u16; - if imm < 0 { - danger_anguished_string_write(&mut self.out, "-"); - v = -imm as u16; - } - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 4]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s: &str = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - anguished_string_write(&mut self.out, s); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_u16(&mut self, imm: u16) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u32; - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 4]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - anguished_string_write(&mut self.out, s); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_i32(&mut self, imm: i32) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u32; - if imm < 0 { - danger_anguished_string_write(&mut self.out, "-"); - v = -imm as u32; - } - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 8]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - // danger_anguished_string_write(&mut self.out, s); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_u32(&mut self, imm: u32) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u32; - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 8]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - //danger_anguished_string_write(&mut self.out, s); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_i64(&mut self, imm: i64) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u32; - if imm < 0 { - danger_anguished_string_write(&mut self.out, "-"); - v = -imm as u32; - } - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 16]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - Ok(()) - - - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_u64(&mut self, imm: u64) -> Result<Self::Ok, Self::Error> { - let mut v = imm as u64; - danger_anguished_string_write(&mut self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 16]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_abs_u32(&mut self, imm: u32) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " [0x"); - let mut v = imm as u32; - let mut buf = [MaybeUninit::<u8>::uninit(); 16]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - // anguished_string_write(&mut self.out, s); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_abs_u64(&mut self, imm: u64) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " [0x"); - let mut v = imm as u64; - let mut buf = [MaybeUninit::<u8>::uninit(); 16]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - // anguished_string_write(&mut self.out, s); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " "); - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); - danger_anguished_string_write(self.out, ":"); - } - danger_anguished_string_write(self.out, "["); - let label = regspec_label(®); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " * "); - danger_anguished_bstring_write(unsafe { self.out.as_mut_vec() }, &[scale + b'0']); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " "); - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); - danger_anguished_string_write(self.out, ":"); - } - danger_anguished_string_write(self.out, "["); - let label = regspec_label(&base); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " + "); - let label = regspec_label(&index); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " * "); - danger_anguished_bstring_write(unsafe { self.out.as_mut_vec() }, &[scale + b'0']); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " "); - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); - danger_anguished_string_write(self.out, ":"); - } - danger_anguished_string_write(self.out, "["); - let label = regspec_label(®); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " * "); - danger_anguished_bstring_write(unsafe { self.out.as_mut_vec() }, &[scale + b'0']); - let mut v = disp as u32; - if disp < 0 { - danger_anguished_string_write(self.out, " - "); - v = -disp as u32; - } else { - danger_anguished_string_write(self.out, " + "); - } - danger_anguished_string_write(self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 8]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - // anguished_string_write(&mut self.out, s); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] - fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> { - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, mem_size_label(self.inst.mem_size).as_bytes()); - danger_anguished_string_write(self.out, " "); - - if self.op_nr >= 4 { - unsafe { core::hint::unreachable_unchecked(); } - } - if let Some(prefix) = self.inst.segment_override_for_op(self.op_nr) { - danger_anguished_bstring_write(unsafe{self.out.as_mut_vec()}, prefix.name()); - danger_anguished_string_write(self.out, ":"); - } - danger_anguished_string_write(self.out, "["); - let label = regspec_label(&base); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " + "); - let label = regspec_label(&index); - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, label.as_bytes()); - danger_anguished_string_write(self.out, " * "); - danger_anguished_bstring_write(unsafe { self.out.as_mut_vec() }, &[scale + b'0']); - let mut v = disp as u32; - if disp < 0 { - danger_anguished_string_write(self.out, " - "); - v = -disp as u32; - } else { - danger_anguished_string_write(self.out, " + "); - } - danger_anguished_string_write(self.out, "0x"); - let mut buf = [MaybeUninit::<u8>::uninit(); 8]; - let mut curr = buf.len(); - loop { - let digit = v % 16; - let c = c_to_hex(digit as u8); - curr -= 1; - buf[curr].write(c); - v = v / 16; - if v == 0 { - break; - } - } - let buf = &buf[curr..]; - let s = unsafe { - core::mem::transmute::<&[MaybeUninit<u8>], &str>(buf) - }; - danger_anguished_smaller_variable_length_bstring_write(unsafe { self.out.as_mut_vec() }, s.as_bytes()); - danger_anguished_string_write(self.out, "]"); - Ok(()) - } - fn visit_other(&mut self) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_mask_merge(&mut self, spec: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_mask_merge_sae(&mut self, spec: RegSpec, mask: RegSpec, merge_mode: MergeMode, sae_mode: crate::long_mode::SaeMode) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_mask_merge_sae_noround(&mut self, spec: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_deref_masked(&mut self, spec: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_scale_masked(&mut self, spec: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_reg_scale_disp_masked(&mut self, spec: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> { - Ok(()) - } - } - - let mut printer = OperandPrinter { - out, - inst, - op_nr, - colors, - }; - inst.visit_operand(op_nr, &mut printer) - } - - display_op(self, 0, colors, out)?; - - for i in 1..self.operand_count { - match self.opcode { - _ => { - match &self.operands[i as usize] { - &OperandSpec::Nothing => { - // should never see a Nothing if we iterate only through - // `operand_count`.. - unsafe { crate::long_mode::unreachable_unchecked() } - }, - _ => { - danger_anguished_string_write(out, ", "); - display_op(self, i, colors, out)?; - if let Some(evex) = self.prefixes.evex() { - if evex.broadcast() && false { // x.is_memory() { - let scale = if self.opcode == Opcode::VCVTPD2PS || self.opcode == Opcode::VCVTTPD2UDQ || self.opcode == Opcode::VCVTPD2UDQ || self.opcode == Opcode::VCVTUDQ2PD || self.opcode == Opcode::VCVTPS2PD || self.opcode == Opcode::VCVTQQ2PS || self.opcode == Opcode::VCVTDQ2PD || self.opcode == Opcode::VCVTTPD2DQ || self.opcode == Opcode::VFPCLASSPS || self.opcode == Opcode::VFPCLASSPD || self.opcode == Opcode::VCVTNEPS2BF16 || self.opcode == Opcode::VCVTUQQ2PS || self.opcode == Opcode::VCVTPD2DQ || self.opcode == Opcode::VCVTTPS2UQQ || self.opcode == Opcode::VCVTPS2UQQ || self.opcode == Opcode::VCVTTPS2QQ || self.opcode == Opcode::VCVTPS2QQ { - if self.opcode == Opcode::VFPCLASSPS || self.opcode == Opcode::VCVTNEPS2BF16 { - if evex.vex().l() { - 8 - } else if evex.lp() { - 16 - } else { - 4 - } - } else if self.opcode == Opcode::VFPCLASSPD { - if evex.vex().l() { - 4 - } else if evex.lp() { - 8 - } else { - 2 - } - } else { - // vcvtpd2ps is "cool": in broadcast mode, it can read a - // double-precision float (qword), resize to single-precision, - // then broadcast that to the whole destination register. this - // means we need to show `xmm, qword [addr]{1to4}` if vector - // size is 256. likewise, scale of 8 for the same truncation - // reason if vector size is 512. - // vcvtudq2pd is the same story. - // vfpclassp{s,d} is a mystery to me. - if evex.vex().l() { - 4 - } else if evex.lp() { - 8 - } else { - 2 - } - } - } else { - // this should never be `None` - that would imply two - // memory operands for a broadcasted operation. - if let Some(width) = Operand::from_spec(self, self.operands[i as usize - 1]).width() { - width / self.mem_size - } else { - 0 - } - }; - write!(out, "{{1to{}}}", scale)?; - } - } - } - } - } - } - } - } - Ok(()) - } - #[cfg_attr(feature="profiling", inline(never))] pub fn write_to<T: DisplaySink>(&self, out: &mut T) -> fmt::Result { contextualize_intel(self, out) |