capstone_git/arch/
sh.rs

1//! Contains sh-specific types
2
3use core::convert::From;
4use core::{cmp, fmt, slice};
5
6pub use capstone_sys::sh_insn as ShInsn;
7pub use capstone_sys::sh_reg as ShReg;
8use capstone_sys::{cs_sh, cs_sh_op, sh_op_mem, sh_op_mem_type, sh_op_type};
9
10pub use crate::arch::arch_builder::sh::*;
11use crate::arch::DetailsArchInsn;
12use crate::instruction::{RegId, RegIdInt};
13
14/// Contains sh-specific details for an instruction
15pub struct ShInsnDetail<'a>(pub(crate) &'a cs_sh);
16
17impl_PartialEq_repr_fields!(ShInsnDetail<'a> [ 'a ];
18    operands
19);
20
21/// sh operand
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub enum ShOperand {
24    /// Register
25    Reg(RegId),
26
27    /// Immediate
28    Imm(u64),
29
30    /// Memory
31    Mem(ShOpMem),
32
33    /// Invalid
34    Invalid,
35}
36
37impl Default for ShOperand {
38    fn default() -> Self {
39        ShOperand::Invalid
40    }
41}
42
43impl From<&cs_sh_op> for ShOperand {
44    fn from(insn: &cs_sh_op) -> ShOperand {
45        match insn.type_ {
46            sh_op_type::SH_OP_REG => {
47                ShOperand::Reg(RegId(unsafe { insn.__bindgen_anon_1.reg } as RegIdInt))
48            }
49            sh_op_type::SH_OP_IMM => ShOperand::Imm(unsafe { insn.__bindgen_anon_1.imm }),
50            sh_op_type::SH_OP_MEM => ShOperand::Mem(ShOpMem(unsafe { insn.__bindgen_anon_1.mem })),
51            sh_op_type::SH_OP_INVALID => ShOperand::Invalid,
52        }
53    }
54}
55
56/// SH memory operand
57#[derive(Debug, Copy, Clone)]
58pub struct ShOpMem(pub(crate) sh_op_mem);
59
60impl ShOpMem {
61    /// Register
62    pub fn reg(&self) -> RegId {
63        RegId(self.0.reg as RegIdInt)
64    }
65
66    /// Disp value
67    fn disp(&self) -> u32 {
68        self.0.disp as u32
69    }
70
71    /// Addressing mode
72    pub fn address(&self) -> ShOpMemType {
73        ShOpMemType::from_u32(self.0.address as u32).unwrap_or(ShOpMemType::Invalid)
74    }
75}
76
77define_cs_enum_wrapper_reverse!(
78    [
79        /// SH Memory Operand type
80        => ShOpMemType = sh_op_mem_type,
81    ]
82    /// Invalid
83    => Invalid = SH_OP_MEM_INVALID;
84    /// Register indirect
85    => RegisterIndirect = SH_OP_MEM_REG_IND;
86    /// Register post increment
87    => RegisterPost = SH_OP_MEM_REG_POST;
88    /// Register pre increment
89    => RegisterPre = SH_OP_MEM_REG_PRE;
90    /// Displacement
91    => Displacement = SH_OP_MEM_REG_DISP;
92    /// R0 indexed
93    => RegisterR0 = SH_OP_MEM_REG_R0;
94    /// GBR based displacement
95    => GBRDisplacement = SH_OP_MEM_GBR_DISP;
96    /// GBR based R0 indexed
97    => GBRR0 = SH_OP_MEM_GBR_R0;
98    /// PC Relative
99    => PCRelative = SH_OP_MEM_PCR;
100    /// TBR based displacement
101    => TBRDisplacement = SH_OP_MEM_TBR_DISP;
102);
103
104impl_PartialEq_repr_fields!(ShOpMem;
105    address, reg, disp
106);
107
108impl cmp::Eq for ShOpMem {}
109
110def_arch_details_struct!(
111    InsnDetail = ShInsnDetail;
112    Operand = ShOperand;
113    OperandIterator = ShOperandIterator;
114    OperandIteratorLife = ShOperandIterator<'a>;
115    [ pub struct ShOperandIterator<'a>(slice::Iter<'a, cs_sh_op>); ]
116    cs_arch_op = cs_sh_op;
117    cs_arch = cs_sh;
118);