Pass ppc750cl::Ins by value

This commit is contained in:
Luke Street 2024-04-30 22:53:32 -06:00
parent 963425793d
commit 9452ca8b8c
3 changed files with 24 additions and 28 deletions

View File

@ -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 => {

View File

@ -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
} }

View File

@ -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;