capstone_git/arch/
mips.rs

1//! Contains mips-specific types
2
3use core::convert::From;
4use core::{cmp, fmt, slice};
5
6use capstone_sys::{cs_mips, cs_mips_op, mips_op_mem, mips_op_type};
7
8// XXX todo(tmfink): create rusty versions
9pub use capstone_sys::mips_insn_group as MipsInsnGroup;
10pub use capstone_sys::mips_insn as MipsInsn;
11pub use capstone_sys::mips_reg as MipsReg;
12
13pub use crate::arch::arch_builder::mips::*;
14use crate::arch::DetailsArchInsn;
15use crate::instruction::{RegId, RegIdInt};
16
17/// Contains MIPS-specific details for an instruction
18pub struct MipsInsnDetail<'a>(pub(crate) &'a cs_mips);
19
20impl_PartialEq_repr_fields!(MipsInsnDetail<'a> [ 'a ];
21    operands
22);
23
24/// MIPS operand
25#[derive(Clone, Debug, Eq, PartialEq)]
26pub enum MipsOperand {
27    /// Register
28    Reg(RegId),
29
30    /// Immediate
31    Imm(i64),
32
33    /// Memory
34    Mem(MipsOpMem),
35
36    /// Invalid
37    Invalid,
38}
39
40impl Default for MipsOperand {
41    fn default() -> Self {
42        MipsOperand::Invalid
43    }
44}
45
46/// MIPS memory operand
47#[derive(Debug, Copy, Clone)]
48pub struct MipsOpMem(pub(crate) mips_op_mem);
49
50impl MipsOpMem {
51    /// Base register
52    pub fn base(&self) -> RegId {
53        RegId(self.0.base as RegIdInt)
54    }
55
56    /// Disp value
57    pub fn disp(&self) -> i64 {
58        self.0.disp
59    }
60}
61
62impl_PartialEq_repr_fields!(MipsOpMem;
63    base, disp
64);
65
66impl cmp::Eq for MipsOpMem {}
67
68impl From<&cs_mips_op> for MipsOperand {
69    fn from(insn: &cs_mips_op) -> MipsOperand {
70        match insn.type_ {
71            mips_op_type::MIPS_OP_REG => {
72                MipsOperand::Reg(RegId(unsafe { insn.__bindgen_anon_1.reg } as RegIdInt))
73            }
74            mips_op_type::MIPS_OP_IMM => MipsOperand::Imm(unsafe { insn.__bindgen_anon_1.imm }),
75            mips_op_type::MIPS_OP_MEM => {
76                MipsOperand::Mem(MipsOpMem(unsafe { insn.__bindgen_anon_1.mem }))
77            }
78            mips_op_type::MIPS_OP_INVALID => MipsOperand::Invalid,
79        }
80    }
81}
82
83def_arch_details_struct!(
84    InsnDetail = MipsInsnDetail;
85    Operand = MipsOperand;
86    OperandIterator = MipsOperandIterator;
87    OperandIteratorLife = MipsOperandIterator<'a>;
88    [ pub struct MipsOperandIterator<'a>(slice::Iter<'a, cs_mips_op>); ]
89    cs_arch_op = cs_mips_op;
90    cs_arch = cs_mips;
91);
92
93#[cfg(test)]
94mod test {
95    use super::*;
96    use capstone_sys::*;
97
98    #[test]
99    fn test_mips_op_from() {
100        let op = cs_mips_op {
101            type_: mips_op_type::MIPS_OP_INVALID,
102            __bindgen_anon_1: cs_mips_op__bindgen_ty_1 { reg: 0 },
103        };
104        assert_eq!(MipsOperand::from(&op), MipsOperand::Invalid);
105    }
106}