aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2024-06-18 14:10:32 -0700
committeriximeow <me@iximeow.net>2024-06-18 14:10:32 -0700
commit4142a4a16b62ce9f80d796e930518c169c52d587 (patch)
tree3feea5634bfad58f2b41abd22f5221b7507c75ef
parent758ddc604b6300c48ae14dbdc8d48720124658f2 (diff)
move non-avx512 operand printing away from fmt
-rw-r--r--src/long_mode/display.rs106
1 files changed, 85 insertions, 21 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 0e09173..46227fb 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -1284,10 +1284,13 @@ impl <T: DisplaySink, Y: YaxColors> crate::long_mode::OperandVisitor for Coloriz
self.f.write_char(name[1] as char)?;
self.f.write_char(':')?;
}
- write!(self.f, "[{} * {}]",
- regspec_label(&reg),
- self.colors.number(scale)
- )
+ self.f.write_fixed_size("[")?;
+ unsafe { self.f.write_lt_8(regspec_label(&reg))?; }
+ self.f.write_fixed_size(" * ")?;
+ self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
+ self.f.write_fixed_size("]")?;
+
+ Ok(())
}
fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_str(MEM_SIZE_STRINGS[self.instr.mem_size as usize])?;
@@ -1298,11 +1301,40 @@ impl <T: DisplaySink, Y: YaxColors> crate::long_mode::OperandVisitor for Coloriz
self.f.write_char(name[1] as char)?;
self.f.write_char(':')?;
}
- write!(self.f, "[{} * {} ",
- regspec_label(&reg),
- self.colors.number(scale),
- )?;
- format_number_i32(self.colors, self.f, disp, NumberStyleHint::HexSignedWithSignSplit)?;
+ self.f.write_fixed_size("[")?;
+ unsafe { self.f.write_lt_8(regspec_label(&reg))?; }
+ self.f.write_fixed_size(" * ")?;
+ self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
+ self.f.write_fixed_size(" ")?;
+
+ {
+ let mut v = disp as u32;
+ if disp < 0 {
+ self.f.write_fixed_size("- 0x")?;
+ v = -disp as u32;
+ } else {
+ self.f.write_fixed_size("+ 0x")?;
+ }
+ let mut buf = [core::mem::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::<&[core::mem::MaybeUninit<u8>], &str>(buf)
+ };
+
+ // not actually fixed size, but this should optimize right i hope..
+ self.f.write_fixed_size(s)?;
+ }
write!(self.f, "]")
}
fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
@@ -1314,11 +1346,13 @@ impl <T: DisplaySink, Y: YaxColors> crate::long_mode::OperandVisitor for Coloriz
self.f.write_char(name[1] as char)?;
self.f.write_char(':')?;
}
- write!(self.f, "[{} + {} * {}]",
- regspec_label(&base),
- regspec_label(&index),
- self.colors.number(scale)
- )
+ 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))?; }
+ self.f.write_fixed_size(" * ")?;
+ self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
+ self.f.write_fixed_size("]")
}
fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_str(MEM_SIZE_STRINGS[self.instr.mem_size as usize])?;
@@ -1329,13 +1363,43 @@ impl <T: DisplaySink, Y: YaxColors> crate::long_mode::OperandVisitor for Coloriz
self.f.write_char(name[1] as char)?;
self.f.write_char(':')?;
}
- write!(self.f, "[{} + {} * {} ",
- regspec_label(&base),
- regspec_label(&index),
- self.colors.number(scale),
- )?;
- format_number_i32(self.colors, self.f, disp, NumberStyleHint::HexSignedWithSignSplit)?;
- write!(self.f, "]")
+ 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))?; }
+ self.f.write_fixed_size(" * ")?;
+ self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
+ self.f.write_fixed_size(" ")?;
+
+ {
+ let mut v = disp as u32;
+ if disp < 0 {
+ self.f.write_fixed_size("- 0x")?;
+ v = -disp as u32;
+ } else {
+ self.f.write_fixed_size("+ 0x")?;
+ }
+ let mut buf = [core::mem::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::<&[core::mem::MaybeUninit<u8>], &str>(buf)
+ };
+
+ // not actually fixed size, but this should optimize right i hope..
+ self.f.write_fixed_size(s)?;
+ }
+ self.f.write_fixed_size("]")
}
fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_str(MEM_SIZE_STRINGS[self.instr.mem_size as usize])?;