disasm: branch helpers, fix split fields
This commit is contained in:
parent
5c4a3d01e5
commit
a80372c1b6
|
@ -1808,7 +1808,11 @@ impl Ins {
|
|||
Opcode::Mfmsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
Opcode::Mfspr => vec![
|
||||
Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)),
|
||||
Field::spr(SPR(((self.code >> 11u8) & 0x3ff) as _)),
|
||||
Field::spr(SPR(
|
||||
(((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32 as _,
|
||||
)),
|
||||
],
|
||||
Opcode::Mfsr => vec![
|
||||
Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)),
|
||||
|
@ -1820,7 +1824,11 @@ impl Ins {
|
|||
],
|
||||
Opcode::Mftb => vec![
|
||||
Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)),
|
||||
Field::tbr(OpaqueU(((self.code >> 11u8) & 0x3ff) as _)),
|
||||
Field::tbr(OpaqueU(
|
||||
(((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32 as _,
|
||||
)),
|
||||
],
|
||||
Opcode::Mtcrf => vec![
|
||||
Field::crm(OpaqueU(((self.code >> 12u8) & 0xff) as _)),
|
||||
|
@ -1838,7 +1846,11 @@ impl Ins {
|
|||
],
|
||||
Opcode::Mtmsr => vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
Opcode::Mtspr => vec![
|
||||
Field::spr(SPR(((self.code >> 11u8) & 0x3ff) as _)),
|
||||
Field::spr(SPR(
|
||||
(((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32 as _,
|
||||
)),
|
||||
Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)),
|
||||
],
|
||||
Opcode::Mtsr => vec![
|
||||
|
@ -4971,6 +4983,13 @@ impl Ins {
|
|||
}
|
||||
}
|
||||
Opcode::Bc => {
|
||||
if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 {
|
||||
return SimplifiedIns {
|
||||
mnemonic: "b",
|
||||
args: vec![],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 21u8) & 0x1f) == 12
|
||||
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
|
||||
&& ((self.code >> 18u8) & 0x7) == 0
|
||||
|
@ -5637,42 +5656,66 @@ impl Ins {
|
|||
}
|
||||
}
|
||||
Opcode::Mfspr => {
|
||||
if ((self.code >> 11u8) & 0x3ff) == 1 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 1
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mfxer",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 8 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 8
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mflr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 9 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 9
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mfctr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 18 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 18
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mfdsisr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 397 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 397
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mfdbatu",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 571 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 571
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mftdu",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
|
@ -5681,42 +5724,66 @@ impl Ins {
|
|||
}
|
||||
}
|
||||
Opcode::Mtspr => {
|
||||
if ((self.code >> 11u8) & 0x3ff) == 1 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 1
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mtxer",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 8 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 8
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mtlr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 9 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 9
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mtctr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 18 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 18
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mtdsisr",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 397 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 397
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mtdbatu",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
ins: self,
|
||||
};
|
||||
}
|
||||
if ((self.code >> 11u8) & 0x3ff) == 571 {
|
||||
if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32))
|
||||
as u32
|
||||
== 571
|
||||
{
|
||||
return SimplifiedIns {
|
||||
mnemonic: "mttdu",
|
||||
args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))],
|
||||
|
@ -5901,7 +5968,8 @@ impl Ins {
|
|||
}
|
||||
#[inline(always)]
|
||||
pub fn field_spr(&self) -> usize {
|
||||
((self.code >> 11u8) & 0x3ff) as _
|
||||
(((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 as _
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn field_frS(&self) -> usize {
|
||||
|
@ -5961,7 +6029,8 @@ impl Ins {
|
|||
}
|
||||
#[inline(always)]
|
||||
pub fn field_tbr(&self) -> usize {
|
||||
((self.code >> 11u8) & 0x3ff) as _
|
||||
(((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32)
|
||||
| ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 as _
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn field_mtfsf_FM(&self) -> usize {
|
||||
|
|
|
@ -129,6 +129,8 @@ impl Display for Bit {
|
|||
// Unsigned opaque argument.
|
||||
field_arg!(OpaqueU, u32);
|
||||
|
||||
const SPR_LR: usize = 16;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Argument {
|
||||
GPR(GPR),
|
||||
|
@ -166,9 +168,9 @@ impl Display for Argument {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<i64> for Argument {
|
||||
fn into(self) -> i64 {
|
||||
match self {
|
||||
impl From<Argument> for i64 {
|
||||
fn from(arg: Argument) -> Self {
|
||||
match arg {
|
||||
Argument::GPR(x) => x.0 as i64,
|
||||
Argument::FPR(x) => x.0 as i64,
|
||||
Argument::SR(x) => x.0 as i64,
|
||||
|
@ -288,6 +290,32 @@ impl Ins {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_branch(&self) -> bool {
|
||||
match self.op {
|
||||
Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unconditional_branch(&self) -> bool {
|
||||
match self.op {
|
||||
Opcode::B => true,
|
||||
Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => {
|
||||
self.field_BO() == 20 && self.field_BI() == 0
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_conditional_branch(&self) -> bool {
|
||||
self.is_branch() && !self.is_unconditional_branch()
|
||||
}
|
||||
|
||||
pub fn is_blr(&self) -> bool {
|
||||
// self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK()
|
||||
self.code == 0x4e800020
|
||||
}
|
||||
}
|
||||
|
||||
/// A simplified PowerPC 750CL instruction.
|
||||
|
|
|
@ -128,6 +128,10 @@ impl Field {
|
|||
val = quote!((#val & #mask));
|
||||
}
|
||||
|
||||
if self.split {
|
||||
val = quote!((((#val & 0b11111_00000u32) >> 5u32) | ((#val & 0b00000_11111u32) << 5u32)) as u32);
|
||||
}
|
||||
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
|
||||
if self.signed {
|
||||
let mask2 = 1u32 << (self.bits.0.len() - 1);
|
||||
|
|
Loading…
Reference in New Issue