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,
|
/// Returns an iterator over the arguments of the instruction,
|
||||||
/// stopping at the first [Argument::None].
|
/// stopping at the first [Argument::None].
|
||||||
#[inline]
|
#[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))
|
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;
|
mod generated;
|
||||||
|
|
||||||
pub use disasm::{
|
pub use disasm::{
|
||||||
Argument, BranchDest, CRBit, CRField, Ins, Offset, OpaqueU, ParsedIns, Simm, Uimm, FPR, GPR,
|
Argument, BranchDest, CRBit, CRField, Ins, InsIter, Offset, OpaqueU, ParsedIns, Simm, Uimm,
|
||||||
GQR, SPR, SR,
|
FPR, GPR, GQR, SPR, SR,
|
||||||
};
|
};
|
||||||
pub use generated::{Arguments, Opcode};
|
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 {
|
macro_rules! assert_asm {
|
||||||
($ins:ident, $disasm:literal) => {{
|
($ins:ident, $disasm:literal) => {{
|
||||||
|
@ -1137,3 +1137,11 @@ fn test_ins_xori() {
|
||||||
fn test_ins_xoris() {
|
fn test_ins_xoris() {
|
||||||
assert_asm!(0x6E3D8000, "xoris r29, r17, 0x8000");
|
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