Pass ppc750cl::Ins by value
This commit is contained in:
parent
963425793d
commit
9452ca8b8c
|
@ -62,7 +62,7 @@ pub struct ExecCbData<'a> {
|
||||||
pub result: StepResult,
|
pub result: StepResult,
|
||||||
pub ins_addr: SectionAddress,
|
pub ins_addr: SectionAddress,
|
||||||
pub section: &'a ObjSection,
|
pub section: &'a ObjSection,
|
||||||
pub ins: &'a Ins,
|
pub ins: Ins,
|
||||||
pub block_start: SectionAddress,
|
pub block_start: SectionAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +109,14 @@ impl Executor {
|
||||||
Some(ins) => ins,
|
Some(ins) => ins,
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
let result = state.vm.step(obj, state.address, &ins);
|
let result = state.vm.step(obj, state.address, ins);
|
||||||
match cb(ExecCbData {
|
match cb(ExecCbData {
|
||||||
executor: self,
|
executor: self,
|
||||||
vm: &mut state.vm,
|
vm: &mut state.vm,
|
||||||
result,
|
result,
|
||||||
ins_addr: state.address,
|
ins_addr: state.address,
|
||||||
section,
|
section,
|
||||||
ins: &ins,
|
ins,
|
||||||
block_start,
|
block_start,
|
||||||
})? {
|
})? {
|
||||||
ExecCbResult::Continue => {
|
ExecCbResult::Continue => {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
|
||||||
collections::{btree_map, BTreeMap, BTreeSet},
|
collections::{btree_map, BTreeMap, BTreeSet},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
};
|
};
|
||||||
|
@ -44,34 +43,31 @@ pub enum TailCallResult {
|
||||||
|
|
||||||
type BlockRange = Range<SectionAddress>;
|
type BlockRange = Range<SectionAddress>;
|
||||||
|
|
||||||
type InsCheck = dyn Fn(&Ins) -> bool;
|
type InsCheck = dyn Fn(Ins) -> bool;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn check_sequence(
|
fn check_sequence(
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
addr: SectionAddress,
|
addr: SectionAddress,
|
||||||
ins: Option<&Ins>,
|
ins: Option<Ins>,
|
||||||
sequence: &[(&InsCheck, &InsCheck)],
|
sequence: &[(&InsCheck, &InsCheck)],
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
|
|
||||||
for &(first, second) in sequence {
|
for &(first, second) in sequence {
|
||||||
let Some(ins) =
|
let Some(ins) = ins.or_else(|| disassemble(section, addr.address)) else {
|
||||||
ins.map(Cow::Borrowed).or_else(|| disassemble(section, addr.address).map(Cow::Owned))
|
|
||||||
else {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if !first(&ins) {
|
if !first(ins) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(next) = disassemble(section, addr.address + 4) else {
|
let Some(next) = disassemble(section, addr.address + 4) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if second(&next)
|
if second(next)
|
||||||
// Also check the following instruction, in case the scheduler
|
// Also check the following instruction, in case the scheduler
|
||||||
// put something in between.
|
// put something in between.
|
||||||
|| (!next.is_branch()
|
|| (!next.is_branch()
|
||||||
&& matches!(disassemble(section, addr.address + 8), Some(ins) if second(&ins)))
|
&& matches!(disassemble(section, addr.address + 8), Some(ins) if second(ins)))
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -84,20 +80,20 @@ fn check_sequence(
|
||||||
fn check_prologue_sequence(
|
fn check_prologue_sequence(
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
addr: SectionAddress,
|
addr: SectionAddress,
|
||||||
ins: Option<&Ins>,
|
ins: Option<Ins>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_mflr(ins: &Ins) -> bool {
|
fn is_mflr(ins: Ins) -> bool {
|
||||||
// mfspr r0, LR
|
// mfspr r0, LR
|
||||||
ins.op == Opcode::Mfspr && ins.field_rd() == 0 && ins.field_spr() == 8
|
ins.op == Opcode::Mfspr && ins.field_rd() == 0 && ins.field_spr() == 8
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_stwu(ins: &Ins) -> bool {
|
fn is_stwu(ins: Ins) -> bool {
|
||||||
// stwu r1, d(r1)
|
// stwu r1, d(r1)
|
||||||
ins.op == Opcode::Stwu && ins.field_rs() == 1 && ins.field_ra() == 1
|
ins.op == Opcode::Stwu && ins.field_rs() == 1 && ins.field_ra() == 1
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_stw(ins: &Ins) -> bool {
|
fn is_stw(ins: Ins) -> bool {
|
||||||
// stw r0, d(r1)
|
// stw r0, d(r1)
|
||||||
ins.op == Opcode::Stw && ins.field_rs() == 0 && ins.field_ra() == 1
|
ins.op == Opcode::Stw && ins.field_rs() == 0 && ins.field_ra() == 1
|
||||||
}
|
}
|
||||||
|
@ -138,10 +134,10 @@ impl FunctionSlices {
|
||||||
&mut self,
|
&mut self,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
addr: SectionAddress,
|
addr: SectionAddress,
|
||||||
ins: &Ins,
|
ins: Ins,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_lwz(ins: &Ins) -> bool {
|
fn is_lwz(ins: Ins) -> bool {
|
||||||
// lwz r1, d(r)
|
// lwz r1, d(r)
|
||||||
ins.op == Opcode::Lwz && ins.field_rd() == 1
|
ins.op == Opcode::Lwz && ins.field_rd() == 1
|
||||||
}
|
}
|
||||||
|
@ -166,20 +162,20 @@ impl FunctionSlices {
|
||||||
&mut self,
|
&mut self,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
addr: SectionAddress,
|
addr: SectionAddress,
|
||||||
ins: &Ins,
|
ins: Ins,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_mtlr(ins: &Ins) -> bool {
|
fn is_mtlr(ins: Ins) -> bool {
|
||||||
// mtspr LR, r0
|
// mtspr LR, r0
|
||||||
ins.op == Opcode::Mtspr && ins.field_rs() == 0 && ins.field_spr() == 8
|
ins.op == Opcode::Mtspr && ins.field_rs() == 0 && ins.field_spr() == 8
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_addi(ins: &Ins) -> bool {
|
fn is_addi(ins: Ins) -> bool {
|
||||||
// addi r1, r1, SIMM
|
// addi r1, r1, SIMM
|
||||||
ins.op == Opcode::Addi && ins.field_rd() == 1 && ins.field_ra() == 1
|
ins.op == Opcode::Addi && ins.field_rd() == 1 && ins.field_ra() == 1
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_or(ins: &Ins) -> bool {
|
fn is_or(ins: Ins) -> bool {
|
||||||
// or r1, rA, rB
|
// or r1, rA, rB
|
||||||
ins.op == Opcode::Or && ins.field_rd() == 1
|
ins.op == Opcode::Or && ins.field_rd() == 1
|
||||||
}
|
}
|
||||||
|
@ -454,7 +450,7 @@ impl FunctionSlices {
|
||||||
// Skip nops
|
// Skip nops
|
||||||
match disassemble(&obj.sections[end.section], end.address) {
|
match disassemble(&obj.sections[end.section], end.address) {
|
||||||
Some(ins) => {
|
Some(ins) => {
|
||||||
if !is_nop(&ins) {
|
if !is_nop(ins) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +556,7 @@ impl FunctionSlices {
|
||||||
|
|
||||||
// Some functions with rfi also include a trailing nop
|
// Some functions with rfi also include a trailing nop
|
||||||
if self.has_rfi
|
if self.has_rfi
|
||||||
&& matches!(disassemble(section, end.address), Some(ins) if is_nop(&ins))
|
&& matches!(disassemble(section, end.address), Some(ins) if is_nop(ins))
|
||||||
&& !known_functions.contains_key(&end)
|
&& !known_functions.contains_key(&end)
|
||||||
{
|
{
|
||||||
log::trace!("Found trailing nop @ {:#010X}, merging with function", end);
|
log::trace!("Found trailing nop @ {:#010X}, merging with function", end);
|
||||||
|
@ -713,12 +709,12 @@ impl FunctionSlices {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_conditional_blr(ins: &Ins) -> bool {
|
fn is_conditional_blr(ins: Ins) -> bool {
|
||||||
ins.op == Opcode::Bclr && ins.field_bo() & 0b10100 != 0b10100
|
ins.op == Opcode::Bclr && ins.field_bo() & 0b10100 != 0b10100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_nop(ins: &Ins) -> bool {
|
fn is_nop(ins: Ins) -> bool {
|
||||||
// ori r0, r0, 0
|
// ori r0, r0, 0
|
||||||
ins.code == 0x60000000
|
ins.code == 0x60000000
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ impl VM {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clone_all(&self) -> Box<Self> { Box::new(self.clone()) }
|
pub fn clone_all(&self) -> Box<Self> { Box::new(self.clone()) }
|
||||||
|
|
||||||
pub fn step(&mut self, obj: &ObjInfo, ins_addr: SectionAddress, ins: &Ins) -> StepResult {
|
pub fn step(&mut self, obj: &ObjInfo, ins_addr: SectionAddress, ins: Ins) -> StepResult {
|
||||||
match ins.op {
|
match ins.op {
|
||||||
Opcode::Illegal => {
|
Opcode::Illegal => {
|
||||||
return StepResult::Illegal;
|
return StepResult::Illegal;
|
||||||
|
|
Loading…
Reference in New Issue