auto-generate mnemonics function
This commit is contained in:
parent
fca4e052a6
commit
9e5fa58e3e
409
lib/src/lib.rs
409
lib/src/lib.rs
|
@ -449,50 +449,22 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(
|
||||||
Opcode::Eciwx => "eciwx",
|
out,
|
||||||
Opcode::Ecowx => "ecowx",
|
"{} r{}, r{}, r{}",
|
||||||
Opcode::Lhaux => "lhaux",
|
self.op.mnemonic(),
|
||||||
Opcode::Lhax => "lhax",
|
self.d(),
|
||||||
Opcode::Lbzux => "lbzux",
|
self.a(),
|
||||||
Opcode::Lbzx => "lbzx",
|
self.b()
|
||||||
Opcode::Lhbrx => "lhbrx",
|
)
|
||||||
Opcode::Lhzux => "lhzux",
|
|
||||||
Opcode::Lhzx => "lhzx",
|
|
||||||
Opcode::Lswx => "lswx",
|
|
||||||
Opcode::Lwarx => "lwarx",
|
|
||||||
Opcode::Lwbrx => "lwbrx",
|
|
||||||
Opcode::Lwzx => "lwzx",
|
|
||||||
Opcode::Lwzux => "lwzux",
|
|
||||||
Opcode::Stbux => "stbux",
|
|
||||||
Opcode::Stbx => "stbx",
|
|
||||||
Opcode::Sthux => "sthux",
|
|
||||||
Opcode::Sthx => "sthx",
|
|
||||||
Opcode::Sthbrx => "sthbrx",
|
|
||||||
Opcode::Stswx => "stswx",
|
|
||||||
Opcode::Stwbrx => "stwbrx",
|
|
||||||
Opcode::Stwcx_ => "stwcx.",
|
|
||||||
Opcode::Stwx => "stwx",
|
|
||||||
Opcode::Stwux => "stwux",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} r{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg123_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg123_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::And => "and",
|
|
||||||
Opcode::Andc => "andc",
|
|
||||||
Opcode::Mulhw => "mulhw",
|
|
||||||
Opcode::Mulhwu => "mulhwu",
|
|
||||||
Opcode::Xor => "xor",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} r{}, r{}, r{}",
|
"{}{} r{}, r{}, r{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -507,22 +479,10 @@ impl Ins {
|
||||||
(true, false) => "o",
|
(true, false) => "o",
|
||||||
(true, true) => "o.",
|
(true, true) => "o.",
|
||||||
};
|
};
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Add => "add",
|
|
||||||
Opcode::Addc => "addc",
|
|
||||||
Opcode::Adde => "adde",
|
|
||||||
Opcode::Divw => "divw",
|
|
||||||
Opcode::Divwu => "divwu",
|
|
||||||
Opcode::Mullw => "mullw",
|
|
||||||
Opcode::Subf => "subf",
|
|
||||||
Opcode::Subfc => "subfc",
|
|
||||||
Opcode::Subfe => "subfe",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} r{}, r{}, r{}",
|
"{}{} r{}, r{}, r{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -531,32 +491,14 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_noargs<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_noargs<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{}", self.op.mnemonic())
|
||||||
Opcode::Eieio => "eieio",
|
|
||||||
Opcode::Isync => "isync",
|
|
||||||
Opcode::Rfi => "rfi",
|
|
||||||
Opcode::Sc => "sc",
|
|
||||||
Opcode::Sync => "sync",
|
|
||||||
Opcode::Tlbsync => "tlbsync",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{}", name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg12_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg12_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Addi => "addi",
|
|
||||||
Opcode::Addic => "addic",
|
|
||||||
Opcode::Addic_ => "addic.",
|
|
||||||
Opcode::Addis => "addis",
|
|
||||||
Opcode::Mulli => "mulli",
|
|
||||||
Opcode::Subfic => "subfic",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} r{}, r{}, {}",
|
"{} r{}, r{}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
self.simm()
|
self.simm()
|
||||||
|
@ -564,19 +506,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg12_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg12_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Andi_ => "andi.",
|
|
||||||
Opcode::Andis_ => "andis.",
|
|
||||||
Opcode::Ori => "ori",
|
|
||||||
Opcode::Oris => "oris",
|
|
||||||
Opcode::Xori => "xori",
|
|
||||||
Opcode::Xoris => "xoris",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} r{}, r{}, {}",
|
"{} r{}, r{}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
self.uimm()
|
self.uimm()
|
||||||
|
@ -584,29 +517,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg12_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg12_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Lha => "lha",
|
|
||||||
Opcode::Lhau => "lhau",
|
|
||||||
Opcode::Lbz => "lbz",
|
|
||||||
Opcode::Lbzu => "lbzu",
|
|
||||||
Opcode::Lhz => "lhz",
|
|
||||||
Opcode::Lhzu => "lhzu",
|
|
||||||
Opcode::Lmw => "lmw",
|
|
||||||
Opcode::Lwz => "lwz",
|
|
||||||
Opcode::Lwzu => "lwzu",
|
|
||||||
Opcode::Stb => "stb",
|
|
||||||
Opcode::Stbu => "stbu",
|
|
||||||
Opcode::Sth => "sth",
|
|
||||||
Opcode::Sthu => "sthu",
|
|
||||||
Opcode::Stmw => "stmw",
|
|
||||||
Opcode::Stw => "stw",
|
|
||||||
Opcode::Stwu => "stwu",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} r{}, {}(r{})",
|
"{} r{}, {}(r{})",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.simm(),
|
self.simm(),
|
||||||
self.a()
|
self.a()
|
||||||
|
@ -614,21 +528,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_fr1_reg2_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr1_reg2_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Lfd => "lfd",
|
|
||||||
Opcode::Lfdu => "lfdu",
|
|
||||||
Opcode::Lfs => "lfs",
|
|
||||||
Opcode::Lfsu => "lfsu",
|
|
||||||
Opcode::Stfd => "stfd",
|
|
||||||
Opcode::Stfdu => "stfdu",
|
|
||||||
Opcode::Stfs => "stfs",
|
|
||||||
Opcode::Stfsu => "stfsu",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} fr{}, {}(r{})",
|
"{} fr{}, {}(r{})",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.simm(),
|
self.simm(),
|
||||||
self.a()
|
self.a()
|
||||||
|
@ -636,27 +539,18 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_fr1_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr1_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(
|
||||||
Opcode::Lfdux => "lfdux",
|
out,
|
||||||
Opcode::Lfdx => "lfdx",
|
"{} fr{}, r{}, r{}",
|
||||||
Opcode::Lfsux => "lfsux",
|
self.op.mnemonic(),
|
||||||
Opcode::Lfsx => "lfsx",
|
self.d(),
|
||||||
Opcode::Stfdux => "stfdux",
|
self.a(),
|
||||||
Opcode::Stfdx => "stfdx",
|
self.b()
|
||||||
Opcode::Stfiwx => "stfiwx",
|
)
|
||||||
Opcode::Stfsux => "stfsux",
|
|
||||||
Opcode::Stfsx => "stfsx",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} fr{}, r{}, r{}", name, self.d(), self.a(), self.b())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_mtfsf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_mtfsf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{} {}, fr{}", self.op.mnemonic(), self.fm(), self.b())
|
||||||
Opcode::Mtfsf => "mtfsf",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} {}, fr{}", name, self.fm(), self.b())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_mtfsfi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_mtfsfi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
|
@ -691,72 +585,43 @@ impl Ins {
|
||||||
(true, false) => "o",
|
(true, false) => "o",
|
||||||
(true, true) => "o.",
|
(true, true) => "o.",
|
||||||
};
|
};
|
||||||
let name = match self.op {
|
write!(
|
||||||
Opcode::Addme => "addme",
|
out,
|
||||||
Opcode::Addze => "addze",
|
"{}{} r{}, r{}",
|
||||||
Opcode::Neg => "neg",
|
self.op.mnemonic(),
|
||||||
Opcode::Subfme => "subfme",
|
name_suffix,
|
||||||
Opcode::Subfze => "subfze",
|
self.d(),
|
||||||
_ => disasm_unreachable!(self.code),
|
self.a()
|
||||||
};
|
)
|
||||||
write!(out, "{}{} r{}, r{}", name, name_suffix, self.d(), self.a())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{} r{}, r{}", self.op.mnemonic(), self.d(), self.b())
|
||||||
Opcode::Mfsrin => "mfsrin",
|
|
||||||
Opcode::Mtsrin => "mtsrin",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} r{}, r{}", name, self.d(), self.b())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg21_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg21_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
write!(
|
||||||
Opcode::Cntlzw => "cntlzw",
|
out,
|
||||||
Opcode::Extsb => "extsb",
|
"{}{} r{}, r{}",
|
||||||
Opcode::Extsh => "extsh",
|
self.op.mnemonic(),
|
||||||
_ => disasm_unreachable!(self.code),
|
name_suffix,
|
||||||
};
|
self.a(),
|
||||||
write!(out, "{}{} r{}, r{}", name, name_suffix, self.a(), self.s())
|
self.s()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_fr1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
Opcode::Mffs => match self.rc() != 0 {
|
write!(out, "{}{} fr{}", self.op.mnemonic(), name_suffix, self.d())
|
||||||
false => "mffs",
|
|
||||||
true => "mffs.",
|
|
||||||
},
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} fr{}", name, self.d())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_fr13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fabs => "fabs",
|
|
||||||
Opcode::Fnabs => "fnabs",
|
|
||||||
Opcode::Fmr => "fmr",
|
|
||||||
Opcode::Fneg => "fneg",
|
|
||||||
Opcode::Fres => "fres",
|
|
||||||
Opcode::Frsp => "frsp",
|
|
||||||
Opcode::Frsqrte => "frsqrte",
|
|
||||||
Opcode::PsAbs => "ps_abs",
|
|
||||||
Opcode::PsMr => "ps_mr",
|
|
||||||
Opcode::PsNabs => "ps_nabs",
|
|
||||||
Opcode::PsNeg => "ps_neg",
|
|
||||||
Opcode::PsRes => "ps_res",
|
|
||||||
Opcode::PsRsqrte => "ps_rsqrte",
|
|
||||||
Opcode::PsSum0 => "ps_sum0",
|
|
||||||
Opcode::PsSum1 => "ps_sum1",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} fr{}, fr{}",
|
"{}{} fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.b()
|
self.b()
|
||||||
|
@ -765,26 +630,10 @@ impl Ins {
|
||||||
|
|
||||||
fn write_string_form_fr123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fadd => "fadd",
|
|
||||||
Opcode::Fadds => "fadds",
|
|
||||||
Opcode::Fdiv => "fdiv",
|
|
||||||
Opcode::Fdivs => "fdivs",
|
|
||||||
Opcode::Fsub => "fsub",
|
|
||||||
Opcode::Fsubs => "fsubs",
|
|
||||||
Opcode::PsAdd => "ps_add",
|
|
||||||
Opcode::PsDiv => "ps_div",
|
|
||||||
Opcode::PsMerge00 => "ps_merge00",
|
|
||||||
Opcode::PsMerge01 => "ps_merge01",
|
|
||||||
Opcode::PsMerge10 => "ps_merge10",
|
|
||||||
Opcode::PsMerge11 => "ps_merge11",
|
|
||||||
Opcode::PsSub => "ps_sub",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -794,31 +643,10 @@ impl Ins {
|
||||||
|
|
||||||
fn write_string_form_fr1243<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr1243<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fmadd => "fmadd",
|
|
||||||
Opcode::Fmadds => "fmadds",
|
|
||||||
Opcode::Fmsub => "fmsub",
|
|
||||||
Opcode::Fmsubs => "fmsubs",
|
|
||||||
Opcode::Fnmadd => "fnmadd",
|
|
||||||
Opcode::Fnmadds => "fnmadds",
|
|
||||||
Opcode::Fnmsub => "fnmsub",
|
|
||||||
Opcode::Fnmsubs => "fnmsubs",
|
|
||||||
Opcode::Fsel => "fsel",
|
|
||||||
Opcode::PsMadd => "ps_madd",
|
|
||||||
Opcode::PsMadds0 => "ps_madds0",
|
|
||||||
Opcode::PsMadds1 => "ps_madds1",
|
|
||||||
Opcode::PsMsub => "ps_msub",
|
|
||||||
Opcode::PsNmadd => "ps_nmadd",
|
|
||||||
Opcode::PsNmsub => "ps_nmsub",
|
|
||||||
Opcode::PsSel => "ps_sel",
|
|
||||||
Opcode::PsSum0 => "ps_sum0",
|
|
||||||
Opcode::PsSum1 => "ps_sum1",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -829,18 +657,10 @@ impl Ins {
|
||||||
|
|
||||||
fn write_string_form_fr124<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_fr124<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fmul => "fmul",
|
|
||||||
Opcode::Fmuls => "fmuls",
|
|
||||||
Opcode::PsMul => "ps_mul",
|
|
||||||
Opcode::PsMuls0 => "ps_muls0",
|
|
||||||
Opcode::PsMuls1 => "ps_muls1",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} fr{}, fr{}, fr{}",
|
"{}{} fr{}, fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -849,19 +669,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_condreg1_fr23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_condreg1_fr23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fcmpo => "fcmpo",
|
|
||||||
Opcode::Fcmpu => "fcmpu",
|
|
||||||
Opcode::PsCmpo0 => "ps_cmpo0",
|
|
||||||
Opcode::PsCmpo1 => "ps_cmpo1",
|
|
||||||
Opcode::PsCmpu0 => "ps_cmpu0",
|
|
||||||
Opcode::PsCmpu1 => "ps_cmpu1",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} crf{}, fr{}, fr{}",
|
"{} crf{}, fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
self.b()
|
self.b()
|
||||||
|
@ -870,15 +681,10 @@ impl Ins {
|
||||||
|
|
||||||
fn write_string_form_condreg1_fr13_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_condreg1_fr13_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Fctiw => "fctiw",
|
|
||||||
Opcode::Fctiwz => "fctiwz",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} crf{}, fr{}, fr{}",
|
"{}{} crf{}, fr{}, fr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
self.d(),
|
self.d(),
|
||||||
|
@ -937,15 +743,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_cmp<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_cmp<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Cmp => "cmp",
|
|
||||||
Opcode::Cmpl => "cmpl",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} crf{}, {}, r{}, r{}",
|
"{} crf{}, {}, r{}, r{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
self.l() as u8,
|
self.l() as u8,
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -954,11 +755,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_cmp_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_cmp_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = "cmpi";
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} crf{}, {}, r{}, {}",
|
"{} crf{}, {}, r{}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
self.l() as u8,
|
self.l() as u8,
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -967,11 +767,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_cmp_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_cmp_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = "cmpli";
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} crf{}, {}, r{}, {}",
|
"{} crf{}, {}, r{}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.crf_d(),
|
self.crf_d(),
|
||||||
self.l() as u8,
|
self.l() as u8,
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -1005,21 +804,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_condreg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_condreg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Crand => "crand",
|
|
||||||
Opcode::Crandc => "crandc",
|
|
||||||
Opcode::Creqv => "creqv",
|
|
||||||
Opcode::Crnand => "crnand",
|
|
||||||
Opcode::Crnor => "crnor",
|
|
||||||
Opcode::Cror => "cror",
|
|
||||||
Opcode::Crorc => "crorc",
|
|
||||||
Opcode::Crxor => "crxor",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} crb{}, crb{}, crb{}",
|
"{} crb{}, crb{}, crb{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.crb_d(),
|
self.crb_d(),
|
||||||
self.crb_a(),
|
self.crb_a(),
|
||||||
self.crb_b()
|
self.crb_b()
|
||||||
|
@ -1027,18 +815,7 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{} r{}, r{}", self.op.mnemonic(), self.a(), self.b())
|
||||||
Opcode::Dcbf => "dcbf",
|
|
||||||
Opcode::Dcbi => "dcbi",
|
|
||||||
Opcode::Dcbst => "dcbst",
|
|
||||||
Opcode::Dcbt => "dcbt",
|
|
||||||
Opcode::Dcbtst => "dcbtst",
|
|
||||||
Opcode::Dcbz => "dcbz",
|
|
||||||
Opcode::DcbzL => "dcbz_l",
|
|
||||||
Opcode::Icbi => "icbi",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} r{}, r{}", name, self.a(), self.b())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg213<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg213<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
|
@ -1073,15 +850,10 @@ impl Ins {
|
||||||
|
|
||||||
fn write_string_rlw_imm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_rlw_imm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name_prefix = if self.rc() != 0 { "." } else { "" };
|
let name_prefix = if self.rc() != 0 { "." } else { "" };
|
||||||
let name = match self.op {
|
|
||||||
Opcode::Rlwimi => "rlwimi",
|
|
||||||
Opcode::Rlwinm => "rlwinm",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{}{} r{}, r{}, {}, {}, {}",
|
"{}{} r{}, r{}, {}, {}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
name_prefix,
|
name_prefix,
|
||||||
self.a(),
|
self.a(),
|
||||||
self.s(),
|
self.s(),
|
||||||
|
@ -1107,12 +879,14 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg12_nb<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg12_nb<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(
|
||||||
Opcode::Lswi => "lswi",
|
out,
|
||||||
Opcode::Stswi => "stswi",
|
"{} r{}, r{}, {}",
|
||||||
_ => disasm_unreachable!(self.code),
|
self.op.mnemonic(),
|
||||||
};
|
self.d(),
|
||||||
write!(out, "{} r{}, r{}, {}", name, self.d(), self.a(), self.b())
|
self.a(),
|
||||||
|
self.b()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg1_spr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg1_spr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
|
@ -1143,32 +917,23 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_reg1_sr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_reg1_sr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{} r{}, {}", self.op.mnemonic(), self.d(), self.sr())
|
||||||
Opcode::Mfsr => "mfsr",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} r{}, {}", name, self.d(), self.sr())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_form_sr_reg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_form_sr_reg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
write!(out, "{} {}, r{}", self.op.mnemonic(), self.sr(), self.s())
|
||||||
Opcode::Mtsr => "mtsr",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(out, "{} {}, r{}", name, self.sr(), self.s())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_mtcrf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_mtcrf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
assert_eq!(self.op, Opcode::Mtcrf);
|
write!(out, "{} {}, r{}", self.op.mnemonic(), self.crm(), self.s())
|
||||||
write!(out, "mtcrf {} r{}", self.crm(), self.s())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_srawi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_srawi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
assert_eq!(self.op, Opcode::Srawi);
|
|
||||||
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
let name_suffix = if self.rc() != 0 { "." } else { "" };
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"srawi{} r{}, r{}, {}",
|
"{}{} r{}, r{}, {}",
|
||||||
|
self.op.mnemonic(),
|
||||||
name_suffix,
|
name_suffix,
|
||||||
self.s(),
|
self.s(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -1177,27 +942,32 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_tw<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_tw<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
assert_eq!(self.op, Opcode::Tw);
|
write!(
|
||||||
write!(out, "tw {}, r{}, r{}", self.to(), self.a(), self.b())
|
out,
|
||||||
|
"{} {}, r{}, r{}",
|
||||||
|
self.op.mnemonic(),
|
||||||
|
self.to(),
|
||||||
|
self.a(),
|
||||||
|
self.b()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_twi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_twi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
assert_eq!(self.op, Opcode::Twi);
|
write!(
|
||||||
write!(out, "twi {}, r{}, {}", self.to(), self.a(), self.simm())
|
out,
|
||||||
|
"{} {}, r{}, {}",
|
||||||
|
self.op.mnemonic(),
|
||||||
|
self.to(),
|
||||||
|
self.a(),
|
||||||
|
self.simm()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_psq<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_psq<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::PsqL => "psq_l",
|
|
||||||
Opcode::PsqLu => "psq_lu",
|
|
||||||
Opcode::PsqSt => "psq_st",
|
|
||||||
Opcode::PsqStu => "psq_stu",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} fr{}, {}(r{}), {}, qr{}",
|
"{} fr{}, {}(r{}), {}, qr{}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.ps_d(),
|
self.ps_d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
|
@ -1207,17 +977,10 @@ impl Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string_psq_x<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
fn write_string_psq_x<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
|
||||||
let name = match self.op {
|
|
||||||
Opcode::PsqLx => "psq_lx",
|
|
||||||
Opcode::PsqLux => "psq_lux",
|
|
||||||
Opcode::PsqStx => "psq_stx",
|
|
||||||
Opcode::PsqStux => "psq_stux",
|
|
||||||
_ => disasm_unreachable!(self.code),
|
|
||||||
};
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"{} fr{}, r{}, r{}, {}, {}",
|
"{} fr{}, r{}, r{}, {}, {}",
|
||||||
name,
|
self.op.mnemonic(),
|
||||||
self.d(),
|
self.d(),
|
||||||
self.a(),
|
self.a(),
|
||||||
self.b(),
|
self.b(),
|
||||||
|
|
|
@ -120,6 +120,34 @@ fn gen_is_valid_fn(tokens: &mut Vec<TokenTree>, opcodes: &Opcodes) {
|
||||||
tokens.push(TokenTree::Group(body));
|
tokens.push(TokenTree::Group(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_mnemonic_fn(tokens: &mut Vec<TokenTree>, opcodes: &Opcodes) {
|
||||||
|
let header: TokenStream = "pub fn mnemonic(self) -> &'static str".parse().unwrap();
|
||||||
|
tokens.append(&mut header.into_iter().collect());
|
||||||
|
let mut parts = Vec::<TokenTree>::new();
|
||||||
|
let match_header: TokenStream = "match self".parse().unwrap();
|
||||||
|
parts.append(&mut match_header.into_iter().collect());
|
||||||
|
let mut match_parts = Vec::<TokenTree>::new();
|
||||||
|
let illegal_match: TokenStream = "Opcode::Illegal => \"<illegal>\",".parse().unwrap();
|
||||||
|
match_parts.append(&mut illegal_match.into_iter().collect());
|
||||||
|
for opcode in &opcodes.opcodes {
|
||||||
|
match_parts.push(TokenTree::Ident(Ident::new("Opcode", Span::call_site())));
|
||||||
|
match_parts.push(TokenTree::Punct(Punct::new(':', Spacing::Joint)));
|
||||||
|
match_parts.push(TokenTree::Punct(Punct::new(':', Spacing::Alone)));
|
||||||
|
match_parts.push(TokenTree::Ident(Ident::new(
|
||||||
|
&opcode.variant_name,
|
||||||
|
Span::call_site(),
|
||||||
|
)));
|
||||||
|
match_parts.push(TokenTree::Punct(Punct::new('=', Spacing::Joint)));
|
||||||
|
match_parts.push(TokenTree::Punct(Punct::new('>', Spacing::Alone)));
|
||||||
|
match_parts.push(TokenTree::Literal(Literal::string(&opcode.name)));
|
||||||
|
match_parts.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
|
||||||
|
}
|
||||||
|
let match_body = Group::new(Delimiter::Brace, TokenStream::from_iter(match_parts));
|
||||||
|
parts.push(TokenTree::Group(match_body));
|
||||||
|
let body = Group::new(Delimiter::Brace, TokenStream::from_iter(parts));
|
||||||
|
tokens.push(TokenTree::Group(body));
|
||||||
|
}
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn isa(input: TokenStream) -> TokenStream {
|
pub fn isa(input: TokenStream) -> TokenStream {
|
||||||
let opcodes = syn::parse_macro_input!(input as Opcodes);
|
let opcodes = syn::parse_macro_input!(input as Opcodes);
|
||||||
|
@ -178,11 +206,26 @@ impl Default for Opcode {
|
||||||
root.append(&mut impl_opcode_header.into_iter().collect());
|
root.append(&mut impl_opcode_header.into_iter().collect());
|
||||||
let mut impl_opcode_body_parts = Vec::<TokenTree>::new();
|
let mut impl_opcode_body_parts = Vec::<TokenTree>::new();
|
||||||
gen_is_valid_fn(&mut impl_opcode_body_parts, &opcodes);
|
gen_is_valid_fn(&mut impl_opcode_body_parts, &opcodes);
|
||||||
|
gen_mnemonic_fn(&mut impl_opcode_body_parts, &opcodes);
|
||||||
let impl_opcode_body = Group::new(
|
let impl_opcode_body = Group::new(
|
||||||
Delimiter::Brace,
|
Delimiter::Brace,
|
||||||
TokenStream::from_iter(impl_opcode_body_parts),
|
TokenStream::from_iter(impl_opcode_body_parts),
|
||||||
);
|
);
|
||||||
root.push(TokenTree::Group(impl_opcode_body));
|
root.push(TokenTree::Group(impl_opcode_body));
|
||||||
|
|
||||||
|
// impl ToString block.
|
||||||
|
let to_string_trait_impl: TokenStream = "
|
||||||
|
impl std::string::ToString for Opcode {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mnemonic = self.mnemonic();
|
||||||
|
mnemonic.to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
root.append(&mut to_string_trait_impl.into_iter().collect());
|
||||||
|
|
||||||
TokenStream::from_iter(root)
|
TokenStream::from_iter(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue