Add InsIter
This commit is contained in:
parent
d31bf75009
commit
d63c94c3e2
|
@ -354,7 +354,7 @@ impl ParsedIns {
|
|||
/// Returns an iterator over the arguments of the instruction,
|
||||
/// stopping at the first [Argument::None].
|
||||
#[inline]
|
||||
pub fn args_iter(&self) -> impl Iterator<Item = &Argument> {
|
||||
pub fn args_iter(&self) -> impl Iterator<Item=&Argument> {
|
||||
self.args.iter().take_while(|x| !matches!(x, Argument::None))
|
||||
}
|
||||
}
|
||||
|
@ -405,3 +405,40 @@ impl LowerHex for SignedHexLiteral<i32> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InsIter<'a> {
|
||||
address: u32,
|
||||
data: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> InsIter<'a> {
|
||||
pub fn new(data: &'a [u8], address: u32) -> Self {
|
||||
Self { address, data }
|
||||
}
|
||||
|
||||
pub fn address(&self) -> u32 {
|
||||
self.address
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &'a [u8] {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for InsIter<'a> {
|
||||
type Item = (u32, Ins);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.data.len() < 4 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// SAFETY: The slice is guaranteed to be at least 4 bytes long.
|
||||
let chunk = unsafe { *(self.data.as_ptr() as *const [u8; 4]) };
|
||||
let ins = Ins::new(u32::from_be_bytes(chunk));
|
||||
let addr = self.address;
|
||||
self.address += 4;
|
||||
self.data = &self.data[4..];
|
||||
Some((addr, ins))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ mod disasm;
|
|||
mod generated;
|
||||
|
||||
pub use disasm::{
|
||||
Argument, BranchDest, CRBit, CRField, Ins, Offset, OpaqueU, ParsedIns, Simm, Uimm, FPR, GPR,
|
||||
GQR, SPR, SR,
|
||||
Argument, BranchDest, CRBit, CRField, Ins, InsIter, Offset, OpaqueU, ParsedIns, Simm, Uimm,
|
||||
FPR, GPR, GQR, SPR, SR,
|
||||
};
|
||||
pub use generated::{Arguments, Opcode};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ppc750cl::{Argument, Ins, Opcode, FPR, GPR};
|
||||
use ppc750cl::{Argument, Ins, InsIter, Opcode, FPR, GPR};
|
||||
|
||||
macro_rules! assert_asm {
|
||||
($ins:ident, $disasm:literal) => {{
|
||||
|
@ -1137,3 +1137,11 @@ fn test_ins_xori() {
|
|||
fn test_ins_xoris() {
|
||||
assert_asm!(0x6E3D8000, "xoris r29, r17, 0x8000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ins_iter() {
|
||||
let mut iter = InsIter::new(&[0x7C, 0x43, 0x22, 0x14, 0x7E, 0x1A, 0x02, 0xA6, 0xFF], 0);
|
||||
assert_eq!(iter.next(), Some((0, Ins::new(0x7C432214))));
|
||||
assert_eq!(iter.next(), Some((4, Ins::new(0x7E1A02A6))));
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue