ppc750cl/disasm-py/src/lib.rs

262 lines
5.3 KiB
Rust

use pyo3::prelude::*;
use pyo3::types::PyBytes;
use ppc750cl::formatter::FormattedIns;
#[pyclass]
struct Ins(ppc750cl::Ins);
#[pymethods]
impl Ins {
#[new]
fn new(code: u32, addr: u32) -> Self {
Ins(ppc750cl::Ins::new(code, addr))
}
#[getter]
fn code(&self) -> u32 {
self.0.code
}
#[getter]
fn addr(&self) -> u32 {
self.0.addr
}
#[getter]
fn opcode(&self) -> &'static str {
self.0.op.mnemonic()
}
fn __str__(&self) -> String {
FormattedIns(self.0.clone()).to_string()
}
fn fields(&self) -> Vec<(&'static str, i64)> {
self.0
.fields()
.iter()
.flat_map(|field| field.argument().map(|arg| (field.name(), arg.into())))
.collect()
}
}
#[allow(non_snake_case)]
#[pymethods]
impl Ins {
#[getter]
fn simm(&self) -> i64 {
self.0.field_simm() as i64
}
#[getter]
fn uimm(&self) -> i64 {
self.0.field_uimm() as i64
}
#[getter]
fn offset(&self) -> i64 {
self.0.field_offset() as i64
}
#[getter]
fn ps_offset(&self) -> i64 {
self.0.field_ps_offset() as i64
}
#[getter]
fn BO(&self) -> i64 {
self.0.field_BO() as i64
}
#[getter]
fn BI(&self) -> i64 {
self.0.field_BI() as i64
}
#[getter]
fn BD(&self) -> i64 {
self.0.field_BD() as i64
}
#[getter]
fn LI(&self) -> i64 {
self.0.field_LI() as i64
}
#[getter]
fn SH(&self) -> i64 {
self.0.field_SH() as i64
}
#[getter]
fn MB(&self) -> i64 {
self.0.field_SH() as i64
}
#[getter]
fn ME(&self) -> i64 {
self.0.field_SH() as i64
}
#[getter]
fn rS(&self) -> i64 {
self.0.field_rS() as i64
}
#[getter]
fn rD(&self) -> i64 {
self.0.field_rD() as i64
}
#[getter]
fn rA(&self) -> i64 {
self.0.field_rA() as i64
}
#[getter]
fn rB(&self) -> i64 {
self.0.field_rB() as i64
}
#[getter]
fn rC(&self) -> i64 {
self.0.field_rC() as i64
}
#[getter]
fn sr(&self) -> i64 {
self.0.field_sr() as i64
}
#[getter]
fn spr(&self) -> i64 {
self.0.field_spr() as i64
}
#[getter]
fn frS(&self) -> i64 {
self.0.field_frS() as i64
}
#[getter]
fn frD(&self) -> i64 {
self.0.field_frD() as i64
}
#[getter]
fn frA(&self) -> i64 {
self.0.field_frA() as i64
}
#[getter]
fn frB(&self) -> i64 {
self.0.field_frB() as i64
}
#[getter]
fn frC(&self) -> i64 {
self.0.field_frC() as i64
}
#[getter]
fn crbD(&self) -> i64 {
self.0.field_crbD() as i64
}
#[getter]
fn crbA(&self) -> i64 {
self.0.field_crbA() as i64
}
#[getter]
fn crbB(&self) -> i64 {
self.0.field_crbB() as i64
}
#[getter]
fn crfD(&self) -> i64 {
self.0.field_crfD() as i64
}
#[getter]
fn crfS(&self) -> i64 {
self.0.field_crfS() as i64
}
#[getter]
fn crm(&self) -> i64 {
self.0.field_crm() as i64
}
#[getter]
fn ps_I(&self) -> i64 {
self.0.field_ps_I() as i64
}
#[getter]
fn ps_IX(&self) -> i64 {
self.0.field_ps_IX() as i64
}
#[getter]
fn ps_W(&self) -> i64 {
self.0.field_ps_W() as i64
}
#[getter]
fn ps_WX(&self) -> i64 {
self.0.field_ps_WX() as i64
}
#[getter]
fn ps_NB(&self) -> i64 {
self.0.field_NB() as i64
}
#[getter]
fn tbr(&self) -> i64 {
self.0.field_tbr() as i64
}
#[getter]
fn mtfsf_FM(&self) -> i64 {
self.0.field_mtfsf_FM() as i64
}
#[getter]
fn mtfsf_IMM(&self) -> i64 {
self.0.field_mtfsf_IMM() as i64
}
#[getter]
fn TO(&self) -> i64 {
self.0.field_TO() as i64
}
}
impl From<ppc750cl::Ins> for Ins {
fn from(ins: ppc750cl::Ins) -> Self {
Self(ins)
}
}
#[pyclass]
struct DisasmIterator {
bytes: Py<PyBytes>,
addr: u32,
offset: u32,
left: usize,
}
#[pymethods]
impl DisasmIterator {
fn __iter__(slf: PyRef<Self>) -> PyRef<DisasmIterator> {
slf
}
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<Ins>> {
if slf.left < 4 {
return Ok(None);
}
let bytes = slf.bytes.as_ref(slf.py());
let code = ((bytes[(slf.offset) as usize] as u32) << 24)
| ((bytes[(slf.offset + 1) as usize] as u32) << 16)
| ((bytes[(slf.offset + 2) as usize] as u32) << 8)
| (bytes[(slf.offset + 3) as usize] as u32);
slf.offset += 4;
slf.left -= 4;
let ins = Ins::new(code, slf.addr);
slf.addr += 4;
Ok(Some(ins))
}
}
#[pyfunction(code, addr, offset = "0", size = "None")]
fn disasm_iter(
code: &PyBytes,
addr: u32,
offset: u32,
size: Option<u32>,
) -> PyResult<DisasmIterator> {
let left = match size {
None => code.as_bytes().len().saturating_sub(offset as usize),
Some(v) => v as usize,
};
Ok(DisasmIterator {
bytes: code.into(),
addr,
offset,
left,
})
}
#[pymodule]
fn ppc750cl(_: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Ins>()?;
m.add_wrapped(wrap_pyfunction!(disasm_iter))?;
Ok(())
}