use write instead of format
Decreases fuzz time from 183s to 72s.
This commit is contained in:
parent
7d2b8c16ca
commit
a94ee22d14
|
@ -88,8 +88,11 @@ impl Fuzzer {
|
||||||
let counter = Arc::clone(&self.counter);
|
let counter = Arc::clone(&self.counter);
|
||||||
let range = self.range.clone();
|
let range = self.range.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
let mut buf = String::with_capacity(1024);
|
||||||
for x in range.clone() {
|
for x in range.clone() {
|
||||||
black_box(Ins::disasm(x).to_string());
|
let ins = Ins::disasm(x);
|
||||||
|
ins.write_string(&mut buf).unwrap();
|
||||||
|
black_box(&buf);
|
||||||
if x % (1 << 19) == 0 {
|
if x % (1 << 19) == 0 {
|
||||||
counter.store(x, Ordering::Relaxed);
|
counter.store(x, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
379
lib/src/lib.rs
379
lib/src/lib.rs
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::Write;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use num_traits::AsPrimitive;
|
use num_traits::AsPrimitive;
|
||||||
|
@ -1309,7 +1310,7 @@ impl Ins {
|
||||||
ins
|
ins
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg123(&self) -> String {
|
fn write_string_form_reg123(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Eciwx => "eciwx",
|
Opcode::Eciwx => "eciwx",
|
||||||
Opcode::Ecowx => "ecowx",
|
Opcode::Ecowx => "ecowx",
|
||||||
|
@ -1337,10 +1338,10 @@ impl Ins {
|
||||||
Opcode::Stwux => "stwux",
|
Opcode::Stwux => "stwux",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
write!(out, "{} r{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg123_rc(&self) -> String {
|
fn write_string_form_reg123_rc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::And => "and",
|
Opcode::And => "and",
|
||||||
|
@ -1350,7 +1351,8 @@ impl Ins {
|
||||||
Opcode::Xor => "xor",
|
Opcode::Xor => "xor",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} r{}, r{}, r{}",
|
"{}{} r{}, r{}, r{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1360,7 +1362,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg123_oe_rc(&self) -> String {
|
fn write_string_form_reg123_oe_rc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = match (self.oe(), self.rc()) {
|
let name_suffix = match (self.oe(), self.rc()) {
|
||||||
(false, false) => "",
|
(false, false) => "",
|
||||||
(false, true) => ".",
|
(false, true) => ".",
|
||||||
|
@ -1379,7 +1381,8 @@ impl Ins {
|
||||||
Opcode::Subfe => "subfe",
|
Opcode::Subfe => "subfe",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} r{}, r{}, r{}",
|
"{}{} r{}, r{}, r{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1389,8 +1392,8 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_noargs(&self) -> String {
|
fn write_string_noargs(&self, out: &mut String) -> std::fmt::Result {
|
||||||
match self.op {
|
*out = match self.op {
|
||||||
Opcode::Eieio => "eieio",
|
Opcode::Eieio => "eieio",
|
||||||
Opcode::Isync => "isync",
|
Opcode::Isync => "isync",
|
||||||
Opcode::Rfi => "rfi",
|
Opcode::Rfi => "rfi",
|
||||||
|
@ -1398,11 +1401,11 @@ impl Ins {
|
||||||
Opcode::Sync => "sync",
|
Opcode::Sync => "sync",
|
||||||
Opcode::Tlbsync => "tlbsync",
|
Opcode::Tlbsync => "tlbsync",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
}
|
}.to_owned();
|
||||||
.to_owned()
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg12_simm(&self) -> String {
|
fn write_string_form_reg12_simm(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Addi => "addi",
|
Opcode::Addi => "addi",
|
||||||
Opcode::Addic => "addic",
|
Opcode::Addic => "addic",
|
||||||
|
@ -1412,10 +1415,17 @@ impl Ins {
|
||||||
Opcode::Subfic => "subfic",
|
Opcode::Subfic => "subfic",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}, {}", name, self.d(), self.a(), self.simm())
|
write!(
|
||||||
|
out,
|
||||||
|
"{} r{}, r{}, {}",
|
||||||
|
name,
|
||||||
|
self.d(),
|
||||||
|
self.a(),
|
||||||
|
self.simm()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg12_uimm(&self) -> String {
|
fn write_string_form_reg12_uimm(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Andi_ => "andi.",
|
Opcode::Andi_ => "andi.",
|
||||||
Opcode::Andis_ => "andis.",
|
Opcode::Andis_ => "andis.",
|
||||||
|
@ -1425,10 +1435,17 @@ impl Ins {
|
||||||
Opcode::Xoris => "xoris",
|
Opcode::Xoris => "xoris",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}, {}", name, self.d(), self.a(), self.uimm())
|
write!(
|
||||||
|
out,
|
||||||
|
"{} r{}, r{}, {}",
|
||||||
|
name,
|
||||||
|
self.d(),
|
||||||
|
self.a(),
|
||||||
|
self.uimm()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg12_offset(&self) -> String {
|
fn write_string_form_reg12_offset(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Lha => "lha",
|
Opcode::Lha => "lha",
|
||||||
Opcode::Lhau => "lhau",
|
Opcode::Lhau => "lhau",
|
||||||
|
@ -1448,10 +1465,17 @@ impl Ins {
|
||||||
Opcode::Stwu => "stwu",
|
Opcode::Stwu => "stwu",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, {}(r{})", name, self.d(), self.simm(), self.a())
|
write!(
|
||||||
|
out,
|
||||||
|
"{} r{}, {}(r{})",
|
||||||
|
name,
|
||||||
|
self.d(),
|
||||||
|
self.simm(),
|
||||||
|
self.a()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr1_reg2_offset(&self) -> String {
|
fn write_string_form_fr1_reg2_offset(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Lfd => "lfd",
|
Opcode::Lfd => "lfd",
|
||||||
Opcode::Lfdu => "lfdu",
|
Opcode::Lfdu => "lfdu",
|
||||||
|
@ -1463,10 +1487,17 @@ impl Ins {
|
||||||
Opcode::Stfsu => "stfsu",
|
Opcode::Stfsu => "stfsu",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} fr{}, {}(r{})", name, self.d(), self.simm(), self.a())
|
write!(
|
||||||
|
out,
|
||||||
|
"{} fr{}, {}(r{})",
|
||||||
|
name,
|
||||||
|
self.d(),
|
||||||
|
self.simm(),
|
||||||
|
self.a()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr1_reg23(&self) -> String {
|
fn write_string_form_fr1_reg23(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Lfdux => "lfdux",
|
Opcode::Lfdux => "lfdux",
|
||||||
Opcode::Lfdx => "lfdx",
|
Opcode::Lfdx => "lfdx",
|
||||||
|
@ -1479,23 +1510,24 @@ impl Ins {
|
||||||
Opcode::Stfsx => "stfsx",
|
Opcode::Stfsx => "stfsx",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} fr{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
write!(out, "{} fr{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_mtfsf(&self) -> String {
|
fn write_string_mtfsf(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mtfsf => "mtfsf",
|
Opcode::Mtfsf => "mtfsf",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} {}, fr{}", name, self.fm(), self.b())
|
write!(out, "{} {}, fr{}", name, self.fm(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_mtfsfi(&self) -> String {
|
fn write_string_mtfsfi(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mtfsfi => "mtfsfi",
|
Opcode::Mtfsfi => "mtfsfi",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crf{}, {}",
|
"{} crf{}, {}",
|
||||||
name,
|
name,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
|
@ -1503,7 +1535,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg1(&self) -> String {
|
fn write_string_form_reg1(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mfcr => "mfcr",
|
Opcode::Mfcr => "mfcr",
|
||||||
Opcode::Mfmsr => "mfmsr",
|
Opcode::Mfmsr => "mfmsr",
|
||||||
|
@ -1511,10 +1543,10 @@ impl Ins {
|
||||||
Opcode::Tlbie => "tblie",
|
Opcode::Tlbie => "tblie",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}", name, self.d())
|
write!(out, "{} r{}", name, self.d())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg12_oe_rc(&self) -> String {
|
fn write_string_form_reg12_oe_rc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = match (self.oe(), self.rc()) {
|
let name_suffix = match (self.oe(), self.rc()) {
|
||||||
(false, false) => "",
|
(false, false) => "",
|
||||||
(false, true) => ".",
|
(false, true) => ".",
|
||||||
|
@ -1529,19 +1561,19 @@ impl Ins {
|
||||||
Opcode::Subfze => "subfze",
|
Opcode::Subfze => "subfze",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{}{} r{}, r{}", name, name_suffix, self.d(), self.a())
|
write!(out, "{}{} r{}, r{}", name, name_suffix, self.d(), self.a())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg13(&self) -> String {
|
fn write_string_form_reg13(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mfsrin => "mfsrin",
|
Opcode::Mfsrin => "mfsrin",
|
||||||
Opcode::Mtsrin => "mtsrin",
|
Opcode::Mtsrin => "mtsrin",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}", name, self.d(), self.b())
|
write!(out, "{} r{}, r{}", name, self.d(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg21_rc(&self) -> String {
|
fn write_string_form_reg21_rc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Cntlzw => "cntlzw",
|
Opcode::Cntlzw => "cntlzw",
|
||||||
|
@ -1549,10 +1581,10 @@ impl Ins {
|
||||||
Opcode::Extsh => "extsh",
|
Opcode::Extsh => "extsh",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{}{} r{}, r{}", name, name_suffix, self.a(), self.s())
|
write!(out, "{}{} r{}, r{}", name, name_suffix, self.a(), self.s())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr1(&self) -> String {
|
fn write_string_form_fr1(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mffs => match self.rc() {
|
Opcode::Mffs => match self.rc() {
|
||||||
false => "mffs",
|
false => "mffs",
|
||||||
|
@ -1560,10 +1592,10 @@ impl Ins {
|
||||||
},
|
},
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} fr{}", name, self.d())
|
write!(out, "{} fr{}", name, self.d())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr13(&self) -> String {
|
fn write_string_form_fr13(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fabs => "fabs",
|
Opcode::Fabs => "fabs",
|
||||||
|
@ -1583,10 +1615,17 @@ impl Ins {
|
||||||
Opcode::PsSum1 => "ps_sum1",
|
Opcode::PsSum1 => "ps_sum1",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{}{} fr{}, fr{}", name, name_suffix, self.d(), self.b())
|
write!(
|
||||||
|
out,
|
||||||
|
"{}{} fr{}, fr{}",
|
||||||
|
name,
|
||||||
|
name_suffix,
|
||||||
|
self.d(),
|
||||||
|
self.b()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr123(&self) -> String {
|
fn write_string_form_fr123(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fadd => "fadd",
|
Opcode::Fadd => "fadd",
|
||||||
|
@ -1604,7 +1643,8 @@ impl Ins {
|
||||||
Opcode::PsSub => "ps_sub",
|
Opcode::PsSub => "ps_sub",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1614,7 +1654,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr1243(&self) -> String {
|
fn write_string_form_fr1243(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fmadd => "fmadd",
|
Opcode::Fmadd => "fmadd",
|
||||||
|
@ -1637,7 +1677,8 @@ impl Ins {
|
||||||
Opcode::PsSum1 => "ps_sum1",
|
Opcode::PsSum1 => "ps_sum1",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}, fr{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1648,7 +1689,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_fr124(&self) -> String {
|
fn write_string_form_fr124(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fmul => "fmul",
|
Opcode::Fmul => "fmul",
|
||||||
|
@ -1658,7 +1699,8 @@ impl Ins {
|
||||||
Opcode::PsMuls1 => "ps_muls1",
|
Opcode::PsMuls1 => "ps_muls1",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1668,7 +1710,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_condreg1_fr23(&self) -> String {
|
fn write_string_form_condreg1_fr23(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fcmpo => "fcmpo",
|
Opcode::Fcmpo => "fcmpo",
|
||||||
Opcode::Fcmpu => "fcmpu",
|
Opcode::Fcmpu => "fcmpu",
|
||||||
|
@ -1678,7 +1720,8 @@ impl Ins {
|
||||||
Opcode::PsCmpu1 => "ps_cmpu1",
|
Opcode::PsCmpu1 => "ps_cmpu1",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crf{}, fr{}, fr{}",
|
"{} crf{}, fr{}, fr{}",
|
||||||
name,
|
name,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
|
@ -1687,14 +1730,15 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_condreg1_fr13_rc(&self) -> String {
|
fn write_string_form_condreg1_fr13_rc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Fctiw => "fctiw",
|
Opcode::Fctiw => "fctiw",
|
||||||
Opcode::Fctiwz => "fctiwz",
|
Opcode::Fctiwz => "fctiwz",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} crf{}, fr{}, fr{}",
|
"{}{} crf{}, fr{}, fr{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1704,7 +1748,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_b(&self) -> String {
|
fn write_string_b(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match (self.aa(), self.lk()) {
|
let name = match (self.aa(), self.lk()) {
|
||||||
(false, false) => "b",
|
(false, false) => "b",
|
||||||
(false, true) => "bl",
|
(false, true) => "bl",
|
||||||
|
@ -1712,10 +1756,10 @@ impl Ins {
|
||||||
(true, true) => "bla",
|
(true, true) => "bla",
|
||||||
};
|
};
|
||||||
// TODO absolute address
|
// TODO absolute address
|
||||||
format!("{} 0x{:x}", name, self.li())
|
write!(out, "{} 0x{:x}", name, self.li())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_bc(&self) -> String {
|
fn write_string_bc(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match (self.aa(), self.lk()) {
|
let name = match (self.aa(), self.lk()) {
|
||||||
(false, false) => "bc",
|
(false, false) => "bc",
|
||||||
(false, true) => "bcl",
|
(false, true) => "bcl",
|
||||||
|
@ -1723,7 +1767,8 @@ impl Ins {
|
||||||
(true, true) => "bcla",
|
(true, true) => "bcla",
|
||||||
};
|
};
|
||||||
// TODO absolute address
|
// TODO absolute address
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} 0x{:x}, 0x{:x}, 0x{:x}",
|
"{} 0x{:x}, 0x{:x}, 0x{:x}",
|
||||||
name,
|
name,
|
||||||
self.bo(),
|
self.bo(),
|
||||||
|
@ -1732,7 +1777,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_branch_cond_to_reg(&self) -> String {
|
fn write_string_branch_cond_to_reg(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Bcctr => match self.lk() {
|
Opcode::Bcctr => match self.lk() {
|
||||||
false => "bcctr",
|
false => "bcctr",
|
||||||
|
@ -1744,16 +1789,17 @@ impl Ins {
|
||||||
},
|
},
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} 0x{:x}, 0x{:x}", name, self.bo(), self.bi())
|
write!(out, "{} 0x{:x}, 0x{:x}", name, self.bo(), self.bi())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_cmp(&self) -> String {
|
fn write_string_cmp(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Cmp => "cmp",
|
Opcode::Cmp => "cmp",
|
||||||
Opcode::Cmpl => "cmpl",
|
Opcode::Cmpl => "cmpl",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crf{}, {}, r{}, r{}",
|
"{} crf{}, {}, r{}, r{}",
|
||||||
name,
|
name,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
|
@ -1763,9 +1809,10 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_cmp_simm(&self) -> String {
|
fn write_string_cmp_simm(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = "cmpi";
|
let name = "cmpi";
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crf{}, {}, r{}, {}",
|
"{} crf{}, {}, r{}, {}",
|
||||||
name,
|
name,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
|
@ -1775,9 +1822,10 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_cmp_uimm(&self) -> String {
|
fn write_string_cmp_uimm(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = "cmpli";
|
let name = "cmpli";
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crf{}, {}, r{}, {}",
|
"{} crf{}, {}, r{}, {}",
|
||||||
name,
|
name,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
|
@ -1787,7 +1835,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_condreg1(&self) -> String {
|
fn write_string_form_condreg1(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mcrxr => "mcrxr",
|
Opcode::Mcrxr => "mcrxr",
|
||||||
Opcode::Mtfsb0 => match self.rc() {
|
Opcode::Mtfsb0 => match self.rc() {
|
||||||
|
@ -1800,19 +1848,19 @@ impl Ins {
|
||||||
},
|
},
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} crf{}", name, self.crf_d())
|
write!(out, "{} crf{}", name, self.crf_d())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_condreg12(&self) -> String {
|
fn write_string_form_condreg12(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mcrf => "mcrf",
|
Opcode::Mcrf => "mcrf",
|
||||||
Opcode::Mcrfs => "mcrfs",
|
Opcode::Mcrfs => "mcrfs",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} crf{}, crf{}", name, self.crf_d(), self.crf_s())
|
write!(out, "{} crf{}, crf{}", name, self.crf_d(), self.crf_s())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_condreg123(&self) -> String {
|
fn write_string_form_condreg123(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Crand => "crand",
|
Opcode::Crand => "crand",
|
||||||
Opcode::Crandc => "crandc",
|
Opcode::Crandc => "crandc",
|
||||||
|
@ -1824,7 +1872,8 @@ impl Ins {
|
||||||
Opcode::Crxor => "crxor",
|
Opcode::Crxor => "crxor",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} crb{}, crb{}, crb{}",
|
"{} crb{}, crb{}, crb{}",
|
||||||
name,
|
name,
|
||||||
self.crb_d(),
|
self.crb_d(),
|
||||||
|
@ -1833,7 +1882,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg23(&self) -> String {
|
fn write_string_form_reg23(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Dcbf => "dcbf",
|
Opcode::Dcbf => "dcbf",
|
||||||
Opcode::Dcbi => "dcbi",
|
Opcode::Dcbi => "dcbi",
|
||||||
|
@ -1845,10 +1894,10 @@ impl Ins {
|
||||||
Opcode::Icbi => "icbi",
|
Opcode::Icbi => "icbi",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}", name, self.a(), self.b())
|
write!(out, "{} r{}, r{}", name, self.a(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg213(&self) -> String {
|
fn write_string_form_reg213(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Eqv => "eqv",
|
Opcode::Eqv => "eqv",
|
||||||
|
@ -1861,7 +1910,8 @@ impl Ins {
|
||||||
Opcode::Srw => "srw",
|
Opcode::Srw => "srw",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} r{}, r{}, r{}",
|
"{}{} r{}, r{}, r{}",
|
||||||
name,
|
name,
|
||||||
name_suffix,
|
name_suffix,
|
||||||
|
@ -1871,14 +1921,15 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_rlw_imm(&self) -> String {
|
fn write_string_rlw_imm(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name_prefix = if self.rc() { "." } else { "" };
|
let name_prefix = if self.rc() { "." } else { "" };
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Rlwimi => "rlwimi",
|
Opcode::Rlwimi => "rlwimi",
|
||||||
Opcode::Rlwinm => "rlwinm",
|
Opcode::Rlwinm => "rlwinm",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{}{} r{}, r{}, {}, {}, {}",
|
"{}{} r{}, r{}, {}, {}, {}",
|
||||||
name,
|
name,
|
||||||
name_prefix,
|
name_prefix,
|
||||||
|
@ -1890,10 +1941,11 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_rlw_reg(&self) -> String {
|
fn write_string_rlw_reg(&self, out: &mut String) -> std::fmt::Result {
|
||||||
assert_eq!(self.op, Opcode::Rlwnm);
|
assert_eq!(self.op, Opcode::Rlwnm);
|
||||||
let name_prefix = if self.rc() { "." } else { "" };
|
let name_prefix = if self.rc() { "." } else { "" };
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"rlwnm{} r{}, r{}, r{}, {}, {}",
|
"rlwnm{} r{}, r{}, r{}, {}, {}",
|
||||||
name_prefix,
|
name_prefix,
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -1904,54 +1956,77 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg12_nb(&self) -> String {
|
fn write_string_form_reg12_nb(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Lswi => "lswi",
|
Opcode::Lswi => "lswi",
|
||||||
Opcode::Stswi => "stswi",
|
Opcode::Stswi => "stswi",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, r{}, {}", name, self.d(), self.a(), self.b())
|
write!(out, "{} r{}, r{}, {}", name, self.d(), self.a(), self.b())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg1_spr(&self) -> String {
|
fn write_string_form_reg1_spr(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mfspr => "mfspr",
|
Opcode::Mfspr => "mfspr",
|
||||||
Opcode::Mftb => "mftb",
|
Opcode::Mftb => "mftb",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, {}", name, self.d(), self.spr())
|
write!(out, "{} r{}, {}", name, self.d(), self.spr())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_spr_reg1(&self) -> String {
|
fn write_string_form_spr_reg1(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mtspr => "mtspr",
|
Opcode::Mtspr => "mtspr",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} {}, r{}", name, self.spr(), self.s())
|
write!(out, "{} {}, r{}", name, self.spr(), self.s())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_reg1_sr(&self) -> String {
|
fn write_string_form_reg1_sr(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mfsr => "mfsr",
|
Opcode::Mfsr => "mfsr",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} r{}, {}", name, self.d(), self.sr())
|
write!(out, "{} r{}, {}", name, self.d(), self.sr())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_form_sr_reg1(&self) -> String {
|
fn write_string_form_sr_reg1(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::Mtsr => "mtsr",
|
Opcode::Mtsr => "mtsr",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!("{} {}, r{}", name, self.sr(), self.s())
|
write!(out, "{} {}, r{}", name, self.sr(), self.s())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_mtcrf(&self) -> String {
|
fn write_string_mtcrf(&self, out: &mut String) -> std::fmt::Result {
|
||||||
assert_eq!(self.op, Opcode::Mtcrf);
|
assert_eq!(self.op, Opcode::Mtcrf);
|
||||||
format!("mtcrf {} r{}", self.crm(), self.s())
|
write!(out, "mtcrf {} r{}", self.crm(), self.s())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_psq(&self) -> String {
|
fn write_string_srawi(&self, out: &mut String) -> std::fmt::Result {
|
||||||
|
assert_eq!(self.op, Opcode::Srawi);
|
||||||
|
let name_suffix = if self.rc() { "." } else { "" };
|
||||||
|
write!(
|
||||||
|
out,
|
||||||
|
"srawi{} r{}, r{}, {}",
|
||||||
|
name_suffix,
|
||||||
|
self.s(),
|
||||||
|
self.a(),
|
||||||
|
self.sh()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string_tw(&self, out: &mut String) -> std::fmt::Result {
|
||||||
|
assert_eq!(self.op, Opcode::Tw);
|
||||||
|
write!(out, "tw {}, r{}, r{}", self.to(), self.a(), self.b())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string_twi(&self, out: &mut String) -> std::fmt::Result {
|
||||||
|
assert_eq!(self.op, Opcode::Twi);
|
||||||
|
write!(out, "twi {}, r{}, {}", self.to(), self.a(), self.simm())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string_psq(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::PsqL => "psq_l",
|
Opcode::PsqL => "psq_l",
|
||||||
Opcode::PsqLu => "psq_lu",
|
Opcode::PsqLu => "psq_lu",
|
||||||
|
@ -1959,7 +2034,8 @@ impl Ins {
|
||||||
Opcode::PsqStu => "psq_stu",
|
Opcode::PsqStu => "psq_stu",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} fr{}, {}(r{}), {}, {}",
|
"{} fr{}, {}(r{}), {}, {}",
|
||||||
name,
|
name,
|
||||||
self.d(),
|
self.d(),
|
||||||
|
@ -1970,7 +2046,7 @@ impl Ins {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string_psq_x(&self) -> String {
|
fn write_string_psq_x(&self, out: &mut String) -> std::fmt::Result {
|
||||||
let name = match self.op {
|
let name = match self.op {
|
||||||
Opcode::PsqLx => "psq_lx",
|
Opcode::PsqLx => "psq_lx",
|
||||||
Opcode::PsqLux => "psq_lux",
|
Opcode::PsqLux => "psq_lux",
|
||||||
|
@ -1978,7 +2054,8 @@ impl Ins {
|
||||||
Opcode::PsqStux => "psq_stux",
|
Opcode::PsqStux => "psq_stux",
|
||||||
_ => disasm_unreachable!(self.code),
|
_ => disasm_unreachable!(self.code),
|
||||||
};
|
};
|
||||||
format!(
|
write!(
|
||||||
|
out,
|
||||||
"{} fr{}, r{}, r{}, {}, {}",
|
"{} fr{}, r{}, r{}, {}, {}",
|
||||||
name,
|
name,
|
||||||
self.d(),
|
self.d(),
|
||||||
|
@ -1988,12 +2065,10 @@ impl Ins {
|
||||||
self.ps_l()
|
self.ps_l()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for Ins {
|
pub fn write_string(&self, out: &mut String) -> std::fmt::Result {
|
||||||
fn to_string(&self) -> String {
|
|
||||||
match self.op {
|
match self.op {
|
||||||
Opcode::Illegal => "<illegal>".to_string(),
|
Opcode::Illegal => write!(out, "<illegal>"),
|
||||||
|
|
||||||
// Standalone instructions
|
// Standalone instructions
|
||||||
Opcode::Eieio
|
Opcode::Eieio
|
||||||
|
@ -2001,17 +2076,17 @@ impl ToString for Ins {
|
||||||
| Opcode::Rfi
|
| Opcode::Rfi
|
||||||
| Opcode::Sc
|
| Opcode::Sc
|
||||||
| Opcode::Sync
|
| Opcode::Sync
|
||||||
| Opcode::Tlbsync => self.to_string_noargs(),
|
| Opcode::Tlbsync => self.write_string_noargs(out),
|
||||||
|
|
||||||
// General purpose register only
|
// General purpose register only
|
||||||
Opcode::Mfcr | Opcode::Mfmsr | Opcode::Mtmsr | Opcode::Tlbie => {
|
Opcode::Mfcr | Opcode::Mfmsr | Opcode::Mtmsr | Opcode::Tlbie => {
|
||||||
self.to_string_form_reg1()
|
self.write_string_form_reg1(out)
|
||||||
}
|
}
|
||||||
Opcode::Addme | Opcode::Addze | Opcode::Neg | Opcode::Subfme | Opcode::Subfze => {
|
Opcode::Addme | Opcode::Addze | Opcode::Neg | Opcode::Subfme | Opcode::Subfze => {
|
||||||
self.to_string_form_reg12_oe_rc()
|
self.write_string_form_reg12_oe_rc(out)
|
||||||
}
|
}
|
||||||
Opcode::Mfsrin | Opcode::Mtsrin => self.to_string_form_reg13(),
|
Opcode::Mfsrin | Opcode::Mtsrin => self.write_string_form_reg13(out),
|
||||||
Opcode::Cntlzw | Opcode::Extsb | Opcode::Extsh => self.to_string_form_reg21_rc(),
|
Opcode::Cntlzw | Opcode::Extsb | Opcode::Extsh => self.write_string_form_reg21_rc(out),
|
||||||
Opcode::Dcbf
|
Opcode::Dcbf
|
||||||
| Opcode::Dcbi
|
| Opcode::Dcbi
|
||||||
| Opcode::Dcbst
|
| Opcode::Dcbst
|
||||||
|
@ -2019,7 +2094,7 @@ impl ToString for Ins {
|
||||||
| Opcode::Dcbtst
|
| Opcode::Dcbtst
|
||||||
| Opcode::Dcbz
|
| Opcode::Dcbz
|
||||||
| Opcode::DcbzL
|
| Opcode::DcbzL
|
||||||
| Opcode::Icbi => self.to_string_form_reg23(),
|
| Opcode::Icbi => self.write_string_form_reg23(out),
|
||||||
Opcode::Eciwx
|
Opcode::Eciwx
|
||||||
| Opcode::Ecowx
|
| Opcode::Ecowx
|
||||||
| Opcode::Lhaux
|
| Opcode::Lhaux
|
||||||
|
@ -2043,9 +2118,9 @@ impl ToString for Ins {
|
||||||
| Opcode::Stwbrx
|
| Opcode::Stwbrx
|
||||||
| Opcode::Stwcx_
|
| Opcode::Stwcx_
|
||||||
| Opcode::Stwx
|
| Opcode::Stwx
|
||||||
| Opcode::Stwux => self.to_string_form_reg123(),
|
| Opcode::Stwux => self.write_string_form_reg123(out),
|
||||||
Opcode::And | Opcode::Andc | Opcode::Mulhw | Opcode::Mulhwu | Opcode::Xor => {
|
Opcode::And | Opcode::Andc | Opcode::Mulhw | Opcode::Mulhwu | Opcode::Xor => {
|
||||||
self.to_string_form_reg123_rc()
|
self.write_string_form_reg123_rc(out)
|
||||||
}
|
}
|
||||||
Opcode::Add
|
Opcode::Add
|
||||||
| Opcode::Addc
|
| Opcode::Addc
|
||||||
|
@ -2055,7 +2130,7 @@ impl ToString for Ins {
|
||||||
| Opcode::Mullw
|
| Opcode::Mullw
|
||||||
| Opcode::Subf
|
| Opcode::Subf
|
||||||
| Opcode::Subfc
|
| Opcode::Subfc
|
||||||
| Opcode::Subfe => self.to_string_form_reg123_oe_rc(),
|
| Opcode::Subfe => self.write_string_form_reg123_oe_rc(out),
|
||||||
Opcode::Eqv
|
Opcode::Eqv
|
||||||
| Opcode::Nand
|
| Opcode::Nand
|
||||||
| Opcode::Nor
|
| Opcode::Nor
|
||||||
|
@ -2063,11 +2138,11 @@ impl ToString for Ins {
|
||||||
| Opcode::Orc
|
| Opcode::Orc
|
||||||
| Opcode::Slw
|
| Opcode::Slw
|
||||||
| Opcode::Sraw
|
| Opcode::Sraw
|
||||||
| Opcode::Srw => self.to_string_form_reg213(),
|
| Opcode::Srw => self.write_string_form_reg213(out),
|
||||||
|
|
||||||
// General purpose shifts
|
// General purpose shifts
|
||||||
Opcode::Rlwimi | Opcode::Rlwinm => self.to_string_rlw_imm(),
|
Opcode::Rlwimi | Opcode::Rlwinm => self.write_string_rlw_imm(out),
|
||||||
Opcode::Rlwnm => self.to_string_rlw_reg(),
|
Opcode::Rlwnm => self.write_string_rlw_reg(out),
|
||||||
|
|
||||||
// General purpose register misc
|
// General purpose register misc
|
||||||
Opcode::Addi
|
Opcode::Addi
|
||||||
|
@ -2075,13 +2150,13 @@ impl ToString for Ins {
|
||||||
| Opcode::Addic_
|
| Opcode::Addic_
|
||||||
| Opcode::Addis
|
| Opcode::Addis
|
||||||
| Opcode::Mulli
|
| Opcode::Mulli
|
||||||
| Opcode::Subfic => self.to_string_form_reg12_simm(),
|
| Opcode::Subfic => self.write_string_form_reg12_simm(out),
|
||||||
Opcode::Andi_
|
Opcode::Andi_
|
||||||
| Opcode::Andis_
|
| Opcode::Andis_
|
||||||
| Opcode::Ori
|
| Opcode::Ori
|
||||||
| Opcode::Oris
|
| Opcode::Oris
|
||||||
| Opcode::Xori
|
| Opcode::Xori
|
||||||
| Opcode::Xoris => self.to_string_form_reg12_uimm(),
|
| Opcode::Xoris => self.write_string_form_reg12_uimm(out),
|
||||||
Opcode::Lbz
|
Opcode::Lbz
|
||||||
| Opcode::Lbzu
|
| Opcode::Lbzu
|
||||||
| Opcode::Lha
|
| Opcode::Lha
|
||||||
|
@ -2097,42 +2172,29 @@ impl ToString for Ins {
|
||||||
| Opcode::Sthu
|
| Opcode::Sthu
|
||||||
| Opcode::Stmw
|
| Opcode::Stmw
|
||||||
| Opcode::Stw
|
| Opcode::Stw
|
||||||
| Opcode::Stwu => self.to_string_form_reg12_offset(),
|
| Opcode::Stwu => self.write_string_form_reg12_offset(out),
|
||||||
Opcode::Lswi | Opcode::Stswi => self.to_string_form_reg12_nb(),
|
Opcode::Lswi | Opcode::Stswi => self.write_string_form_reg12_nb(out),
|
||||||
Opcode::Mfspr | Opcode::Mftb => self.to_string_form_reg1_spr(),
|
Opcode::Mfspr | Opcode::Mftb => self.write_string_form_reg1_spr(out),
|
||||||
Opcode::Mtspr => self.to_string_form_spr_reg1(),
|
Opcode::Mtspr => self.write_string_form_spr_reg1(out),
|
||||||
Opcode::Mfsr => self.to_string_form_reg1_sr(),
|
Opcode::Mfsr => self.write_string_form_reg1_sr(out),
|
||||||
Opcode::Mtsr => self.to_string_form_sr_reg1(),
|
Opcode::Mtsr => self.write_string_form_sr_reg1(out),
|
||||||
Opcode::Mtcrf => self.to_string_mtcrf(),
|
Opcode::Mtcrf => self.write_string_mtcrf(out),
|
||||||
Opcode::Srawi => {
|
Opcode::Srawi => self.write_string_srawi(out),
|
||||||
let name_suffix = if self.rc() { "." } else { "" };
|
Opcode::Tw => self.write_string_tw(out),
|
||||||
format!(
|
Opcode::Twi => self.write_string_twi(out),
|
||||||
"srawi{} r{}, r{}, {}",
|
|
||||||
name_suffix,
|
|
||||||
self.s(),
|
|
||||||
self.a(),
|
|
||||||
self.sh()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Opcode::Tw => {
|
|
||||||
format!("tw {}, r{}, r{}", self.to(), self.a(), self.b())
|
|
||||||
}
|
|
||||||
Opcode::Twi => {
|
|
||||||
format!("twi {}, r{}, {}", self.to(), self.a(), self.simm())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Branch instructions
|
// Branch instructions
|
||||||
Opcode::B => self.to_string_b(),
|
Opcode::B => self.write_string_b(out),
|
||||||
Opcode::Bc => self.to_string_bc(),
|
Opcode::Bc => self.write_string_bc(out),
|
||||||
Opcode::Bcctr | Opcode::Bclr => self.to_string_branch_cond_to_reg(),
|
Opcode::Bcctr | Opcode::Bclr => self.write_string_branch_cond_to_reg(out),
|
||||||
|
|
||||||
// Compare instructions
|
// Compare instructions
|
||||||
Opcode::Cmp | Opcode::Cmpl => self.to_string_cmp(),
|
Opcode::Cmp | Opcode::Cmpl => self.write_string_cmp(out),
|
||||||
Opcode::Cmpi => self.to_string_cmp_simm(),
|
Opcode::Cmpi => self.write_string_cmp_simm(out),
|
||||||
Opcode::Cmpli => self.to_string_cmp_uimm(),
|
Opcode::Cmpli => self.write_string_cmp_uimm(out),
|
||||||
|
|
||||||
// Floating point register only instructions
|
// Floating point register only instructions
|
||||||
Opcode::Mffs => self.to_string_form_fr1(),
|
Opcode::Mffs => self.write_string_form_fr1(out),
|
||||||
Opcode::Fabs
|
Opcode::Fabs
|
||||||
| Opcode::Fmr
|
| Opcode::Fmr
|
||||||
| Opcode::Fnabs
|
| Opcode::Fnabs
|
||||||
|
@ -2145,7 +2207,7 @@ impl ToString for Ins {
|
||||||
| Opcode::PsNabs
|
| Opcode::PsNabs
|
||||||
| Opcode::PsNeg
|
| Opcode::PsNeg
|
||||||
| Opcode::PsRes
|
| Opcode::PsRes
|
||||||
| Opcode::PsRsqrte => self.to_string_form_fr13(),
|
| Opcode::PsRsqrte => self.write_string_form_fr13(out),
|
||||||
Opcode::Fadd
|
Opcode::Fadd
|
||||||
| Opcode::Fadds
|
| Opcode::Fadds
|
||||||
| Opcode::Fdiv
|
| Opcode::Fdiv
|
||||||
|
@ -2158,9 +2220,9 @@ impl ToString for Ins {
|
||||||
| Opcode::PsMerge01
|
| Opcode::PsMerge01
|
||||||
| Opcode::PsMerge10
|
| Opcode::PsMerge10
|
||||||
| Opcode::PsMerge11
|
| Opcode::PsMerge11
|
||||||
| Opcode::PsSub => self.to_string_form_fr123(),
|
| Opcode::PsSub => self.write_string_form_fr123(out),
|
||||||
Opcode::Fmul | Opcode::Fmuls | Opcode::PsMul | Opcode::PsMuls0 | Opcode::PsMuls1 => {
|
Opcode::Fmul | Opcode::Fmuls | Opcode::PsMul | Opcode::PsMuls0 | Opcode::PsMuls1 => {
|
||||||
self.to_string_form_fr124()
|
self.write_string_form_fr124(out)
|
||||||
}
|
}
|
||||||
Opcode::Fmadd
|
Opcode::Fmadd
|
||||||
| Opcode::Fmadds
|
| Opcode::Fmadds
|
||||||
|
@ -2179,16 +2241,16 @@ impl ToString for Ins {
|
||||||
| Opcode::PsNmsub
|
| Opcode::PsNmsub
|
||||||
| Opcode::PsSel
|
| Opcode::PsSel
|
||||||
| Opcode::PsSum0
|
| Opcode::PsSum0
|
||||||
| Opcode::PsSum1 => self.to_string_form_fr1243(),
|
| Opcode::PsSum1 => self.write_string_form_fr1243(out),
|
||||||
|
|
||||||
// Floating point register misc instructions
|
// Floating point register misc instructions
|
||||||
Opcode::Fctiw | Opcode::Fctiwz => self.to_string_form_condreg1_fr13_rc(),
|
Opcode::Fctiw | Opcode::Fctiwz => self.write_string_form_condreg1_fr13_rc(out),
|
||||||
Opcode::Fcmpo
|
Opcode::Fcmpo
|
||||||
| Opcode::Fcmpu
|
| Opcode::Fcmpu
|
||||||
| Opcode::PsCmpo0
|
| Opcode::PsCmpo0
|
||||||
| Opcode::PsCmpo1
|
| Opcode::PsCmpo1
|
||||||
| Opcode::PsCmpu0
|
| Opcode::PsCmpu0
|
||||||
| Opcode::PsCmpu1 => self.to_string_form_condreg1_fr23(),
|
| Opcode::PsCmpu1 => self.write_string_form_condreg1_fr23(out),
|
||||||
Opcode::Lfd
|
Opcode::Lfd
|
||||||
| Opcode::Lfdu
|
| Opcode::Lfdu
|
||||||
| Opcode::Lfs
|
| Opcode::Lfs
|
||||||
|
@ -2196,7 +2258,7 @@ impl ToString for Ins {
|
||||||
| Opcode::Stfd
|
| Opcode::Stfd
|
||||||
| Opcode::Stfdu
|
| Opcode::Stfdu
|
||||||
| Opcode::Stfs
|
| Opcode::Stfs
|
||||||
| Opcode::Stfsu => self.to_string_form_fr1_reg2_offset(),
|
| Opcode::Stfsu => self.write_string_form_fr1_reg2_offset(out),
|
||||||
Opcode::Lfdux
|
Opcode::Lfdux
|
||||||
| Opcode::Lfdx
|
| Opcode::Lfdx
|
||||||
| Opcode::Lfsux
|
| Opcode::Lfsux
|
||||||
|
@ -2205,12 +2267,12 @@ impl ToString for Ins {
|
||||||
| Opcode::Stfdx
|
| Opcode::Stfdx
|
||||||
| Opcode::Stfiwx
|
| Opcode::Stfiwx
|
||||||
| Opcode::Stfsux
|
| Opcode::Stfsux
|
||||||
| Opcode::Stfsx => self.to_string_form_fr1_reg23(),
|
| Opcode::Stfsx => self.write_string_form_fr1_reg23(out),
|
||||||
Opcode::Mtfsf => self.to_string_mtfsf(),
|
Opcode::Mtfsf => self.write_string_mtfsf(out),
|
||||||
|
|
||||||
// Condition register only
|
// Condition register only
|
||||||
Opcode::Mcrxr | Opcode::Mtfsb0 | Opcode::Mtfsb1 => self.to_string_form_condreg1(),
|
Opcode::Mcrxr | Opcode::Mtfsb0 | Opcode::Mtfsb1 => self.write_string_form_condreg1(out),
|
||||||
Opcode::Mcrf | Opcode::Mcrfs => self.to_string_form_condreg12(),
|
Opcode::Mcrf | Opcode::Mcrfs => self.write_string_form_condreg12(out),
|
||||||
Opcode::Crand
|
Opcode::Crand
|
||||||
| Opcode::Crandc
|
| Opcode::Crandc
|
||||||
| Opcode::Creqv
|
| Opcode::Creqv
|
||||||
|
@ -2218,20 +2280,30 @@ impl ToString for Ins {
|
||||||
| Opcode::Crnor
|
| Opcode::Crnor
|
||||||
| Opcode::Cror
|
| Opcode::Cror
|
||||||
| Opcode::Crorc
|
| Opcode::Crorc
|
||||||
| Opcode::Crxor => self.to_string_form_condreg123(),
|
| Opcode::Crxor => self.write_string_form_condreg123(out),
|
||||||
|
|
||||||
// Condition register misc
|
// Condition register misc
|
||||||
Opcode::Mtfsfi => self.to_string_mtfsfi(),
|
Opcode::Mtfsfi => self.write_string_mtfsfi(out),
|
||||||
|
|
||||||
// Paired-single instructions
|
// Paired-single instructions
|
||||||
Opcode::PsqL | Opcode::PsqLu | Opcode::PsqSt | Opcode::PsqStu => self.to_string_psq(),
|
Opcode::PsqL | Opcode::PsqLu | Opcode::PsqSt | Opcode::PsqStu => {
|
||||||
|
self.write_string_psq(out)
|
||||||
|
}
|
||||||
Opcode::PsqLx | Opcode::PsqLux | Opcode::PsqStx | Opcode::PsqStux => {
|
Opcode::PsqLx | Opcode::PsqLux | Opcode::PsqStx | Opcode::PsqStux => {
|
||||||
self.to_string_psq_x()
|
self.write_string_psq_x(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToString for Ins {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut s = String::new();
|
||||||
|
self.write_string(&mut s).unwrap();
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -2290,7 +2362,10 @@ mod tests {
|
||||||
fn test_to_string() {
|
fn test_to_string() {
|
||||||
assert_eq!(Ins::disasm(0x4c000000).to_string(), "mcrf crf0, crf0");
|
assert_eq!(Ins::disasm(0x4c000000).to_string(), "mcrf crf0, crf0");
|
||||||
assert_eq!(Ins::disasm(0x7c000278).to_string(), "xor r0, r0, r0");
|
assert_eq!(Ins::disasm(0x7c000278).to_string(), "xor r0, r0, r0");
|
||||||
assert_eq!(Ins::disasm(0x10000014).to_string(), "ps_sum0 fr0, fr0, fr0, fr0");
|
assert_eq!(
|
||||||
|
Ins::disasm(0x10000014).to_string(),
|
||||||
|
"ps_sum0 fr0, fr0, fr0, fr0"
|
||||||
|
);
|
||||||
assert_eq!(Ins::disasm(0x10000032).to_string(), "ps_mul fr0, fr0, fr0");
|
assert_eq!(Ins::disasm(0x10000032).to_string(), "ps_mul fr0, fr0, fr0");
|
||||||
assert_eq!(Ins::disasm(0x7c00052a).to_string(), "");
|
assert_eq!(Ins::disasm(0x7c00052a).to_string(), "");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue