use crate::addresses::{GotGlobalEntry, Rom, Vram};
use super::InstrOpJumptable;
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum InstrAnalysisInfo {
No,
DirectLink {
target_vram: Vram,
},
BranchLink {
target_vram: Vram,
},
JumpAndLinkRegisterRaw {
raw_vram: Vram,
},
JumpAndLinkRegisterDereferenced {
dereferenced_vram: Vram,
},
MaybeDirectTailCall {
target_vram: Vram,
},
RawRegisterTailCall {
raw_vram: Vram,
},
DereferencedRegisterTailCall {
dereferenced_vram: Vram,
},
Jumptable {
jumptable_vram: Vram,
kind: InstrOpJumptable,
},
Branch {
target_vram: Vram,
},
BranchOutside {
target_vram: Vram,
},
UnpairedHi {
value: u32,
},
PairedHi {
addended_vram: Vram,
unaddended_vram: Vram,
},
PairedLo {
addended_vram: Vram,
unaddended_vram: Vram,
upper_rom: Rom,
},
ConstantHi {
constant: u32,
},
ConstantLo {
constant: u32,
upper_rom: Rom,
},
GpRel {
addended_vram: Vram,
unaddended_vram: Vram,
},
GotLazyResolver {
addended_vram: Vram,
unaddended_vram: Vram,
},
GotGlobal {
addended_vram: Vram,
unaddended_vram: Vram,
global_entry: GotGlobalEntry,
},
GotLocal {
addended_vram: Vram,
unaddended_vram: Vram,
},
GotLocalPaired {
addended_vram: Vram,
unaddended_vram: Vram,
},
GotGlobalCall16 {
vram: Vram,
global_entry: GotGlobalEntry,
},
GotLocalCall16 {
vram: Vram,
},
PairedGotHi {
vram: Vram,
global_entry: Option<GotGlobalEntry>,
},
PairedGotLo {
vram: Vram,
global_entry: Option<GotGlobalEntry>,
},
GotCallHi {
vram: Vram,
global_entry: Option<GotGlobalEntry>,
},
GotCallLo {
vram: Vram,
global_entry: Option<GotGlobalEntry>,
},
GpSetHi,
GpSetLo,
CploadHi,
CploadLo,
CploadAddu,
}
impl InstrAnalysisInfo {
pub(crate) fn upper_rom(&self) -> Option<Rom> {
match self {
InstrAnalysisInfo::No => None,
InstrAnalysisInfo::DirectLink { target_vram: _ } => None,
InstrAnalysisInfo::BranchLink { target_vram: _ } => None,
InstrAnalysisInfo::JumpAndLinkRegisterRaw { raw_vram: _ } => None,
InstrAnalysisInfo::JumpAndLinkRegisterDereferenced {
dereferenced_vram: _,
} => None,
InstrAnalysisInfo::MaybeDirectTailCall { target_vram: _ } => None,
InstrAnalysisInfo::RawRegisterTailCall { raw_vram: _ } => None,
InstrAnalysisInfo::DereferencedRegisterTailCall {
dereferenced_vram: _,
} => None,
InstrAnalysisInfo::Jumptable {
jumptable_vram: _,
kind: _,
} => None,
InstrAnalysisInfo::Branch { target_vram: _ } => None,
InstrAnalysisInfo::BranchOutside { target_vram: _ } => None,
InstrAnalysisInfo::UnpairedHi { value: _ } => None,
InstrAnalysisInfo::PairedHi {
addended_vram: _,
unaddended_vram: _,
} => None,
InstrAnalysisInfo::PairedLo {
addended_vram: _,
unaddended_vram: _,
upper_rom,
} => Some(*upper_rom),
InstrAnalysisInfo::ConstantHi { constant: _ } => None,
InstrAnalysisInfo::ConstantLo {
constant: _,
upper_rom,
} => Some(*upper_rom),
InstrAnalysisInfo::GpRel {
addended_vram: _,
unaddended_vram: _,
} => None,
InstrAnalysisInfo::GotLazyResolver {
addended_vram: _,
unaddended_vram: _,
} => None,
InstrAnalysisInfo::GotGlobal {
addended_vram: _,
unaddended_vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::GotLocal {
addended_vram: _,
unaddended_vram: _,
} => None,
InstrAnalysisInfo::GotLocalPaired {
addended_vram: _,
unaddended_vram: _,
} => None,
InstrAnalysisInfo::GotGlobalCall16 {
vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::GotLocalCall16 { vram: _ } => None,
InstrAnalysisInfo::PairedGotHi {
vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::PairedGotLo {
vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::GotCallHi {
vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::GotCallLo {
vram: _,
global_entry: _,
} => None,
InstrAnalysisInfo::GpSetHi => None,
InstrAnalysisInfo::GpSetLo => None,
InstrAnalysisInfo::CploadHi => None,
InstrAnalysisInfo::CploadLo => None,
InstrAnalysisInfo::CploadAddu => None,
}
}
pub(crate) fn align_down_unaddended(self, alignment: u8) -> Self {
match self {
InstrAnalysisInfo::PairedHi {
addended_vram,
unaddended_vram: _,
} => InstrAnalysisInfo::PairedHi {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
},
InstrAnalysisInfo::PairedLo {
addended_vram,
unaddended_vram: _,
upper_rom,
} => InstrAnalysisInfo::PairedLo {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
upper_rom,
},
InstrAnalysisInfo::GpRel {
addended_vram,
unaddended_vram: _,
} => InstrAnalysisInfo::GpRel {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
},
InstrAnalysisInfo::GotLazyResolver {
addended_vram,
unaddended_vram: _,
} => InstrAnalysisInfo::GotLazyResolver {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
},
InstrAnalysisInfo::GotGlobal {
addended_vram,
unaddended_vram: _,
global_entry,
} => InstrAnalysisInfo::GotGlobal {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
global_entry,
},
InstrAnalysisInfo::GotLocal {
addended_vram,
unaddended_vram: _,
} => InstrAnalysisInfo::GotLocal {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
},
InstrAnalysisInfo::GotLocalPaired {
addended_vram,
unaddended_vram: _,
} => InstrAnalysisInfo::GotLocalPaired {
addended_vram,
unaddended_vram: addended_vram.align_down(alignment),
},
x => x,
}
}
}