disasm: improve branch ins helpers
`branch_dest`: Support absolute destinations `is_branch`: Use `matches!` to improve readability `is_direct_branch`: Added helper to better match direct branches Co-authored-by: Richard Patel <me@terorie.dev>
This commit is contained in:
parent
a80372c1b6
commit
9fd7546916
|
@ -229,6 +229,8 @@ pub struct Ins {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ins {
|
impl Ins {
|
||||||
|
const BLR: u32 = 0x4e800020;
|
||||||
|
|
||||||
/// Constructs an instruction from the given machine code and address.
|
/// Constructs an instruction from the given machine code and address.
|
||||||
pub fn new(code: u32, addr: u32) -> Self {
|
pub fn new(code: u32, addr: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -283,19 +285,24 @@ impl Ins {
|
||||||
|
|
||||||
pub fn branch_dest(&self) -> Option<u32> {
|
pub fn branch_dest(&self) -> Option<u32> {
|
||||||
self.branch_offset().and_then(|offset| {
|
self.branch_offset().and_then(|offset| {
|
||||||
if offset < 0 {
|
if self.field_AA() {
|
||||||
self.addr.checked_sub((-offset) as u32)
|
Some(offset as u32)
|
||||||
} else {
|
} else {
|
||||||
self.addr.checked_add(offset as u32)
|
if offset < 0 {
|
||||||
|
self.addr.checked_sub((-offset) as u32)
|
||||||
|
} else {
|
||||||
|
self.addr.checked_add(offset as u32)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_branch(&self) -> bool {
|
pub fn is_branch(&self) -> bool {
|
||||||
match self.op {
|
matches!(self.op, Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr)
|
||||||
Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => true,
|
}
|
||||||
_ => false,
|
|
||||||
}
|
pub fn is_direct_branch(&self) -> bool {
|
||||||
|
matches!(self.op, Opcode::B | Opcode::Bc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_unconditional_branch(&self) -> bool {
|
pub fn is_unconditional_branch(&self) -> bool {
|
||||||
|
@ -312,9 +319,10 @@ impl Ins {
|
||||||
self.is_branch() && !self.is_unconditional_branch()
|
self.is_branch() && !self.is_unconditional_branch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_blr(&self) -> bool {
|
pub fn is_blr(&self) -> bool {
|
||||||
// self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK()
|
// self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK()
|
||||||
self.code == 0x4e800020
|
self.code == Ins::BLR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue